orz-markdown 1.3.0 → 1.3.1
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 +10 -2
- package/dist/runtime.js +1 -1
- package/orz-markdown-skills/SKILL.md +7 -6
- package/orz-markdown-skills/assets/template.html +21 -1
- package/orz-markdown-skills/references/css-classes.md +16 -9
- package/orz-markdown-skills/references/embedding.md +7 -6
- package/orz-markdown-skills/references/syntax.md +5 -3
- package/orz-markdown-skills/references/themes.md +4 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,7 +55,7 @@ Once the runtime is loaded, selecting rendered content and copying it (Cmd/Ctrl-
|
|
|
55
55
|
|
|
56
56
|
It only transforms selections inside an element with class `markdown-body` (wrap your rendered output in one, e.g. `<article class="markdown-body">…</article>`, or mark a container with `data-orz-copy`), and never touches selections inside `<input>`, `<textarea>`, or `contenteditable` regions.
|
|
57
57
|
|
|
58
|
-
Generated constructs that lose their source after client-side rendering — `mermaid`, `smiles`, `qrcode`, `youtube` — carry a `data-md` attribute that the walker emits verbatim. As a result a copied table of contents yields its heading links (not `{{toc 2,3}}`) and a copied QR code yields `{{qr ...}}` (not its SVG). **Do not strip `data-md` attributes** if you post-process the HTML.
|
|
58
|
+
Generated constructs that lose their source after client-side rendering — `mermaid`, `smiles`, `qrcode`, `youtube`, `chart` — carry a `data-md` attribute that the walker emits verbatim. As a result a copied table of contents yields its heading links (not `{{toc 2,3}}`) and a copied QR code yields `{{qr ...}}` (not its SVG). **Do not strip `data-md` attributes** if you post-process the HTML.
|
|
59
59
|
|
|
60
60
|
You can also convert a node programmatically:
|
|
61
61
|
|
|
@@ -130,6 +130,14 @@ node_modules/orz-markdown/orz-markdown-skills/SKILL.md
|
|
|
130
130
|
|
|
131
131
|
with supporting files under `orz-markdown-skills/references/` and `orz-markdown-skills/assets/`. Point your agent tooling at that directory (e.g. copy or symlink it into your agent's skills folder).
|
|
132
132
|
|
|
133
|
+
Or hand your agent the skill straight from the CDN — no install needed:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
https://cdn.jsdelivr.net/npm/orz-markdown/orz-markdown-skills/SKILL.md
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
See **[markdown.orz.how/agents.html](https://markdown.orz.how/agents.html)** for every install route (Claude Code, Claude.ai upload, or point-at-URL for any agent).
|
|
140
|
+
|
|
133
141
|
## Official Plugins Bundled
|
|
134
142
|
|
|
135
143
|
This project builds upon `markdown-it` and pre-configures a curated selection of official and popular community plugins.
|
|
@@ -159,7 +167,7 @@ We utilize a generalized and uniform `{{plugin_name ...}}` syntax for all custom
|
|
|
159
167
|
| **Attributes** | N/A | `# Header {{attrs[id="my-id"]}}`| Injects continuous HTML attributes (classes, IDs, config properties) to the immediately preceding element. |
|
|
160
168
|
| **Emoji** | `em` | `{{emoji smile}}` / `{{em tada}}` | Renders the specific text alias directly into the corresponding Unicode emoji natively. |
|
|
161
169
|
| **Table of Content** | N/A | `{{toc}}` or `{{toc 2,3}}` | Autogenerates a Table of Contents based on document headings. Allows specifying bound heading ranges. |
|
|
162
|
-
| **Space** | N/A | `{{space 4}}` | Inserts inline horizontal whitespace
|
|
170
|
+
| **Space** | N/A | `{{space 4}}` | Inserts inline horizontal whitespace — an empty `inline-block` span sized in `rem` (`{{space 4}}` → 4rem wide). |
|
|
163
171
|
| **YouTube** | `yt` | `{{youtube dQw4w9WgXcQ}}` | Embedded block element containing a responsive YouTube video iframe matching the ID. |
|
|
164
172
|
| **Markdown Source**| `md` | `{{md path/to/file.md}}` | Securely embeds the complete content of an external markdown file directly into the parsed structure. |
|
|
165
173
|
| **QR Code** | `qr` | `{{qr https://example.com}}` | Transforms text inline implicitly into an internally generated SVG QR Code natively. |
|
package/dist/runtime.js
CHANGED
|
@@ -121,7 +121,7 @@ exports.browserRuntimeScript = String.raw `
|
|
|
121
121
|
// ---- copy-as-markdown: DOM -> Markdown walker ---------------------------
|
|
122
122
|
// Converts a selected DOM fragment back to Markdown so that copying rendered
|
|
123
123
|
// content yields source, not HTML. Standard constructs are reconstructed from
|
|
124
|
-
// their tags; generated constructs (math, mermaid, smiles, qr, youtube) carry
|
|
124
|
+
// their tags; generated constructs (math, mermaid, smiles, qr, youtube, chart) carry
|
|
125
125
|
// a [data-md] breadcrumb that is emitted verbatim. Written without template
|
|
126
126
|
// literals/backticks because this whole file is a String.raw template.
|
|
127
127
|
var BT = String.fromCharCode(96);
|
|
@@ -8,7 +8,7 @@ compatibility:
|
|
|
8
8
|
|
|
9
9
|
# orz-markdown
|
|
10
10
|
|
|
11
|
-
A deeply customized `markdown-it` instance with 10+ plugins,
|
|
11
|
+
A deeply customized `markdown-it` instance with 10+ custom plugins, 10 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
|
|
|
@@ -38,10 +38,10 @@ const html = md.render(resolved, { markdownBasePath: '/local/base/path' });
|
|
|
38
38
|
|
|
39
39
|
Every page that displays parser output needs **all five** of these:
|
|
40
40
|
|
|
41
|
-
1. **Theme stylesheet** — one of the
|
|
41
|
+
1. **Theme stylesheet** — one of the 12 bundled themes, or `assets/minimal.css`
|
|
42
42
|
2. **KaTeX CSS** — `https://cdn.jsdelivr.net/npm/katex@0.16.35/dist/katex.min.css`
|
|
43
43
|
3. **Highlight.js CSS** — match light/dark to the chosen theme
|
|
44
|
-
4. **
|
|
44
|
+
4. **Four CDN scripts** — Highlight.js, Mermaid.js, SmilesDrawer, Chart.js (loaded in body)
|
|
45
45
|
5. **Two inline scripts** — tabs initializer and QR code runtime (also in body)
|
|
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.
|
|
@@ -56,6 +56,7 @@ CDN URLs (pinned versions):
|
|
|
56
56
|
| Highlight.js dark CSS | `.../styles/atom-one-dark.min.css` |
|
|
57
57
|
| Mermaid.js | `https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js` |
|
|
58
58
|
| SmilesDrawer | `https://unpkg.com/smiles-drawer@1.0.10/dist/smiles-drawer.min.js` |
|
|
59
|
+
| Chart.js | `https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js` |
|
|
59
60
|
|
|
60
61
|
### Browser runtime API
|
|
61
62
|
|
|
@@ -71,7 +72,7 @@ document.body.appendChild(script);
|
|
|
71
72
|
|
|
72
73
|
The runtime also provides **copy-as-Markdown**: with it loaded, copying a selection inside `.markdown-body` puts Markdown source on the clipboard, not HTML (tables, lists, math, code, etc. are reconstructed). It skips selections inside `<input>`/`<textarea>`/`contenteditable`. Convert a node directly with `window.OrzMarkdownRuntime.elementToMarkdown(node)`.
|
|
73
74
|
|
|
74
|
-
> **Do not strip `data-md` attributes.** `mermaid`, `smiles`, `qrcode`, and `
|
|
75
|
+
> **Do not strip `data-md` attributes.** `mermaid`, `smiles`, `qrcode`, `youtube`, and `chart` output carry a `data-md` breadcrumb so copy recovers their source after client-side rendering (e.g. a copied QR yields `{{qr ...}}`, not its SVG). Preserve these attributes if you post-process the HTML.
|
|
75
76
|
|
|
76
77
|
---
|
|
77
78
|
|
|
@@ -119,7 +120,7 @@ Escape with backslash: `\{{name}}` renders as literal `{{name}}`.
|
|
|
119
120
|
|---|---|---|
|
|
120
121
|
| **span** | `sp` | `{{sp[red] colored}}` · `{{sp[success] ✓ Done}}` |
|
|
121
122
|
| **emoji** | `em` | `{{emoji wave}}` · `{{em tada}}` |
|
|
122
|
-
| **space** | — | `{{space 4}}` →
|
|
123
|
+
| **space** | — | `{{space 4}}` → 4rem-wide inline-block spacer |
|
|
123
124
|
| **qrcode** | `qr` | `{{qr https://example.com}}` (click-to-expand SVG) |
|
|
124
125
|
| **youtube** | `yt` | `{{youtube dQw4w9WgXcQ}}` (responsive iframe) |
|
|
125
126
|
| **mermaid** | `mm` | `{{mm\ngraph LR\nA-->B\n}}` |
|
|
@@ -178,7 +179,7 @@ Documents may carry stable block IDs on headings: `## Title{{attrs[#blk-abc12345
|
|
|
178
179
|
|---|---|
|
|
179
180
|
| `references/syntax.md` | Full syntax with examples for every plugin, container, and extended markdown feature |
|
|
180
181
|
| `references/block-ids.md` | Stable block-ID preservation rules — REQUIRED reading before editing documents that use `{{attrs[#blk-...]}}` |
|
|
181
|
-
| `references/themes.md` | Custom theme guide: design tokens, element checklist,
|
|
182
|
+
| `references/themes.md` | Custom theme guide: design tokens, element checklist, 12 design guidelines |
|
|
182
183
|
| `references/css-classes.md` | Every CSS class and HTML element the parser emits — the spec for theme authors |
|
|
183
184
|
| `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 |
|
|
184
185
|
| `assets/template.html` | Ready-to-use HTML page template with all scripts and CDN links wired up |
|
|
@@ -64,6 +64,26 @@ if (typeof SmilesDrawer !== 'undefined') {
|
|
|
64
64
|
}
|
|
65
65
|
</script>
|
|
66
66
|
|
|
67
|
+
<!-- Chart.js — renders {{chart}} canvases emitted by the parser. -->
|
|
68
|
+
<script src="https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js"></script>
|
|
69
|
+
<script>
|
|
70
|
+
if (typeof Chart !== 'undefined') {
|
|
71
|
+
document.querySelectorAll('canvas.orz-chart[data-chart]').forEach(function (canvas) {
|
|
72
|
+
var wrap = document.createElement('div');
|
|
73
|
+
wrap.style.cssText = 'position:relative;width:100%;max-width:520px;margin:.6em auto';
|
|
74
|
+
canvas.parentNode.insertBefore(wrap, canvas);
|
|
75
|
+
wrap.appendChild(canvas);
|
|
76
|
+
canvas.removeAttribute('width');
|
|
77
|
+
canvas.removeAttribute('height');
|
|
78
|
+
try {
|
|
79
|
+
var config = JSON.parse(canvas.getAttribute('data-chart') || '{}');
|
|
80
|
+
config.options = Object.assign({ responsive: true, maintainAspectRatio: true, animation: false }, config.options || {});
|
|
81
|
+
new Chart(canvas, config);
|
|
82
|
+
} catch (e) {}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
</script>
|
|
86
|
+
|
|
67
87
|
<!-- Tabs component — builds the .tabs-bar and activates .tab panels.
|
|
68
88
|
Must run after the DOM is painted so .tabs elements are found. -->
|
|
69
89
|
<script>
|
|
@@ -184,7 +204,7 @@ if (typeof SmilesDrawer !== 'undefined') {
|
|
|
184
204
|
// ---- copy-as-markdown: DOM -> Markdown walker ---------------------------
|
|
185
205
|
// Converts a selected DOM fragment back to Markdown so that copying rendered
|
|
186
206
|
// content yields source, not HTML. Standard constructs are reconstructed from
|
|
187
|
-
// their tags; generated constructs (math, mermaid, smiles, qr, youtube) carry
|
|
207
|
+
// their tags; generated constructs (math, mermaid, smiles, qr, youtube, chart) carry
|
|
188
208
|
// a [data-md] breadcrumb that is emitted verbatim. Written without template
|
|
189
209
|
// literals/backticks because this whole file is a String.raw template.
|
|
190
210
|
var BT = String.fromCharCode(96);
|
|
@@ -193,23 +193,30 @@ span.qrcode { background: #fff; padding: 4px; /* or 6px */ vertical-align: middl
|
|
|
193
193
|
|
|
194
194
|
Note: `span.success/info/warning/danger` also have `display: inline-flex; align-items: center; line-height: 1; white-space: nowrap` set by `common.css`. Add `padding`, `border-radius`, `font-size`, and colors in the theme.
|
|
195
195
|
|
|
196
|
+
### Chart
|
|
197
|
+
|
|
198
|
+
| Class | Element | Description |
|
|
199
|
+
|---|---|---|
|
|
200
|
+
| `canvas.orz-chart` | `<canvas>` | Carries a Chart.js config as HTML-escaped JSON in `data-chart` (and a `data-md` breadcrumb). The host runtime reads `data-chart` and calls Chart.js. Cap its width. |
|
|
201
|
+
|
|
202
|
+
```css
|
|
203
|
+
canvas.orz-chart { max-width: 100%; height: auto; }
|
|
204
|
+
```
|
|
205
|
+
|
|
196
206
|
### Table of Contents
|
|
197
207
|
|
|
198
208
|
| Class | Element | Description |
|
|
199
209
|
|---|---|---|
|
|
200
|
-
| `.toc-
|
|
201
|
-
| `nav.toc` / `.toc-list` | `<nav>` | The `<ul>` tree of heading links. Reset list bullets in TOC context. |
|
|
210
|
+
| `.toc-list` | `<ul>` | The flat `<ul>` of heading links emitted by `{{toc}}`. Each `<li>` carries an inline `padding-left` for its depth. Reset list bullets. This is the **only** class the parser emits for the TOC. |
|
|
202
211
|
|
|
203
212
|
```css
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
nav.toc ul, .toc-list ul { margin: 0; padding-left: 1.1rem; }
|
|
209
|
-
nav.toc li, .toc-list li { list-style: none; margin-bottom: 0.25rem; }
|
|
210
|
-
nav.toc a, .toc-list a { text-decoration: none; color: var(--link); }
|
|
213
|
+
.toc-list { padding: ...; border: 1px solid var(--border); list-style: none; }
|
|
214
|
+
.toc-list li { list-style: none; margin-bottom: 0.25rem; }
|
|
215
|
+
.toc-list a { text-decoration: none; color: var(--link); }
|
|
211
216
|
```
|
|
212
217
|
|
|
218
|
+
> Note: the parser does **not** emit a `<nav class="toc">` wrapper or a `.toc-wrapper`. `{{toc}}` produces a single `<ul class="toc-list">`. If your host wants a wrapper, add it around the rendered TOC yourself.
|
|
219
|
+
|
|
213
220
|
### Test elements (development only)
|
|
214
221
|
|
|
215
222
|
| Class | Element | Description |
|
|
@@ -166,14 +166,15 @@ when) all of this holds:
|
|
|
166
166
|
2. **Content is inside `.markdown-body`** (or an element with `data-orz-copy`).
|
|
167
167
|
The handler ignores selections elsewhere and inside inputs/textareas.
|
|
168
168
|
3. **`data-md` breadcrumbs are preserved.** Generated constructs whose source is
|
|
169
|
-
otherwise lost — `mermaid`, `smiles`, `qrcode`, `youtube`, `
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
post-process HTML.
|
|
169
|
+
otherwise lost — `mermaid`, `smiles`, `qrcode`, `youtube`, `chart` (and any
|
|
170
|
+
plugin that adds one) — carry `data-md` with their original directive. The
|
|
171
|
+
walker emits it verbatim. **Never strip `data-md`** when you post-process HTML.
|
|
173
172
|
4. **Plugin/container classes are preserved.** Constructs without a `data-md`
|
|
174
|
-
are recovered *by class*: `<span class="red">` → `{{sp[red] …}}`,
|
|
173
|
+
are recovered *by class/structure*: `<span class="red">` → `{{sp[red] …}}`,
|
|
175
174
|
`<div class="center">` → `::: center … :::`, nested `cols`/`tabs` get the
|
|
176
|
-
right fence length
|
|
175
|
+
right fence length, and a `{{toc}}` is recovered as its rendered list of
|
|
176
|
+
heading links (not the `{{toc}}` directive). If you rewrite/strip these
|
|
177
|
+
classes, copy loses the source.
|
|
177
178
|
|
|
178
179
|
Caveat: a container (`::: center`, `:::: cols`, spoiler, tabs) is recovered only
|
|
179
180
|
when the **selection includes the container element**, not just the text inside
|
|
@@ -310,10 +310,12 @@ Uses `node-emoji` for name lookup. The emoji text alias (e.g., `wave`, `smile`)
|
|
|
310
310
|
### space — Inline horizontal whitespace
|
|
311
311
|
|
|
312
312
|
```markdown
|
|
313
|
-
{{space 4}} →
|
|
314
|
-
{{space 1}} →
|
|
313
|
+
{{space 4}} → 4rem-wide inline-block spacer
|
|
314
|
+
{{space 1}} → 1rem-wide inline-block spacer
|
|
315
315
|
```
|
|
316
316
|
|
|
317
|
+
The numeric argument is a `rem` width: `{{space 4}}` emits `<span style="display:inline-block;width:4rem"></span>`. Non-positive or non-numeric values render nothing.
|
|
318
|
+
|
|
317
319
|
---
|
|
318
320
|
|
|
319
321
|
### qrcode / qr — Inline QR code
|
|
@@ -381,7 +383,7 @@ Renders `<div class="smiles-render"><canvas data-smiles="...">`. SmilesDrawer.js
|
|
|
381
383
|
{{toc 1,4}}
|
|
382
384
|
```
|
|
383
385
|
|
|
384
|
-
Auto-generates a `<
|
|
386
|
+
Auto-generates a `<ul class="toc-list">` of heading links (each `<li>` indented by depth). Optional argument is a comma-separated level range (`min,max`), defaulting to `1,3`. The placement in the source does not matter — a core rule scans the whole document, so `{{toc}}` works at the top or bottom.
|
|
385
387
|
|
|
386
388
|
---
|
|
387
389
|
|
|
@@ -99,8 +99,8 @@ Follow this section order in every theme file for consistency:
|
|
|
99
99
|
12. Semantic containers: `.success`, `.info`, `.warning`, `.danger`
|
|
100
100
|
13. Layout utilities: `.left`, `.right`, `.center`
|
|
101
101
|
14. Spoiler, tabs, and columns: `details.spoil`, `.tabs`, `.cols`
|
|
102
|
-
15. TOC and footnotes:
|
|
103
|
-
16. Plugin output: `.youtube-embed`, `.mermaid`, `.smiles-render`, `.qrcode`, span color/badge classes
|
|
102
|
+
15. TOC and footnotes: `.toc-list`, `.footnotes`
|
|
103
|
+
16. Plugin output: `.youtube-embed`, `.mermaid`, `.smiles-render`, `canvas.orz-chart`, `.qrcode`, span color/badge classes
|
|
104
104
|
17. Decorative pseudo-elements and theme-only flourishes
|
|
105
105
|
18. Responsive rules (`@media`)
|
|
106
106
|
19. Print rules (`@media print`)
|
|
@@ -165,12 +165,13 @@ Every theme must have CSS rules for all of the following. See `references/css-cl
|
|
|
165
165
|
- [ ] `.tabs` `.tabs-bar` `.tabs-bar-btn` `.tabs-bar-btn.active` `.tab` `.tab.active`
|
|
166
166
|
- [ ] `.tabs:not([data-js]) .tab` — no-JS fallback: show all panels
|
|
167
167
|
- [ ] `.cols` `.col`
|
|
168
|
-
- [ ]
|
|
168
|
+
- [ ] `.toc-list` — list reset, link styles (the parser emits only `<ul class="toc-list">`, no `nav.toc` wrapper)
|
|
169
169
|
- [ ] `span.red` `span.yellow` `span.green` `span.blue`
|
|
170
170
|
- [ ] `span.success` `span.info` `span.warning` `span.danger` — inline badge variant
|
|
171
171
|
- [ ] `div.youtube-embed` `div.youtube-embed iframe` — 16:9 responsive wrapper (structural)
|
|
172
172
|
- [ ] `div.mermaid` `div.mermaid svg`
|
|
173
173
|
- [ ] `div.smiles-render` `canvas[data-smiles]`
|
|
174
|
+
- [ ] `canvas.orz-chart` — width-capped (Chart.js draws into it client-side)
|
|
174
175
|
- [ ] `span.qrcode` — **must have `background: #fff`** (SVG is always black-on-white)
|
|
175
176
|
|
|
176
177
|
---
|