orz-paged 0.1.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 +146 -0
- package/assets/app.js +413 -0
- package/assets/templates/article-page.md +71 -0
- package/assets/templates/article-section.md +83 -0
- package/assets/templates/cover-letter.md +53 -0
- package/assets/templates/cv-elegant.md +93 -0
- package/assets/templates/cv-modern.md +86 -0
- package/assets/templates/cv.md +45 -0
- package/assets/templates/exam-page.md +76 -0
- package/assets/templates/exam-section.md +59 -0
- package/assets/templates/letter.md +47 -0
- package/assets/templates/note.md +28 -0
- package/assets/templates/report-page.md +72 -0
- package/assets/templates/report-section.md +80 -0
- package/assets/themes/base.css +538 -0
- package/assets/themes/beige-decent-1.css +103 -0
- package/assets/themes/beige-decent-2.css +92 -0
- package/assets/themes/light-academic-1.css +114 -0
- package/assets/themes/light-academic-2.css +99 -0
- package/assets/themes/light-neat-1.css +90 -0
- package/assets/themes/light-neat-2.css +101 -0
- package/assets/themes/light-neat-3.css +91 -0
- package/dist/browser-entry.js +302 -0
- package/dist/cli.js +167 -0
- package/dist/doc/dynamic.js +57 -0
- package/dist/doc/elements.js +813 -0
- package/dist/doc/fonts.js +83 -0
- package/dist/doc/nyml.js +140 -0
- package/dist/doc/page-css.js +230 -0
- package/dist/doc/settings.js +390 -0
- package/dist/doc/templates.js +147 -0
- package/dist/doc/theme-fonts.js +10 -0
- package/dist/orz-paged.browser.js +1524 -0
- package/dist/paged.js +31 -0
- package/dist/render-paged.js +123 -0
- package/dist/template.js +242 -0
- package/dist/types.js +11 -0
- package/orz-paged-skills/SKILL.md +547 -0
- package/package.json +51 -0
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: orz-paged
|
|
3
|
+
description: Author and edit self-contained .paged.html print documents (orz-paged). Use when a user wants to turn Markdown into a paginated, printable document — one portable HTML file that, in any browser, shows the text as real print pages on light paper (paged.js), is edited in-browser, and exports to PDF by printing (Ctrl/Cmd+P → Save as PDF). Covers the document settings block, templates (article, report, exam, letter, cover-letter, three CV styles, note), the curated document elements (title sections with multi-author/affiliation/ORCID support, abstract, toc, letter and CV parts, exam questions), a dynamic switch (print several versions from one source, e.g. an exam with or without its answer key), page breaks, and print-first content guidance.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# orz-paged — author a `.paged.html` document
|
|
7
|
+
|
|
8
|
+
`orz-paged` turns a **Markdown source** into **one `.paged.html` file** that:
|
|
9
|
+
|
|
10
|
+
- shows the document as a sequence of **print pages on light-colored paper**
|
|
11
|
+
(real page size, margins, running headers/footers, page numbers) in any modern
|
|
12
|
+
browser, via [paged.js](https://pagedjs.org),
|
|
13
|
+
- is authored entirely in **orz-markdown** (math, mermaid, smiles, qr, charts,
|
|
14
|
+
tables, admonitions, columns) plus a small **document layer**,
|
|
15
|
+
- can be **edited in the browser** (CodeMirror source + live paged preview) and
|
|
16
|
+
**saves itself** back into the file,
|
|
17
|
+
- **exports to PDF by printing** — the on-screen pages are the printed pages
|
|
18
|
+
(Ctrl/Cmd+P → Save as PDF, or the ↓ button), so there is no rendering surprise.
|
|
19
|
+
|
|
20
|
+
The Markdown source is the single source of truth, embedded in the file:
|
|
21
|
+
|
|
22
|
+
```html
|
|
23
|
+
<script type="text/markdown" id="orz-src">
|
|
24
|
+
...your Markdown (this is what you write)...
|
|
25
|
+
</script>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
You write only the **Markdown source**. Never hand-write the surrounding HTML
|
|
29
|
+
(the paged.js shell, runtime, CDN links) — saving regenerates it. To change a
|
|
30
|
+
document, edit the source (in a `.md` file fed to the CLI, or in-browser) and let
|
|
31
|
+
the tool re-render.
|
|
32
|
+
|
|
33
|
+
## When to use it
|
|
34
|
+
|
|
35
|
+
- A user wants a **single shareable file** that looks like a printed document —
|
|
36
|
+
an article, report, letter, CV, note, or exam — and can be turned into a PDF by
|
|
37
|
+
printing, with no install.
|
|
38
|
+
- The content is **markdown-native** (prose, tables, math, diagrams) and the
|
|
39
|
+
author wants a paginated document, not a slide deck or a continuous web page.
|
|
40
|
+
- Prefer `.paged.html` (orz-paged) when the output is a **paginated document to
|
|
41
|
+
print or hand in**; prefer `.md.html` (orz-mdhtml) for a continuous document to
|
|
42
|
+
read/annotate on screen; prefer `.slides.html` (orz-slides) for a deck to
|
|
43
|
+
present.
|
|
44
|
+
|
|
45
|
+
> It mimics **ink on paper**: light backgrounds only, no dark mode, no
|
|
46
|
+
> interactive constructs. Author for print (see [Print-first content](#print-first-content)).
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Workflow
|
|
51
|
+
|
|
52
|
+
Generate from a Markdown file:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
orz-paged document.md # → document.paged.html
|
|
56
|
+
orz-paged document.md -o out.paged.html # choose the output name
|
|
57
|
+
orz-paged document.md --inline # (default) embed engine + all themes
|
|
58
|
+
orz-paged document.md --cdn # reference engine + theme from jsDelivr
|
|
59
|
+
|
|
60
|
+
orz-paged --template article-page # scaffold + render a starter document
|
|
61
|
+
orz-paged --new letter -o draft.md # write a starter .md you then edit
|
|
62
|
+
orz-paged --list-templates # list the templates
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
You can also start from a template **inside the editor**: open it (✎) and click
|
|
66
|
+
the **template** button (📄) in the toolbar — a grouped picker of starter
|
|
67
|
+
documents; choosing one drops the starter into the editor (any existing content is
|
|
68
|
+
preserved in an HTML comment).
|
|
69
|
+
|
|
70
|
+
`--inline` (default) embeds the `orz-paged` engine + paged.js + all light themes,
|
|
71
|
+
so the document **paginates offline**. Either way, **fonts, web images, and the
|
|
72
|
+
math/diagram/chart libraries load from a CDN at view time** (so a document that
|
|
73
|
+
uses those, or in-browser editing, needs internet).
|
|
74
|
+
|
|
75
|
+
Then **open the `.paged.html` in any modern browser** — it paginates into pages.
|
|
76
|
+
|
|
77
|
+
- Click the **✎** button to open the editor (source + live paged preview).
|
|
78
|
+
- **Ctrl/Cmd+S** saves the file in place (needs a Chromium-based browser, File
|
|
79
|
+
System Access API; falls back to download elsewhere).
|
|
80
|
+
- **Export PDF** = the **↓** button, or the browser's **Print → Save as PDF**.
|
|
81
|
+
The pages you see are exactly what prints.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## The Markdown source: settings, then content
|
|
86
|
+
|
|
87
|
+
A source is a **document-settings block** at the top, then normal Markdown body
|
|
88
|
+
(with elements and page breaks placed wherever you need them):
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
{{nyml
|
|
92
|
+
kind: document
|
|
93
|
+
template: article
|
|
94
|
+
theme: light-academic-1
|
|
95
|
+
}}
|
|
96
|
+
|
|
97
|
+
{{nyml
|
|
98
|
+
kind: article-title
|
|
99
|
+
title: A Practical Comparison of RAFT and ATRP
|
|
100
|
+
subtitle: Controlled radical polymerization in the teaching lab
|
|
101
|
+
author: Dr. Yu Wang
|
|
102
|
+
date: March 2026
|
|
103
|
+
}}
|
|
104
|
+
|
|
105
|
+
{{nyml
|
|
106
|
+
kind: abstract
|
|
107
|
+
text: We compare two controlled-radical methods on accessible monomers...
|
|
108
|
+
keywords: RAFT, ATRP, controlled polymerization
|
|
109
|
+
}}
|
|
110
|
+
|
|
111
|
+
## Introduction
|
|
112
|
+
|
|
113
|
+
Body text in normal Markdown. Math like $E = mc^2$, tables, lists, and
|
|
114
|
+
diagrams all print.
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 1 · Document settings (`{{nyml kind: document}}`)
|
|
120
|
+
|
|
121
|
+
One block at the top configures the whole document. **Template-first:** most
|
|
122
|
+
documents set only `template:` (and maybe `theme:` and `decoration_color:`) — the
|
|
123
|
+
template sets every other default. The rest are **optional overrides** for power
|
|
124
|
+
users and agents.
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
{{nyml
|
|
128
|
+
kind: document
|
|
129
|
+
template: article
|
|
130
|
+
}}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Templates (set one — it picks the layout + a starter skeleton)
|
|
134
|
+
|
|
135
|
+
**A template owns *layout only*** — page size, furniture (running headers/footers,
|
|
136
|
+
page numbers), and which elements appear and where. **The look — font, decoration
|
|
137
|
+
color, and element styling — comes from the `theme`**, so the same theme renders
|
|
138
|
+
the same across every template. `article`, `report`, and `exam` come in **two
|
|
139
|
+
variants** — `-page` (a dedicated title/cover page) and `-section` (an inline title
|
|
140
|
+
block above the content):
|
|
141
|
+
|
|
142
|
+
| `template` | For | Layout |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| `article-page` / `article-section` | academic paper | title (own page / inline) + `abstract` (own page in `-page`) + body |
|
|
145
|
+
| `report-page` / `report-section` | business / technical report | title (own page / inline) + `toc` + running header/footer + body |
|
|
146
|
+
| `exam-page` / `exam-section` | exam / assessment | title (cover / inline) + `question-*`, answer-key toggle |
|
|
147
|
+
| `letter` | formal letter | `letterhead` + inside-address + body + signature |
|
|
148
|
+
| `cover-letter` | job cover letter | sender header + recipient + body + sign-off |
|
|
149
|
+
| `cv` | résumé (classic) | `cv-header` + sectioned body |
|
|
150
|
+
| `cv-modern` | résumé (modern) | accent name + rule, uppercase labels, right-aligned dates, skill chips |
|
|
151
|
+
| `cv-elegant` | résumé (elegant) | centered, hairline rules, two-column "ledger" entries |
|
|
152
|
+
| `note` | clean readable notes | A4, minimal furniture |
|
|
153
|
+
|
|
154
|
+
The bare names `article` / `report` / `exam` still work and resolve to the
|
|
155
|
+
`-section` variant. To change the look, set `theme:` (not the template).
|
|
156
|
+
|
|
157
|
+
### Overrides (all optional — the template supplies defaults)
|
|
158
|
+
|
|
159
|
+
| Key | Values / unit | Notes |
|
|
160
|
+
|---|---|---|
|
|
161
|
+
| `page_size` | `A3` `A4` `A5` `Letter` `Legal`, or custom `"210mm 297mm"` | |
|
|
162
|
+
| `margin_top` / `margin_bottom` / `margin_left` / `margin_right` | number (mm) | |
|
|
163
|
+
| `font_preset` | see [Font presets](#font-presets) | body font |
|
|
164
|
+
| `font_size` | number (pt) | |
|
|
165
|
+
| `line_height` | number (ratio, e.g. `1.5`) | |
|
|
166
|
+
| `decoration_color` | CSS color, e.g. `"#2962a4"` | accent used by theme + elements |
|
|
167
|
+
| `header_left` / `header_center` / `header_right` | text | running header margin boxes |
|
|
168
|
+
| `footer_left` / `footer_center` / `footer_right` | text | running footer margin boxes |
|
|
169
|
+
| `page_number_position` | `header-left\|center\|right`, `footer-left\|center\|right`, `none` | where the page number sits |
|
|
170
|
+
| `page_number_style` | see [Page-number styles](#page-number-styles) | how it reads |
|
|
171
|
+
| `front_matter` | `clean` (or `normal`, the default) | `clean`: strip header/footer/number from every `placement: page` front-matter page (title / abstract / toc) and restart the page count so the body begins at **1** |
|
|
172
|
+
| `dynamic_choices` | a `key: value` map | conditional content — print several versions from one source (e.g. `answer-key: hide`); see [Dynamic switch](#dynamic-switch--print-several-versions-from-one-source) |
|
|
173
|
+
| `theme` | `none` · `light-neat-1/2/3` · `light-academic-1/2` · `beige-decent-1/2` | **light only** |
|
|
174
|
+
|
|
175
|
+
#### Font presets
|
|
176
|
+
|
|
177
|
+
Serif: `system-serif` `source-serif-4` `lora` `crimson-pro` `noto-serif` ·
|
|
178
|
+
Sans: `inter` `ibm-plex-sans` `roboto` `raleway` `noto-sans` ·
|
|
179
|
+
Mono: `courier-prime`.
|
|
180
|
+
|
|
181
|
+
#### Page-number styles
|
|
182
|
+
|
|
183
|
+
`simple` (just the number) · `page-n` (`Page 3`) · `page-n-of-N` (`Page 3 of 12`) ·
|
|
184
|
+
`n-of-N` (`3 of 12`) · `n-slash-N` (`3 / 12`) · `dash-n-dash` (`— 3 —`) ·
|
|
185
|
+
`brackets` (`[3]`) · `parentheses` (`(3)`).
|
|
186
|
+
|
|
187
|
+
#### Themes (light only — by design)
|
|
188
|
+
|
|
189
|
+
Seven light themes, vendored from the orz family and print-adapted:
|
|
190
|
+
|
|
191
|
+
- `light-neat-1/2/3` — modern sans (blue / teal / Orchard-green accents),
|
|
192
|
+
- `light-academic-1/2` — scholarly serif (justified, ruled tables),
|
|
193
|
+
- `beige-decent-1/2` — warm editorial paper,
|
|
194
|
+
- `none` — plain.
|
|
195
|
+
|
|
196
|
+
There are **no dark themes** — the document mimics ink on paper. **The theme owns
|
|
197
|
+
the look** — font, accent (decoration) color, and element styling — so it is
|
|
198
|
+
consistent across every template. The **default theme is `light-academic-1`** (used
|
|
199
|
+
when a document doesn't set `theme:`). An explicit `font_preset` /
|
|
200
|
+
`decoration_color` / `page_background` still overrides the theme (so
|
|
201
|
+
`layout (template) + look (theme) ← your explicit settings`).
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## 2 · Elements (`{{nyml kind: <element-kind> ...}}`)
|
|
206
|
+
|
|
207
|
+
An element is a `{{nyml}}` block whose `kind:` **is** the element type. Place it
|
|
208
|
+
in the body where you want it to appear. Curated elements:
|
|
209
|
+
|
|
210
|
+
| `kind:` | What | Key fields |
|
|
211
|
+
|---|---|---|
|
|
212
|
+
| `article-title` | article title block | `title`, `subtitle`, `authors` (or `author`), `affiliations`, `notes`, `date`, `placement` |
|
|
213
|
+
| `report-title` | report title block | `title`, `subtitle`, `authors` (or `author`), `affiliations`, `notes`, `date`, `placement` |
|
|
214
|
+
| `exam-title` | exam title / cover | `title`, `subtitle`, `author`, `course`, `duration`, `total_points`, `student_fields`, `instructions`, `date`, `placement` |
|
|
215
|
+
| `abstract` | abstract block | `text`, `keywords` |
|
|
216
|
+
| `toc` | table of contents | `title`, `max_level`, `placement` |
|
|
217
|
+
| `letterhead` | letter letterhead bar | `organization`, `address`, `email`, `phone` |
|
|
218
|
+
| `letter-inside-address` | recipient address block | `to`, `organization`, `address` |
|
|
219
|
+
| `letter-signature` | closing + signature | `from`, `closing`, `title` |
|
|
220
|
+
| `cv-header` | CV name/contact header | `full_name`, `title`, `contacts` |
|
|
221
|
+
| `question-mc` | multiple-choice question | `n`, `pts`, `body`, `options`, `answer` (one letter, or several for select-all: `B, D`) |
|
|
222
|
+
| `question-open` | open-ended question | `n`, `pts`, `body`, `space`, `answer` |
|
|
223
|
+
| `timestamp` | "last updated" line | `label`, `date` |
|
|
224
|
+
|
|
225
|
+
### Title elements & `placement`
|
|
226
|
+
|
|
227
|
+
`article-title`, `report-title`, and `exam-title` each take a **`placement`**:
|
|
228
|
+
|
|
229
|
+
- `placement: section` *(default)* — an **inline title section**: the title block
|
|
230
|
+
sits at the top of the page and the body content flows on the **same page**
|
|
231
|
+
below it.
|
|
232
|
+
- `placement: page` — a **dedicated title / cover page** (a page break follows;
|
|
233
|
+
body page numbering starts at 1 on the next page).
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
{{nyml
|
|
237
|
+
kind: report-title
|
|
238
|
+
title: Q3 Reliability Review
|
|
239
|
+
subtitle: Incident trends and remediation
|
|
240
|
+
author: Platform Team
|
|
241
|
+
date: October 2026
|
|
242
|
+
placement: page
|
|
243
|
+
}}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Authors, affiliations & notes (`article-title` / `report-title`)
|
|
247
|
+
|
|
248
|
+
For papers with several authors, use **`authors`** (one author per line) plus
|
|
249
|
+
**`affiliations`** and **`notes`** (each a `key: text` list). `key` is the marker
|
|
250
|
+
you reference from an author. Each author line is `Name | marks | email | orcid`,
|
|
251
|
+
pipe-separated — the fields after the name are **auto-detected** (an `@` is the
|
|
252
|
+
email, an ORCID id / `orcid.org` link is the ORCID, anything else is the
|
|
253
|
+
affiliation/note markers), so order is flexible and any may be omitted. Email
|
|
254
|
+
renders as a mail link and ORCID as the ORCID iD icon.
|
|
255
|
+
|
|
256
|
+
```
|
|
257
|
+
{{nyml
|
|
258
|
+
kind: article-title
|
|
259
|
+
title: A Practical Comparison of RAFT and ATRP
|
|
260
|
+
subtitle: Controlled radical polymerization in the teaching lab
|
|
261
|
+
authors: |
|
|
262
|
+
Jane Doe | 1,* | jane.doe@example.edu | 0000-0002-1825-0097
|
|
263
|
+
John Smith | 2 | jsmith@example.org
|
|
264
|
+
Maria Garcia | 1,2
|
|
265
|
+
affiliations: |
|
|
266
|
+
1: Department of Chemistry, University of Example
|
|
267
|
+
2: Institute of Science, Example Lab
|
|
268
|
+
notes: |
|
|
269
|
+
*: Corresponding author
|
|
270
|
+
date: March 2026
|
|
271
|
+
}}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
The simple **`author`** single-line field still works for one author (or a plain
|
|
275
|
+
comma-separated list) when you don't need affiliations.
|
|
276
|
+
|
|
277
|
+
### Clean front matter (`front_matter: clean`)
|
|
278
|
+
|
|
279
|
+
When the title, abstract, and/or toc are each on their own page (`placement:
|
|
280
|
+
page`), set `front_matter: clean` in the document block to give those front-matter
|
|
281
|
+
pages **no running header, footer, or page number**, and **renumber the body**
|
|
282
|
+
so it runs 1…N over the main content only — front-matter pages are excluded from
|
|
283
|
+
both the current page number and the `… of N` total. The `article-page` and
|
|
284
|
+
`report-page` templates set it by default.
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
{{nyml
|
|
288
|
+
kind: document
|
|
289
|
+
template: report-page
|
|
290
|
+
front_matter: clean
|
|
291
|
+
}}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### `toc` & `placement`
|
|
295
|
+
|
|
296
|
+
`toc` builds a table of contents (with live page numbers) from your headings.
|
|
297
|
+
`max_level` is the deepest heading included (1–6, default 3). `placement: page`
|
|
298
|
+
puts it on its own page.
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
{{nyml
|
|
302
|
+
kind: toc
|
|
303
|
+
title: Contents
|
|
304
|
+
max_level: 2
|
|
305
|
+
placement: page
|
|
306
|
+
}}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Exam title — student fields & instructions
|
|
310
|
+
|
|
311
|
+
On `exam-title` (cover page or inline section — the **first page**), put the
|
|
312
|
+
student identity fields and the instructions, so they appear **once** rather than
|
|
313
|
+
in a running header on every page:
|
|
314
|
+
|
|
315
|
+
- **`student_fields`** — labelled fill-in blanks. Each **line is a row**; put
|
|
316
|
+
several fields on the **same line** by separating them with `|`. A trailing
|
|
317
|
+
`/ <number>` (e.g. `Score / 100`) becomes a suffix after the blank.
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
student_fields: |
|
|
321
|
+
Name | Student ID | Score / 100
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
(Or one per line to stack them: `Name`, then `Student ID`, then `Score / 100`.)
|
|
325
|
+
|
|
326
|
+
- **`instructions`** — a multiline block (Markdown, so lists work) shown under the
|
|
327
|
+
title. Optional: leave it empty and instead write the instructions as normal
|
|
328
|
+
Markdown at the **top of the main content** — either placement works, whichever
|
|
329
|
+
the instructor prefers.
|
|
330
|
+
|
|
331
|
+
```
|
|
332
|
+
{{nyml
|
|
333
|
+
kind: exam-title
|
|
334
|
+
title: Course Name — Exam 1
|
|
335
|
+
author: Instructor Name
|
|
336
|
+
duration: 60 minutes
|
|
337
|
+
total_points: 100 points
|
|
338
|
+
student_fields: |
|
|
339
|
+
Name | Student ID | Score / 100
|
|
340
|
+
instructions: |
|
|
341
|
+
**Instructions.** Read each question carefully.
|
|
342
|
+
- Answer all questions; show your work for full credit.
|
|
343
|
+
- No calculators or notes.
|
|
344
|
+
placement: page
|
|
345
|
+
}}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Exam questions
|
|
349
|
+
|
|
350
|
+
```
|
|
351
|
+
{{nyml
|
|
352
|
+
kind: question-mc
|
|
353
|
+
n: 1
|
|
354
|
+
pts: 5 pts
|
|
355
|
+
body: What is the SI unit of force?
|
|
356
|
+
options: |
|
|
357
|
+
A. Joule
|
|
358
|
+
B. Newton
|
|
359
|
+
C. Pascal
|
|
360
|
+
D. Watt
|
|
361
|
+
answer: B
|
|
362
|
+
}}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
For **select-all-that-apply**, list several correct letters in `answer` — `B, D`
|
|
366
|
+
(or `B D`, or `BD`); every matching option is ✓-marked in the answer key:
|
|
367
|
+
|
|
368
|
+
```
|
|
369
|
+
{{nyml
|
|
370
|
+
kind: question-mc
|
|
371
|
+
n: 2
|
|
372
|
+
pts: 6 pts
|
|
373
|
+
body: Which of these are vector quantities? (Select all that apply.)
|
|
374
|
+
options: |
|
|
375
|
+
A. Mass
|
|
376
|
+
B. Velocity
|
|
377
|
+
C. Temperature
|
|
378
|
+
D. Force
|
|
379
|
+
answer: B, D
|
|
380
|
+
}}
|
|
381
|
+
|
|
382
|
+
{{nyml
|
|
383
|
+
kind: question-open
|
|
384
|
+
n: 2
|
|
385
|
+
pts: 10 pts
|
|
386
|
+
body: Derive the work-energy theorem from Newton's second law.
|
|
387
|
+
space: 4cm
|
|
388
|
+
answer: Starting from F = ma and integrating over distance...
|
|
389
|
+
}}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
The `answer:` (and the ✓ on the correct `question-mc` option) is shown only when
|
|
393
|
+
the **`answer-key`** dynamic switch is `show` — so one source makes both the
|
|
394
|
+
student copy and the instructor key (see [Dynamic switch](#dynamic-switch--print-several-versions-from-one-source)).
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## Dynamic switch — print several versions from one source
|
|
399
|
+
|
|
400
|
+
`dynamic_choices` is a document setting (a `key: value` map) that drives
|
|
401
|
+
**conditional content**. Any element carrying `data-show-when="key=value"` is kept
|
|
402
|
+
only when the choice matches; `data-hide-when="key=value"` is removed when it
|
|
403
|
+
matches. The exam questions use this automatically: the answers are tagged
|
|
404
|
+
`data-show-when="answer-key=show"`.
|
|
405
|
+
|
|
406
|
+
```
|
|
407
|
+
{{nyml
|
|
408
|
+
kind: document
|
|
409
|
+
template: exam-page
|
|
410
|
+
dynamic_choices: |
|
|
411
|
+
answer-key: hide ← student copy (default); set to `show` for the key
|
|
412
|
+
}}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
- **In the file**: change `answer-key: hide` → `show` and re-render to produce the
|
|
416
|
+
instructor key (✓ marks + model answers revealed).
|
|
417
|
+
- **In the editor**: a live **answer key** dropdown appears in the toolbar
|
|
418
|
+
whenever a document uses `dynamic_choices` — flip it to preview/print either
|
|
419
|
+
version without editing the source.
|
|
420
|
+
|
|
421
|
+
It is general-purpose: define your own keys (e.g. `audience: student`) and tag
|
|
422
|
+
content with `data-show-when` / `data-hide-when` (an HTML span/div in the source,
|
|
423
|
+
or a future custom element) to print tailored variants from one file.
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
## 3 · Page breaks
|
|
428
|
+
|
|
429
|
+
Force a new page with the orz-markdown arbitrary-class container `page-break`
|
|
430
|
+
(no plugin, no extra syntax):
|
|
431
|
+
|
|
432
|
+
```
|
|
433
|
+
::: page-break
|
|
434
|
+
:::
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
Everything after it starts on a fresh page.
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
## 4 · Body content (print-first orz-markdown)
|
|
442
|
+
|
|
443
|
+
The body is full orz-markdown. Everything below **prints well** and is encouraged:
|
|
444
|
+
|
|
445
|
+
- **Headings, lists, tables, blockquotes, code blocks.**
|
|
446
|
+
- **Math** — inline `$E=mc^2$` and display `$$ ... $$` (KaTeX).
|
|
447
|
+
- **Mermaid** diagrams (```` ```mermaid ````), **smiles** chemistry
|
|
448
|
+
(`{{smiles ...}}`), **`{{chart}}`** (bar/line/pie), **`{{qr}}`** (a printed QR
|
|
449
|
+
is genuinely useful), images, and footnotes.
|
|
450
|
+
- **`{{toc}}`** inline anchors, **admonitions** (`::: info` / `::: success` /
|
|
451
|
+
`::: warning` / `::: danger`), and **columns** (`:::: cols`).
|
|
452
|
+
|
|
453
|
+
For the full orz-markdown syntax (containers, `{{name body}}` plugins,
|
|
454
|
+
`{{attrs[#id .class]}}`), read the orz-markdown skill at
|
|
455
|
+
`node_modules/orz-markdown/orz-markdown-skills/SKILL.md`.
|
|
456
|
+
|
|
457
|
+
### Print-first content
|
|
458
|
+
|
|
459
|
+
A `.paged.html` mimics paper, so author for print:
|
|
460
|
+
|
|
461
|
+
- **Avoid screen-only / dynamic constructs** — **tabs**, **spoilers**
|
|
462
|
+
(`::: spoil`), and **youtube**. They hide content or are video, which is
|
|
463
|
+
meaningless on paper.
|
|
464
|
+
- **Light backgrounds only** — there are no dark themes by design.
|
|
465
|
+
- These are guidance, not hard blocks — orz-markdown still renders them — but the
|
|
466
|
+
templates and themes won't use them.
|
|
467
|
+
|
|
468
|
+
---
|
|
469
|
+
|
|
470
|
+
## Do / don't
|
|
471
|
+
|
|
472
|
+
**Do**
|
|
473
|
+
- Start with one `{{nyml kind: document}}` block; in the common case set only
|
|
474
|
+
`template:` (plus maybe `theme:` / `decoration_color:`).
|
|
475
|
+
- Use a title element (`article-title` / `report-title` / `exam-title`) and pick
|
|
476
|
+
`placement: section` (inline) or `placement: page` (cover page).
|
|
477
|
+
- Force pages with `::: page-break` / `:::`.
|
|
478
|
+
- Keep content static and printable — tables, math, diagrams, charts, QR codes.
|
|
479
|
+
|
|
480
|
+
**Don't**
|
|
481
|
+
- Don't hand-edit the generated `.paged.html`; edit the Markdown source.
|
|
482
|
+
- Don't use tabs, `::: spoil`, or youtube — they don't print.
|
|
483
|
+
- Don't ask for a dark theme; the document is always light (ink on paper).
|
|
484
|
+
- Don't expect a PDF binary from the CLI — the PDF comes from the browser's
|
|
485
|
+
Print → Save as PDF on the open file.
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
## Examples
|
|
490
|
+
|
|
491
|
+
### An article with an inline title section and abstract
|
|
492
|
+
|
|
493
|
+
```
|
|
494
|
+
{{nyml
|
|
495
|
+
kind: document
|
|
496
|
+
template: article
|
|
497
|
+
theme: light-academic-1
|
|
498
|
+
decoration_color: "#2962a4"
|
|
499
|
+
}}
|
|
500
|
+
|
|
501
|
+
{{nyml
|
|
502
|
+
kind: article-title
|
|
503
|
+
title: A Practical Comparison of RAFT and ATRP
|
|
504
|
+
subtitle: Controlled radical polymerization in the teaching lab
|
|
505
|
+
author: Dr. Yu Wang
|
|
506
|
+
date: March 2026
|
|
507
|
+
}}
|
|
508
|
+
|
|
509
|
+
{{nyml
|
|
510
|
+
kind: abstract
|
|
511
|
+
text: We compare two controlled-radical methods on accessible monomers, with
|
|
512
|
+
emphasis on dispersity and reproducibility in an undergraduate setting.
|
|
513
|
+
keywords: RAFT, ATRP, controlled polymerization, dispersity
|
|
514
|
+
}}
|
|
515
|
+
|
|
516
|
+
## Introduction
|
|
517
|
+
|
|
518
|
+
Controlled radical polymerization gives narrow dispersity ($\PDI < 1.2$)...
|
|
519
|
+
|
|
520
|
+
## Methods
|
|
521
|
+
|
|
522
|
+
| Method | Mediator | Typical PDI |
|
|
523
|
+
|---|---|---|
|
|
524
|
+
| RAFT | thiocarbonylthio | 1.05–1.15 |
|
|
525
|
+
| ATRP | Cu/ligand | 1.05–1.20 |
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### A one-line note
|
|
529
|
+
|
|
530
|
+
```
|
|
531
|
+
{{nyml
|
|
532
|
+
kind: document
|
|
533
|
+
template: note
|
|
534
|
+
}}
|
|
535
|
+
|
|
536
|
+
Pick up dry cleaning, email the draft to the committee, and water the plants.
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
## Security
|
|
540
|
+
|
|
541
|
+
`.paged.html` files are **self-contained executable HTML** — opening one runs its
|
|
542
|
+
embedded JavaScript. Treat them like programs: only open or edit files from a
|
|
543
|
+
trusted source, and advise users the same. The one-click framework update is
|
|
544
|
+
opt-in (edit view only, explicit confirm) and always fetches from the hardcoded
|
|
545
|
+
canonical jsDelivr packages — a tampered file can't redirect it. A file's
|
|
546
|
+
integrity can't be verified from inside it; for authenticity, verify out-of-band.
|
|
547
|
+
See the README "Security" section.
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "orz-paged",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Self-contained, editable HTML documents (.paged.html) — Markdown shown as print pages via paged.js, edited in-browser, exported to PDF by printing. Sibling of orz-mdhtml and orz-slides.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"orz-paged": "dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"assets",
|
|
12
|
+
"orz-paged-skills"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc && npm run bundle",
|
|
16
|
+
"bundle": "tsx build/bundle.ts",
|
|
17
|
+
"gen": "tsx src/cli.ts",
|
|
18
|
+
"test": "vitest run",
|
|
19
|
+
"test:watch": "vitest",
|
|
20
|
+
"typecheck": "tsc --noEmit",
|
|
21
|
+
"clean": "rm -rf dist"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"paged",
|
|
25
|
+
"pagedjs",
|
|
26
|
+
"print",
|
|
27
|
+
"pdf",
|
|
28
|
+
"orz-markdown",
|
|
29
|
+
"markdown",
|
|
30
|
+
"self-contained",
|
|
31
|
+
"single-file"
|
|
32
|
+
],
|
|
33
|
+
"author": "Yu Wang <yuwang@orz.how>",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/wangyu16/orz-paged"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"orz-markdown": "^1.3.0",
|
|
41
|
+
"pagedjs": "^0.4.3"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^20.11.0",
|
|
45
|
+
"esbuild": "^0.21.5",
|
|
46
|
+
"path-browserify": "^1.0.1",
|
|
47
|
+
"tsx": "^4.7.0",
|
|
48
|
+
"typescript": "^5.4.0",
|
|
49
|
+
"vitest": "^2.0.0"
|
|
50
|
+
}
|
|
51
|
+
}
|