@owomark/view 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 ADDED
@@ -0,0 +1,296 @@
1
+ # @owomark/view
2
+
3
+ Rendering engine and interactive view layer for OwoMark. Provides the Gold Processor Factory for Markdown → HTML rendering, an incremental preview engine, and a DOM-backed editor view.
4
+
5
+ Official package: `@owomark/view`. The flat name `owomark-view` is reserved only as a compatibility redirect and should not be used for new installs.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @owomark/view
11
+ ```
12
+
13
+ For MDX support, also install the optional peer dependencies:
14
+
15
+ ```bash
16
+ npm install @mdx-js/mdx react react-dom
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ### Official CSS Entry
22
+
23
+ ```ts
24
+ import '@owomark/view/style.css';
25
+ ```
26
+
27
+ `style.css` is the official base theme bundle. It includes the structural CSS, built-in MDX component styles, side-annotation/slash-menu styles, and the light/dark preset token values. New users should start here.
28
+
29
+ ### Markdown → HTML (Static Rendering)
30
+
31
+ ```ts
32
+ import { createOwoMarkProcessor } from '@owomark/view/static';
33
+
34
+ const processor = createOwoMarkProcessor();
35
+ const result = await processor.process('# Hello\n\nA paragraph with **bold**.');
36
+ console.log(String(result));
37
+ // <h1 id="hello">Hello</h1>\n<p>A paragraph with <strong>bold</strong>.</p>
38
+ ```
39
+
40
+ ### MDX → HTML
41
+
42
+ Enable MDX to render JSX components and expressions at build time:
43
+
44
+ ```ts
45
+ import { createOwoMarkProcessor } from '@owomark/view/static';
46
+
47
+ const processor = createOwoMarkProcessor({ enableMdx: true });
48
+ const result = await processor.process(`
49
+ <Callout type="info">
50
+ Today is {new Date().getFullYear()}. MDX expressions just work.
51
+ </Callout>
52
+ `);
53
+ console.log(String(result));
54
+ // Built-in Callout component renders to styled HTML
55
+ ```
56
+
57
+ ### With Custom Components
58
+
59
+ ```ts
60
+ import { createElement } from 'react';
61
+ import { createOwoMarkProcessor } from '@owomark/view/static';
62
+
63
+ const Chart = ({ data }) => createElement('div', { className: 'chart' }, `Chart: ${data}`);
64
+
65
+ const processor = createOwoMarkProcessor({
66
+ enableMdx: true,
67
+ mdxComponents: {
68
+ Chart, // Add your own component
69
+ // Callout, // Built-ins are still available unless you override them
70
+ },
71
+ });
72
+
73
+ const result = await processor.process('<Chart data="revenue" />');
74
+ ```
75
+
76
+ ## Gold Processor Factory
77
+
78
+ The Gold Processor Factory is the single source of truth for OwoMark's rendering pipeline. Both preview and production consume the same factory.
79
+
80
+ ### `createOwoMarkProcessor(options?)`
81
+
82
+ Returns an `OwoMarkProcessor` with a single `process(source) → Promise<{ value, toString }>` method.
83
+
84
+ | Option | Type | Default | Description |
85
+ |--------|------|---------|-------------|
86
+ | `mode` | `'preview' \| 'production'` | `'preview'` | Rendering mode |
87
+ | `enableMdx` | `boolean` | `false` | Enable MDX rendering (JSX components + expressions) |
88
+ | `mdxComponents` | `Record<string, ComponentType>` | `{}` | Additional/override components (merged with built-ins) |
89
+ | `enableMath` | `boolean` | `true` | Enable KaTeX math rendering (`$...$`, `$$...$$`) |
90
+ | `enableSideAnnotation` | `boolean` | `true` | Enable side annotation syntax |
91
+ | `preserveSoftLineBreaks` | `boolean` | `false` | When false, plain newlines become `<br>` |
92
+ | `codeTheme` | `string` | `'vitesse-light'` | Shiki theme for code highlighting |
93
+ | `extraRemarkPlugins` | `PluginEntry[]` | `[]` | Additional remark plugins |
94
+ | `extraRehypePlugins` | `PluginEntry[]` | `[]` | Additional rehype plugins |
95
+
96
+ ### `getOwoMarkPlugins(options?)`
97
+
98
+ Returns `{ remarkPlugins, rehypePlugins }` arrays for use with `@mdx-js/mdx` compile paths directly. Excludes `remark-parse` and `remark-mdx` (MDX manages its own parser).
99
+
100
+ ## Theme Packages
101
+
102
+ `@owomark/view` owns the official base theme. Third-party themes should layer on top of it instead of replacing it.
103
+
104
+ ### Using a Third-Party Theme
105
+
106
+ ```ts
107
+ import '@owomark/view/style.css';
108
+ import 'owomark-theme-acme/style.css';
109
+ ```
110
+
111
+ Load `@owomark/view/style.css` first, then the theme package. The theme package should override `--owo-*` tokens and only add narrowly scoped visual overrides when tokens are not enough.
112
+
113
+ ### Authoring `owomark-theme-xxx`
114
+
115
+ A theme package should:
116
+
117
+ - depend on `@owomark/view` and require consumers to import `@owomark/view/style.css` first
118
+ - publish token overrides and theme classes, not a copy of OwoMark's structural CSS
119
+ - target the public `--owo-*` token contract instead of private internal selectors
120
+ - treat `@owomark/view/style.css`, `@owomark/view/owomark.css`, `@owomark/view/mdx-components.css`, and exported theme helpers as the supported extension surface
121
+
122
+ Minimal example:
123
+
124
+ ```css
125
+ .owo-theme-acme {
126
+ --owo-brand: #0f766e;
127
+ --owo-text: #123047;
128
+ --owo-surface: #f6fffb;
129
+ --owo-surface-raised: #ecfdf5;
130
+ --owo-border: #99f6e4;
131
+ --owo-border-strong: #5eead4;
132
+ }
133
+ ```
134
+
135
+ Then pass the class to OwoMark:
136
+
137
+ ```tsx
138
+ import { OwoMarkEditor } from '@owomark/react';
139
+ import '@owomark/view/style.css';
140
+ import 'owomark-theme-acme/style.css';
141
+
142
+ <OwoMarkEditor value={md} onChange={setMd} theme="owo-theme-acme" />;
143
+ ```
144
+
145
+ Compatibility rules for third-party themes:
146
+
147
+ - Do not re-implement editor layout, MDX component skeletons, or side-annotation structure unless you are intentionally shipping a full replacement theme.
148
+ - Do not assume private DOM structure is stable beyond documented classes and token hooks.
149
+ - Prefer base tokens such as `--owo-brand`, `--owo-text`, and `--owo-border`; only override component-level tokens when the editor needs to diverge from the shared base theme.
150
+
151
+ Stable token families:
152
+
153
+ - `--owo-*`: shared base tokens for brand, text, surface, border, semantic colors, and mono font
154
+ - `--owo-editor-*`: editor-only tokens such as caret, selection, heading, placeholder, and editor surfaces
155
+ - `--owo-syntax-*`: syntax-highlight tokens
156
+ - `--owo-toolbar-*`: toolbar tokens
157
+ - `--owo-panel-*`: panel/popover tokens
158
+
159
+ ## MDX Support
160
+
161
+ When `enableMdx: true`, the processor delegates to `@mdx-js/mdx` `evaluate()` + `renderToStaticMarkup()`. The output is still an HTML string — callers see no difference.
162
+
163
+ ### Built-in Components
164
+
165
+ Import the base styles for built-in components:
166
+
167
+ ```ts
168
+ import '@owomark/view/mdx-components.css';
169
+ ```
170
+
171
+ #### Theming
172
+
173
+ MDX component styles consume `--owo-*` base tokens with hardcoded fallbacks. This means:
174
+
175
+ - **Zero-config**: Components render correctly without any theme import (fallback colors are embedded).
176
+ - **With theme**: Import `@owomark/view/style.css` and components automatically adapt to light/dark mode.
177
+ - **Custom brand**: Set `--owo-brand` on a wrapper element to change the accent color across Callout (info), Steps, and Tabs simultaneously.
178
+
179
+ | Component | Props | Description |
180
+ |-----------|-------|-------------|
181
+ | `<Callout>` | `type?: 'info' \| 'warn' \| 'error' \| 'success'` | Styled callout box with icon |
182
+ | `<CodeDemo>` | `title?: string, language?: string, code: string` | Code demonstration block |
183
+ | `<Steps>` | (children: `<Step>`) | Numbered step-by-step guide with vertical line |
184
+ | `<Step>` | `title?: string` | Single step within `<Steps>` |
185
+ | `<Tabs>` | (children: `<Tab>`) | CSS-only tab switcher (no JS runtime) |
186
+ | `<Tab>` | `label?: string` | Single tab panel within `<Tabs>` |
187
+ | `<FileTree>` | (children: indented text) | Directory tree visualization |
188
+ | `<Kbd>` | (children: key name) | Keyboard key indicator |
189
+
190
+ ```mdx
191
+ <Callout type="warn">
192
+ Watch out — this is a warning.
193
+ </Callout>
194
+
195
+ <Steps>
196
+ <Step title="Install">Run `npm install @owomark/view`</Step>
197
+ <Step title="Configure">Enable MDX in your processor options</Step>
198
+ </Steps>
199
+
200
+ <Tabs>
201
+ <Tab label="npm">`npm install @owomark/view`</Tab>
202
+ <Tab label="pnpm">`pnpm add @owomark/view`</Tab>
203
+ </Tabs>
204
+
205
+ <FileTree>
206
+ {`src/
207
+ components/
208
+ lib/
209
+ styles/
210
+ package.json`}
211
+ </FileTree>
212
+
213
+ Press <Kbd>Ctrl</Kbd> + <Kbd>S</Kbd> to save.
214
+
215
+ <CodeDemo title="Hello World" language="python" code="print('hello')" />
216
+ ```
217
+
218
+ ### Component Override
219
+
220
+ User-provided components override built-ins with the same name:
221
+
222
+ ```ts
223
+ import { createElement } from 'react';
224
+
225
+ const MyCallout = ({ type, children }) =>
226
+ createElement('aside', { className: `my-callout-${type}` }, children);
227
+
228
+ const processor = createOwoMarkProcessor({
229
+ enableMdx: true,
230
+ mdxComponents: { Callout: MyCallout }, // Replaces built-in Callout
231
+ });
232
+ ```
233
+
234
+ ### Unregistered Components
235
+
236
+ Components used in MDX but not registered (built-in or user-provided) will:
237
+
238
+ 1. Print a `[owomark-mdx] Unregistered MDX component: <Name>` warning
239
+ 2. Render as `<div data-mdx-missing="Name">children</div>`
240
+ 3. Not interrupt the build
241
+
242
+ ### MDX + Side Annotations
243
+
244
+ The `{` and `=>` side annotation types conflict with MDX expression syntax. Use keyword forms instead:
245
+
246
+ | Symbol | Keyword | Example |
247
+ |--------|---------|---------|
248
+ | `{` | `left-brace` | `(>left-brace annotation text)` |
249
+ | `=>` | `fat-arrow` | `(>fat-arrow annotation text)` |
250
+
251
+ All other side annotation types (`}`, `]`, `->`, etc.) work unchanged in MDX mode.
252
+
253
+ ### Peer Dependencies
254
+
255
+ MDX support requires these optional peer dependencies:
256
+
257
+ - `@mdx-js/mdx` ^3.0.0
258
+ - `react` ^18.0.0 or ^19.0.0
259
+ - `react-dom` ^18.0.0 or ^19.0.0
260
+
261
+ When `enableMdx` is false (default), these are not needed.
262
+
263
+ ## Plugin Chain
264
+
265
+ The Gold Processor applies plugins in this order:
266
+
267
+ **Remark** (Markdown → mdast):
268
+ `remark-parse` → `remark-gfm` → `remark-math`* → `remark-directive` → `remark-mdx`† → `soft-breaks`‡ → `remark-side-annotation`* → extras
269
+
270
+ **Rehype** (hast → HTML):
271
+ `rehype-katex`* → `rehype-math-display-fix`* → `rehype-slug` → `rehype-pretty-code` → `rehype-side-annotation`* → extras → `rehype-stringify`
272
+
273
+ <small>* = gated by feature flag · † = production mode only · ‡ = when `preserveSoftLineBreaks` is false</small>
274
+
275
+ ## Exports
276
+
277
+ ### `@owomark/view/static` (SSR-safe)
278
+
279
+ ```ts
280
+ import {
281
+ createOwoMarkProcessor,
282
+ getOwoMarkPlugins,
283
+ // Built-in MDX components
284
+ DEFAULT_MDX_COMPONENTS,
285
+ Callout, CodeDemo, Steps, Step, Tabs, Tab, FileTree, Kbd,
286
+ // Internal plugins (for advanced use)
287
+ remarkSideAnnotation,
288
+ rehypeSideAnnotation,
289
+ remarkConvertSoftBreaksToHardBreaks,
290
+ rehypeMathDisplayFix,
291
+ } from '@owomark/view/static';
292
+ ```
293
+
294
+ ### `@owomark/view` (Full — includes editor + preview engine)
295
+
296
+ All static exports plus the interactive view engine, preview engine, DOM patcher, and side annotation positioner.