orz-paged 0.1.0 → 0.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.
@@ -0,0 +1,144 @@
1
+ /**
2
+ * orz-paged — LOCKED INTERFACE.
3
+ *
4
+ * Every module codes against these types and nothing else. Changing a type here
5
+ * ripples across the document layer, the assembler, and the engine — treat edits
6
+ * as a coordinated change. (Mirrors orz-slides' `src/types.ts` role.)
7
+ *
8
+ * Vocabulary follows DESIGN.md §6–§9 and docs/document-model.md (the curated
9
+ * subset). Lengths: margins in **mm**, font size in **pt**, line-height unitless.
10
+ */
11
+ /** Named page sizes; a custom CSS size string (e.g. `"210mm 297mm"`) is allowed. */
12
+ export type PageSize = 'A3' | 'A4' | 'A5' | 'Letter' | 'Legal' | (string & {});
13
+ /** Where the page number sits in the margin boxes. */
14
+ export type PageNumberPosition = 'header-left' | 'header-center' | 'header-right' | 'footer-left' | 'footer-center' | 'footer-right' | 'none';
15
+ /** How the page number renders (counter formats). */
16
+ export type PageNumberStyle = 'simple' | 'page-n' | 'page-n-of-N' | 'n-of-N' | 'n-slash-N' | 'dash-n-dash' | 'brackets' | 'parentheses';
17
+ /**
18
+ * Curated document templates. `article`/`report`/`exam` come in two variants —
19
+ * `-page` (a dedicated title/cover page) and `-section` (title-on-content) — via
20
+ * the title element's `placement`. Legacy names (`article`/`report`/`exam`) still
21
+ * resolve to the `-section` variant (see resolveTemplate).
22
+ */
23
+ export type TemplateName = 'article-page' | 'article-section' | 'report-page' | 'report-section' | 'exam-page' | 'exam-section' | 'letter' | 'cover-letter' | 'cv' | 'cv-modern' | 'cv-elegant' | 'note';
24
+ /** Curated, light-only themes (DESIGN §8). `none` = plain. */
25
+ export type ThemeName = 'none' | 'light-academic-1' | 'light-academic-2' | 'light-neat-1' | 'light-neat-2' | 'light-neat-3' | 'beige-decent-1' | 'beige-decent-2';
26
+ /** Curated CDN font presets (DESIGN §4, §8). */
27
+ export type FontPresetName = 'system-serif' | 'source-serif-4' | 'lora' | 'crimson-pro' | 'noto-serif' | 'inter' | 'ibm-plex-sans' | 'roboto' | 'raleway' | 'noto-sans' | 'courier-prime';
28
+ /** Curated document elements (DESIGN §8). */
29
+ export type ElementKind = 'article-title' | 'report-title' | 'exam-title' | 'abstract' | 'letterhead' | 'letter-inside-address' | 'letter-signature' | 'toc' | 'cv-header' | 'question-mc' | 'question-open' | 'timestamp';
30
+ /** A title/cover element renders either as its own page or inline (DESIGN §8). */
31
+ export type Placement = 'page' | 'section';
32
+ /**
33
+ * Raw `{{nyml kind: document}}` payload — snake_case keys, loosely typed, every
34
+ * field optional. M1 (`settings`) parses this from the source.
35
+ */
36
+ export type RawDocSettings = Record<string, string | number | boolean | undefined>;
37
+ /**
38
+ * Fully-normalized document settings — every field resolved with defaults
39
+ * applied (after merging template + user layers). M5 (`page-css`) consumes this.
40
+ */
41
+ export interface DocSettings {
42
+ pageSize: PageSize;
43
+ marginTop: number;
44
+ marginBottom: number;
45
+ marginLeft: number;
46
+ marginRight: number;
47
+ pageBackground?: string;
48
+ fontPreset?: FontPresetName;
49
+ fontFamily?: string;
50
+ fontHeadingPreset?: FontPresetName;
51
+ fontMarginBoxPreset?: FontPresetName;
52
+ fontSize: number;
53
+ lineHeight: number;
54
+ decorationColor?: string;
55
+ pageNumberPosition: PageNumberPosition;
56
+ pageNumberStyle: PageNumberStyle;
57
+ pageNumberStartPage: number;
58
+ firstPageSkipNumber: boolean;
59
+ headerLeft: string;
60
+ headerCenter: string;
61
+ headerRight: string;
62
+ headerRule: boolean;
63
+ headerRuleColor?: string;
64
+ headerFontSize: number;
65
+ footerLeft: string;
66
+ footerCenter: string;
67
+ footerRight: string;
68
+ footerRule: boolean;
69
+ footerRuleColor?: string;
70
+ footerFontSize: number;
71
+ firstPageHideHeader: boolean;
72
+ firstPageHideFooter: boolean;
73
+ /** Strip header/footer/number from every `placement: page` front-matter page
74
+ * (title / abstract / toc on their own pages) and restart the page count so
75
+ * the first main-content page is 1. */
76
+ frontMatterClean: boolean;
77
+ limitImageToPage: boolean;
78
+ keepImageTogether: boolean;
79
+ repeatTableHeader: boolean;
80
+ avoidTableRowBreaks: boolean;
81
+ theme: ThemeName;
82
+ template?: TemplateName;
83
+ customCss?: string;
84
+ /** Dynamic switch — a key→value map driving conditional content. Elements
85
+ * carry `data-show-when="key=value"` / `data-hide-when="key=value"`; at render
86
+ * time non-matching ones are removed. Lets one source print several versions
87
+ * (e.g. `answer-key: hide` for the student copy, `show` for the key). */
88
+ dynamicChoices: Record<string, string>;
89
+ }
90
+ /** A partial settings layer (template defaults / user overrides) for merging. */
91
+ export type DocSettingsLayer = Partial<DocSettings>;
92
+ /** One `{{nyml kind: element}}` block: its kind + raw field map. */
93
+ export interface ElementSpec {
94
+ kind: ElementKind;
95
+ /** snake_case field → raw string value (multiline values preserved). */
96
+ fields: Record<string, string>;
97
+ /** parsed `placement:` if present (title/cover elements). */
98
+ placement?: Placement;
99
+ }
100
+ /** Capabilities an element renderer may use (injected — no hard orz-markdown dep). */
101
+ export interface ElementCtx {
102
+ /** Render inline Markdown (no wrapping `<p>`). */
103
+ renderInline(md: string): string;
104
+ /** Render block Markdown. */
105
+ renderBlock(md: string): string;
106
+ /** The resolved document settings (for accent color, fonts, etc.). */
107
+ settings: DocSettings;
108
+ }
109
+ /** Output of rendering one element. */
110
+ export interface ElementResult {
111
+ /** The element's HTML, placed into the document flow. */
112
+ html: string;
113
+ /** Scoped CSS for this element kind; injected **once** per kind (dedupe by kind). */
114
+ css?: string;
115
+ /** `page` → on its own page; `section` → inline. Defaults to `section`. */
116
+ placement: Placement;
117
+ }
118
+ /** A resolved font preset: a CDN stylesheet to load + the CSS family stack. */
119
+ export interface FontPreset {
120
+ /** `<link rel="stylesheet">` href (e.g. an @fontsource / Google Fonts URL). */
121
+ cssUrl: string;
122
+ /** the `font-family` value to use. */
123
+ family: string;
124
+ }
125
+ /**
126
+ * Result of assembling a document (A1) — everything the engine/template needs to
127
+ * render the paginated document. Pure data; no DOM.
128
+ */
129
+ export interface PagedAssembly {
130
+ /** The page CSS (from M5) + element scoped CSS + theme hook + custom CSS. */
131
+ css: string;
132
+ /** Font stylesheet URLs to `<link>` in <head> (from M3, deduped). */
133
+ fontCssUrls: string[];
134
+ /** Theme name to load its stylesheet. */
135
+ theme: ThemeName;
136
+ /** The document body HTML (content + elements), pre-pagination. */
137
+ bodyHtml: string;
138
+ /** The fully-resolved settings (for the editor settings panel + runtime). */
139
+ settings: DocSettings;
140
+ }
141
+ declare global {
142
+ /** Injected by esbuild at bundle time (build/bundle.ts). */
143
+ const __ORZPAGED_VERSION__: string;
144
+ }
package/package.json CHANGED
@@ -1,8 +1,16 @@
1
1
  {
2
2
  "name": "orz-paged",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
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
5
  "type": "module",
6
+ "main": "./dist/lib.js",
7
+ "types": "./dist/lib.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/lib.d.ts",
11
+ "default": "./dist/lib.js"
12
+ }
13
+ },
6
14
  "bin": {
7
15
  "orz-paged": "dist/cli.js"
8
16
  },