orz-markdown 1.0.0 → 1.2.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.
@@ -0,0 +1,179 @@
1
+ ---
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-...]}})."
4
+ compatibility:
5
+ runtime: "Node.js 20+, ESM"
6
+ package: "orz-markdown"
7
+ ---
8
+
9
+ # orz-markdown
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">`.
12
+
13
+ ## Rendering (Node.js / ESM)
14
+
15
+ ```javascript
16
+ import md from 'orz-markdown';
17
+
18
+ const html = md.render(markdownSource);
19
+ const page = `<article class="markdown-body">${html}</article>`;
20
+ ```
21
+
22
+ Parser is configured with `html: true` — raw HTML in source is emitted verbatim. Sanitize untrusted content before rendering to avoid XSS.
23
+
24
+ ### Remote URL includes
25
+
26
+ If the source contains `{{markdown https://...}}`:
27
+
28
+ ```javascript
29
+ import md, { prepareSources } from 'orz-markdown';
30
+
31
+ const resolved = await prepareSources(markdownSource);
32
+ const html = md.render(resolved, { markdownBasePath: '/local/base/path' });
33
+ ```
34
+
35
+ ---
36
+
37
+ ## HTML Page Requirements
38
+
39
+ Every page that displays parser output needs **all five** of these:
40
+
41
+ 1. **Theme stylesheet** — one of the 10 bundled themes, or `assets/minimal.css`
42
+ 2. **KaTeX CSS** — `https://cdn.jsdelivr.net/npm/katex@0.16.35/dist/katex.min.css`
43
+ 3. **Highlight.js CSS** — match light/dark to the chosen theme
44
+ 4. **Three CDN scripts** — Highlight.js, Mermaid.js, SmilesDrawer (loaded in body)
45
+ 5. **Two inline scripts** — tabs initializer and QR code runtime (also in body)
46
+
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
+
49
+ CDN URLs (pinned versions):
50
+ | Library | URL |
51
+ |---|---|
52
+ | Highlight.js JS | `https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js` |
53
+ | Highlight.js light CSS | `.../styles/github.min.css` (same base URL) |
54
+ | Highlight.js dark CSS | `.../styles/atom-one-dark.min.css` |
55
+ | Mermaid.js | `https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js` |
56
+ | SmilesDrawer | `https://unpkg.com/smiles-drawer@1.0.10/dist/smiles-drawer.min.js` |
57
+
58
+ ### Browser runtime API
59
+
60
+ For programmatic control after mounting HTML dynamically:
61
+
62
+ ```javascript
63
+ import { getBrowserRuntimeScript } from 'orz-markdown/runtime';
64
+ const script = document.createElement('script');
65
+ script.textContent = getBrowserRuntimeScript();
66
+ document.body.appendChild(script);
67
+ // or call directly: window.OrzMarkdownRuntime.init(rootElement)
68
+ ```
69
+
70
+ 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)`.
71
+
72
+ > **Do not strip `data-md` attributes.** `mermaid`, `smiles`, `qrcode`, and `youtube` 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.
73
+
74
+ ---
75
+
76
+ ## Themes
77
+
78
+ Ten bundled themes — each auto-imports `common.css` (structural rules for tables, images, QR overlays, print).
79
+
80
+ | File | Style | Scheme |
81
+ |---|---|---|
82
+ | `dark-elegant-1.css` | Cinzel headings · scholarly serif | Dark |
83
+ | `dark-elegant-2.css` | Dark elegant variant | Dark |
84
+ | `light-neat-1.css` | Figtree · clean modern sans | Light |
85
+ | `light-neat-2.css` | Light neat variant | Light |
86
+ | `beige-decent-1.css` | Warm beige · print-like prose | Light |
87
+ | `beige-decent-2.css` | Beige decent variant | Light |
88
+ | `light-academic-1.css` | Alegreya · justified scholarly prose | Light |
89
+ | `light-academic-2.css` | Light academic variant | Light |
90
+ | `light-playful-1.css` | Casual · personal blog | Light |
91
+ | `light-playful-2.css` | Light playful variant | Light |
92
+
93
+ ```javascript
94
+ // With bundler:
95
+ import 'orz-markdown/themes/light-neat-1.css';
96
+
97
+ // Plain HTML:
98
+ // <link rel="stylesheet" href="node_modules/orz-markdown/themes/light-neat-1.css">
99
+ ```
100
+
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.
102
+
103
+ ---
104
+
105
+ ## Plugin Syntax — Quick Reference
106
+
107
+ For complete examples and all options, read `references/syntax.md`.
108
+
109
+ ### Custom plugins — `{{name[args] body}}`
110
+
111
+ Single-line: `{{name[args] body}}` — Multi-line: `{{name[args]\nbody\n}}` — both close with `}}`.
112
+ Escape with backslash: `\{{name}}` renders as literal `{{name}}`.
113
+
114
+ | Plugin | Alias | Quick example |
115
+ |---|---|---|
116
+ | **span** | `sp` | `{{sp[red] colored}}` · `{{sp[success] ✓ Done}}` |
117
+ | **emoji** | `em` | `{{emoji wave}}` · `{{em tada}}` |
118
+ | **space** | — | `{{space 4}}` → 4 × `&nbsp;` |
119
+ | **qrcode** | `qr` | `{{qr https://example.com}}` (click-to-expand SVG) |
120
+ | **youtube** | `yt` | `{{youtube dQw4w9WgXcQ}}` (responsive iframe) |
121
+ | **mermaid** | `mm` | `{{mm\ngraph LR\nA-->B\n}}` |
122
+ | **smiles** | `sm` | `{{smiles C1=CC=CC=C1}}` (chemical structure) |
123
+ | **toc** | — | `{{toc}}` or `{{toc 2,3}}` (heading levels) |
124
+ | **attrs** | — | `# Title{{attrs[id="hero"]}}` |
125
+ | **markdown** | `md`, `md-include` | `{{md ./path/to/file.md}}` |
126
+ | **yaml** | `yml` | `{{yaml\nkey: val\n}}` (invisible metadata) |
127
+ | **nyml** | — | `{{nyml\nkey: val\n}}` (parsed to JSON) |
128
+
129
+ ### Containers — `::: name ... :::`
130
+
131
+ Space between `:::` and name is required. Nesting uses more colons on the outer level.
132
+
133
+ ```markdown
134
+ ::: success ::: info ::: warning ::: danger
135
+ ::: left ::: right ::: center
136
+ ::: left 30% (optional CSS width arg — only on `left`)
137
+ ::: spoil My Title ::: my-class-name (arbitrary class)
138
+
139
+ :::: tabs (outer: 4 colons)
140
+ ::: tab Label One (inner: 3 colons)
141
+ :::
142
+ ::: tab Label Two
143
+ :::
144
+ ::::
145
+
146
+ :::: cols (equal-width columns)
147
+ :::: cols 1 2 1 (ratio: numbers → fr units, or any CSS length)
148
+ ::: col
149
+ :::
150
+ ::::
151
+
152
+ :::: outer (nesting: outer uses more colons than inner)
153
+ ::: inner
154
+ :::
155
+ ::::
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Stable Block IDs — editing rules
161
+
162
+ Documents may carry stable block IDs on headings: `## Title{{attrs[#blk-abc12345]}}` (canonical form: no space before the marker). These IDs are the block's permanent identity for the host application.
163
+
164
+ **The non-negotiables:** IDs are immutable — when editing or rewriting a section, preserve its `{{attrs[#blk-...]}}` marker exactly, even if you rewrite the heading text completely. Never reuse, invent, regenerate, or duplicate an ID, and never convert to or from Pandoc `{#id}` syntax (unsupported; corrupts the heading).
165
+
166
+ **Before any edit to a document containing `{{attrs[#blk-...]}}`, read `references/block-ids.md`** — it has the full rules and a pre-save checklist.
167
+
168
+ ---
169
+
170
+ ## Reference Files
171
+
172
+ | File | When to read |
173
+ |---|---|
174
+ | `references/syntax.md` | Full syntax with examples for every plugin, container, and extended markdown feature |
175
+ | `references/block-ids.md` | Stable block-ID preservation rules — REQUIRED reading before editing documents that use `{{attrs[#blk-...]}}` |
176
+ | `references/themes.md` | Custom theme guide: design tokens, element checklist, 10 design guidelines |
177
+ | `references/css-classes.md` | Every CSS class and HTML element the parser emits — the spec for theme authors |
178
+ | `assets/template.html` | Ready-to-use HTML page template with all scripts and CDN links wired up |
179
+ | `assets/minimal.css` | Structural-only stylesheet — starting point for custom themes |