@ui-doc/html-renderer 0.4.0 → 1.0.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 +586 -151
- package/dist/HtmlRenderer.d.ts +3 -3
- package/dist/InlineReader.d.ts +1 -1
- package/dist/Lexer.types.d.ts +5 -4
- package/dist/NodeParser.d.ts +2 -2
- package/dist/Parser.types.d.ts +6 -6
- package/dist/Primitive.types.d.ts +1 -1
- package/dist/Reader.types.d.ts +8 -6
- package/dist/Renderer.types.d.ts +7 -7
- package/dist/assets/services/expand.d.ts +4 -2
- package/dist/assets/ui-doc.cjs +24 -13
- package/dist/assets/ui-doc.cjs.map +1 -1
- package/dist/assets/ui-doc.min.js +1 -1
- package/dist/assets/ui-doc.mjs +24 -13
- package/dist/assets/ui-doc.mjs.map +1 -1
- package/dist/assets/utils/delay.d.ts +1 -1
- package/dist/assets/utils/dom.d.ts +6 -3
- package/dist/index.cjs +146 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +145 -114
- package/dist/index.mjs.map +1 -1
- package/dist/nodes/CommentNode.d.ts +2 -1
- package/dist/nodes/TemplateNode.d.ts +2 -1
- package/dist/nodes/index.d.ts +4 -2
- package/dist/nodes/tags/for.d.ts +2 -2
- package/dist/nodes/tags/if.d.ts +3 -3
- package/dist/utils/index.d.ts +1 -1
- package/package.json +32 -29
- package/scripts/services/example.ts +3 -3
- package/scripts/services/expand.ts +19 -12
- package/scripts/services/sidebar.ts +4 -3
- package/scripts/utils/delay.ts +2 -2
- package/scripts/utils/dom.ts +9 -5
- package/LICENSE.md +0 -9
package/README.md
CHANGED
|
@@ -1,251 +1,686 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @ui-doc/html-renderer
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
HTML renderer for UI-Doc that converts UI-Doc context objects into interactive HTML documentation pages. It implements the `Renderer` interface from `@ui-doc/core` and includes a built-in template engine with zero dependencies.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Overview
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The HTML renderer provides:
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
- **Template Engine** - A lightweight, dependency-free template system with custom syntax
|
|
10
|
+
- **Built-in Templates** - Ready-to-use layouts, pages, and partials for documentation
|
|
11
|
+
- **Asset Management** - Pre-built CSS and JavaScript for documentation styling
|
|
12
|
+
- **Extensibility** - Custom templates and styling support
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
## Installation
|
|
12
15
|
|
|
16
|
+
```bash
|
|
17
|
+
npm install @ui-doc/html-renderer @ui-doc/core
|
|
13
18
|
```
|
|
14
|
-
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Basic Usage
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { HtmlRenderer, NodeParser } from '@ui-doc/html-renderer'
|
|
26
|
+
|
|
27
|
+
// Create a renderer instance
|
|
28
|
+
const renderer = new HtmlRenderer(NodeParser.init())
|
|
29
|
+
|
|
30
|
+
// Add templates
|
|
31
|
+
renderer.addLayout('default', {
|
|
32
|
+
source: 'inline',
|
|
33
|
+
content: `
|
|
34
|
+
<html>
|
|
35
|
+
<head>
|
|
36
|
+
<title>{{var:title}}</title>
|
|
37
|
+
</head>
|
|
38
|
+
<body>
|
|
39
|
+
{{page:default}}
|
|
40
|
+
</body>
|
|
41
|
+
</html>
|
|
42
|
+
`,
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
renderer.addPage('default', {
|
|
46
|
+
source: 'inline',
|
|
47
|
+
content: `
|
|
48
|
+
<h1>{{var:title}}</h1>
|
|
49
|
+
<div>{{var:content}}</div>
|
|
50
|
+
`,
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
// Generate HTML from context
|
|
54
|
+
const html = renderer.generate({
|
|
55
|
+
title: 'My Documentation',
|
|
56
|
+
page: {
|
|
57
|
+
title: 'Welcome',
|
|
58
|
+
content: '<p>Documentation content here</p>',
|
|
59
|
+
},
|
|
60
|
+
assets: [],
|
|
61
|
+
})
|
|
15
62
|
```
|
|
16
63
|
|
|
17
|
-
|
|
64
|
+
### Integration with UI-Doc
|
|
18
65
|
|
|
19
|
-
|
|
66
|
+
```ts
|
|
67
|
+
import { UIDoc } from '@ui-doc/core'
|
|
68
|
+
import { HtmlRenderer, NodeParser, TemplateLoader } from '@ui-doc/html-renderer'
|
|
69
|
+
import { NodeFileSystem } from '@ui-doc/node'
|
|
20
70
|
|
|
21
|
-
|
|
71
|
+
const fileSystem = new NodeFileSystem()
|
|
72
|
+
const renderer = new HtmlRenderer(NodeParser.init())
|
|
22
73
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
74
|
+
// Load built-in templates
|
|
75
|
+
const templatePath = await fileSystem.assetLoader().packagePath(
|
|
76
|
+
TemplateLoader.TEMPLATES_PACKAGE,
|
|
77
|
+
)
|
|
78
|
+
await TemplateLoader.load({ renderer, fileSystem, templatePath })
|
|
79
|
+
|
|
80
|
+
// Create UI-Doc instance
|
|
81
|
+
const uidoc = new UIDoc({ renderer })
|
|
28
82
|
|
|
29
|
-
|
|
83
|
+
// Process source files
|
|
84
|
+
uidoc.sourceCreate('path/to/source.css', await fileSystem.fileRead('path/to/source.css'))
|
|
30
85
|
|
|
31
|
-
|
|
86
|
+
// Output documentation
|
|
87
|
+
await uidoc.output(async (file, content) => {
|
|
88
|
+
await fileSystem.fileWrite(`./dist/${file}`, content)
|
|
89
|
+
})
|
|
32
90
|
|
|
91
|
+
// Copy required assets
|
|
92
|
+
const assetLoader = fileSystem.assetLoader()
|
|
93
|
+
await assetLoader.copy('@ui-doc/html-renderer/ui-doc.min.css', './dist/ui-doc.css')
|
|
94
|
+
await assetLoader.copy('@ui-doc/html-renderer/ui-doc.min.js', './dist/ui-doc.js')
|
|
33
95
|
```
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
96
|
+
|
|
97
|
+
## Template Syntax
|
|
98
|
+
|
|
99
|
+
The template engine uses double curly braces `{{...}}` for directives.
|
|
100
|
+
|
|
101
|
+
### Variables
|
|
102
|
+
|
|
103
|
+
Output values from the context:
|
|
104
|
+
|
|
105
|
+
```html
|
|
106
|
+
<h1>{{var:title}}</h1>
|
|
107
|
+
<p>{{var:description}}</p>
|
|
108
|
+
|
|
109
|
+
<!-- Access nested properties with dot notation -->
|
|
110
|
+
<div>{{var:page.content}}</div>
|
|
111
|
+
|
|
112
|
+
<!-- Escape HTML output -->
|
|
113
|
+
<div>{{var:userInput escape}}</div>
|
|
37
114
|
```
|
|
38
115
|
|
|
39
|
-
|
|
116
|
+
### Conditionals
|
|
40
117
|
|
|
41
|
-
|
|
42
|
-
- `==`
|
|
43
|
-
- `!==`
|
|
44
|
-
- `!=`
|
|
45
|
-
- `<`
|
|
46
|
-
- `<=`
|
|
47
|
-
- `>`
|
|
48
|
-
- `>=`
|
|
118
|
+
Render content conditionally:
|
|
49
119
|
|
|
50
|
-
|
|
120
|
+
```html
|
|
121
|
+
{{if:showContent}}
|
|
122
|
+
<p>This is visible when showContent is truthy</p>
|
|
123
|
+
{{/if}}
|
|
124
|
+
```
|
|
51
125
|
|
|
52
|
-
|
|
126
|
+
Supported comparison operators: `===`, `==`, `!==`, `!=`, `<`, `<=`, `>`, `>=`
|
|
53
127
|
|
|
54
|
-
|
|
128
|
+
```html
|
|
129
|
+
{{if:status === "active"}}
|
|
130
|
+
<span>Active</span>
|
|
131
|
+
{{/if}}
|
|
55
132
|
|
|
133
|
+
{{if:count > 5}}
|
|
134
|
+
<span>More than 5 items</span>
|
|
135
|
+
{{/if}}
|
|
56
136
|
```
|
|
57
|
-
|
|
137
|
+
|
|
138
|
+
### Loops
|
|
139
|
+
|
|
140
|
+
#### Array Loops
|
|
141
|
+
|
|
142
|
+
```html
|
|
143
|
+
<!-- Context: {"items": ["apple", "banana", "cherry"]} -->
|
|
58
144
|
<ul>
|
|
59
|
-
{{for:
|
|
60
|
-
|
|
145
|
+
{{for:items}}
|
|
146
|
+
<li>{{var:_loop.value}} (index: {{var:_loop.index}})</li>
|
|
61
147
|
{{/for}}
|
|
62
148
|
</ul>
|
|
63
149
|
|
|
64
150
|
<!-- Output: -->
|
|
65
151
|
<ul>
|
|
66
|
-
<li>
|
|
67
|
-
<li>
|
|
68
|
-
<li>
|
|
152
|
+
<li>apple (index: 0)</li>
|
|
153
|
+
<li>banana (index: 1)</li>
|
|
154
|
+
<li>cherry (index: 2)</li>
|
|
69
155
|
</ul>
|
|
70
156
|
```
|
|
71
157
|
|
|
72
|
-
####
|
|
158
|
+
#### Object Loops
|
|
73
159
|
|
|
74
|
-
```
|
|
75
|
-
<!--
|
|
160
|
+
```html
|
|
161
|
+
<!-- Context: {"colors": {"red": "#f00", "green": "#0f0", "blue": "#00f"}} -->
|
|
76
162
|
<ul>
|
|
77
|
-
{{for:
|
|
78
|
-
|
|
163
|
+
{{for:colors}}
|
|
164
|
+
<li>{{var:_loop.key}}: {{var:_loop.value}}</li>
|
|
79
165
|
{{/for}}
|
|
80
166
|
</ul>
|
|
81
167
|
|
|
82
168
|
<!-- Output: -->
|
|
83
169
|
<ul>
|
|
84
|
-
<li>
|
|
85
|
-
<li>
|
|
86
|
-
<li>
|
|
170
|
+
<li>red: #f00</li>
|
|
171
|
+
<li>green: #0f0</li>
|
|
172
|
+
<li>blue: #00f</li>
|
|
87
173
|
</ul>
|
|
88
174
|
```
|
|
89
175
|
|
|
90
|
-
####
|
|
176
|
+
#### Looping Over Object Arrays
|
|
91
177
|
|
|
92
|
-
|
|
178
|
+
```html
|
|
179
|
+
<!-- Context: {"sections": [{"title": "Intro", "content": "..."}, {"title": "Details", "content": "..."}]} -->
|
|
180
|
+
{{for:sections}}
|
|
181
|
+
<section>
|
|
182
|
+
<h2>{{var:title}}</h2>
|
|
183
|
+
<div>{{var:content}}</div>
|
|
184
|
+
</section>
|
|
185
|
+
{{/for}}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Loop variables available in `_loop`:
|
|
189
|
+
|
|
190
|
+
- `_loop.value` - Current item value
|
|
191
|
+
- `_loop.index` - Current iteration index (0-based)
|
|
192
|
+
- `_loop.key` - Current key (for object loops)
|
|
193
|
+
|
|
194
|
+
### Pages
|
|
195
|
+
|
|
196
|
+
Render registered page templates with optional context switching:
|
|
93
197
|
|
|
198
|
+
```html
|
|
199
|
+
<!-- Use the default page template -->
|
|
200
|
+
{{page}}
|
|
201
|
+
|
|
202
|
+
<!-- Use a specific page template -->
|
|
203
|
+
{{page:default}}
|
|
204
|
+
|
|
205
|
+
<!-- Use a page template with different context -->
|
|
206
|
+
{{page:default page}}
|
|
94
207
|
```
|
|
95
|
-
<!-- context: {"sections": [{"title": "Section 1", content: "<p>Section 1 content</p>"}, {"title": "Section 2", content: "<p>Section 2 content</p>"}]} -->
|
|
96
208
|
|
|
97
|
-
|
|
98
|
-
<section>
|
|
99
|
-
<h2>{{var::title}}</h2>
|
|
100
|
-
{{var:content}}
|
|
101
|
-
</section>
|
|
102
|
-
{{/for}}
|
|
209
|
+
### Partials
|
|
103
210
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
</section>
|
|
211
|
+
Include reusable template fragments:
|
|
212
|
+
|
|
213
|
+
```html
|
|
214
|
+
<!-- Include a partial -->
|
|
215
|
+
{{partial:nav-main}}
|
|
216
|
+
|
|
217
|
+
<!-- Include a partial with different context -->
|
|
218
|
+
{{partial:section currentSection}}
|
|
113
219
|
```
|
|
114
220
|
|
|
115
|
-
###
|
|
221
|
+
### Debug
|
|
222
|
+
|
|
223
|
+
Output context as JSON for debugging:
|
|
116
224
|
|
|
117
|
-
|
|
225
|
+
```html
|
|
226
|
+
<!-- Output entire context -->
|
|
227
|
+
{{debug}}
|
|
118
228
|
|
|
229
|
+
<!-- Output specific context property -->
|
|
230
|
+
{{debug:page}}
|
|
119
231
|
```
|
|
120
|
-
<!-- context: {"title": "Document Title", "page": {"title": "Page title", "content": "Page content"}} -->
|
|
121
232
|
|
|
122
|
-
|
|
123
|
-
<head>
|
|
124
|
-
<title>{{var:title}}</title>
|
|
125
|
-
</head>
|
|
126
|
-
<body>
|
|
127
|
-
<!-- using default layout with new context `page` -->
|
|
128
|
-
{{page:default page}}
|
|
129
|
-
</body>
|
|
130
|
-
</html>
|
|
233
|
+
## Template Types
|
|
131
234
|
|
|
132
|
-
|
|
133
|
-
<!-- context: {"title": "Page title", "content": "Page content"} -->
|
|
235
|
+
### Layouts
|
|
134
236
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
237
|
+
Define the overall HTML structure. A layout typically includes the `<html>`, `<head>`, and `<body>` tags.
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
renderer.addLayout('default', {
|
|
241
|
+
source: 'my-layout.html',
|
|
242
|
+
content: `
|
|
243
|
+
<!doctype html>
|
|
244
|
+
<html lang="en">
|
|
245
|
+
<head>
|
|
246
|
+
<meta charset="utf-8" />
|
|
247
|
+
<title>{{var:title}}</title>
|
|
248
|
+
{{var:styles}}
|
|
249
|
+
</head>
|
|
250
|
+
<body>
|
|
251
|
+
{{page:default}}
|
|
252
|
+
{{var:scripts}}
|
|
253
|
+
</body>
|
|
254
|
+
</html>
|
|
255
|
+
`,
|
|
256
|
+
})
|
|
257
|
+
```
|
|
139
258
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
</
|
|
150
|
-
|
|
151
|
-
</
|
|
259
|
+
### Pages
|
|
260
|
+
|
|
261
|
+
Define page-specific content structures:
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
renderer.addPage('default', {
|
|
265
|
+
source: 'my-page.html',
|
|
266
|
+
content: `
|
|
267
|
+
<header>
|
|
268
|
+
<h1>{{var:title}}</h1>
|
|
269
|
+
{{if:description}}
|
|
270
|
+
<p>{{var:description}}</p>
|
|
271
|
+
{{/if}}
|
|
272
|
+
</header>
|
|
273
|
+
<main>
|
|
274
|
+
{{for:sections}}
|
|
275
|
+
{{partial:section}}
|
|
276
|
+
{{/for}}
|
|
277
|
+
</main>
|
|
278
|
+
`,
|
|
279
|
+
})
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Partials
|
|
283
|
+
|
|
284
|
+
Create reusable template components:
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
renderer.addPartial('section', {
|
|
288
|
+
source: 'section.html',
|
|
289
|
+
content: `
|
|
290
|
+
<section id="{{var:id}}">
|
|
291
|
+
<h2>{{var:title}}</h2>
|
|
292
|
+
<div>{{var:content}}</div>
|
|
293
|
+
</section>
|
|
294
|
+
`,
|
|
295
|
+
})
|
|
152
296
|
```
|
|
153
297
|
|
|
154
|
-
|
|
298
|
+
## Loading Templates
|
|
299
|
+
|
|
300
|
+
### From Files
|
|
301
|
+
|
|
302
|
+
Use `TemplateLoader` to load templates from the file system:
|
|
303
|
+
|
|
304
|
+
```ts
|
|
305
|
+
import { TemplateLoader } from '@ui-doc/html-renderer'
|
|
306
|
+
import { NodeFileSystem } from '@ui-doc/node'
|
|
307
|
+
|
|
308
|
+
const fileSystem = new NodeFileSystem()
|
|
155
309
|
|
|
156
|
-
|
|
310
|
+
// Load templates from a directory
|
|
311
|
+
await TemplateLoader.load({
|
|
312
|
+
renderer,
|
|
313
|
+
fileSystem,
|
|
314
|
+
templatePath: './my-templates',
|
|
315
|
+
})
|
|
316
|
+
```
|
|
157
317
|
|
|
318
|
+
The loader expects this directory structure:
|
|
319
|
+
|
|
320
|
+
```text
|
|
321
|
+
my-templates/
|
|
322
|
+
layouts/
|
|
323
|
+
default.html
|
|
324
|
+
custom.html
|
|
325
|
+
pages/
|
|
326
|
+
default.html
|
|
327
|
+
index.html
|
|
328
|
+
partials/
|
|
329
|
+
nav.html
|
|
330
|
+
section.html
|
|
158
331
|
```
|
|
159
|
-
|
|
332
|
+
|
|
333
|
+
### Using Built-in Templates
|
|
334
|
+
|
|
335
|
+
The package includes ready-to-use templates:
|
|
336
|
+
|
|
337
|
+
```ts
|
|
338
|
+
const templatePath = await fileSystem.assetLoader().packagePath(
|
|
339
|
+
TemplateLoader.TEMPLATES_PACKAGE,
|
|
340
|
+
)
|
|
341
|
+
await TemplateLoader.load({ renderer, fileSystem, templatePath })
|
|
160
342
|
```
|
|
161
343
|
|
|
162
|
-
|
|
344
|
+
## Built-in Assets
|
|
345
|
+
|
|
346
|
+
The package provides pre-built CSS and JavaScript for documentation styling.
|
|
163
347
|
|
|
348
|
+
### CSS
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
# Full CSS
|
|
352
|
+
@ui-doc/html-renderer/ui-doc.css
|
|
353
|
+
|
|
354
|
+
# Minified CSS
|
|
355
|
+
@ui-doc/html-renderer/ui-doc.min.css
|
|
164
356
|
```
|
|
165
|
-
|
|
357
|
+
|
|
358
|
+
### JavaScript
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
# Full JavaScript
|
|
362
|
+
@ui-doc/html-renderer/ui-doc.js
|
|
363
|
+
|
|
364
|
+
# Minified JavaScript (for use in browsers)
|
|
365
|
+
@ui-doc/html-renderer/ui-doc.min.js
|
|
166
366
|
```
|
|
167
367
|
|
|
168
|
-
###
|
|
368
|
+
### Copying Assets
|
|
169
369
|
|
|
170
|
-
|
|
370
|
+
```ts
|
|
371
|
+
const assetLoader = fileSystem.assetLoader()
|
|
171
372
|
|
|
373
|
+
await assetLoader.copy(
|
|
374
|
+
'@ui-doc/html-renderer/ui-doc.min.css',
|
|
375
|
+
'./dist/ui-doc.css',
|
|
376
|
+
)
|
|
377
|
+
await assetLoader.copy(
|
|
378
|
+
'@ui-doc/html-renderer/ui-doc.min.js',
|
|
379
|
+
'./dist/ui-doc.js',
|
|
380
|
+
)
|
|
172
381
|
```
|
|
173
|
-
<!-- context: {"title": "Document Title", "page": {"title": "Page title", "content": "Page content"}} -->
|
|
174
382
|
|
|
175
|
-
|
|
176
|
-
<!-- Output: -->
|
|
177
|
-
{"title": "Document Title", "page": {"title": "Page title", "content": "Page content"}}
|
|
383
|
+
### Syntax Highlighting
|
|
178
384
|
|
|
179
|
-
|
|
180
|
-
<!-- Output: -->
|
|
181
|
-
{"title": "Page title", "content": "Page content"}
|
|
385
|
+
The built-in templates use highlight.js for code syntax highlighting. Include it in your output:
|
|
182
386
|
|
|
387
|
+
```ts
|
|
388
|
+
await assetLoader.copy(
|
|
389
|
+
'@highlightjs/cdn-assets/styles/default.min.css',
|
|
390
|
+
'./dist/highlight.css',
|
|
391
|
+
)
|
|
392
|
+
await assetLoader.copy(
|
|
393
|
+
'@highlightjs/cdn-assets/highlight.min.js',
|
|
394
|
+
'./dist/highlight.js',
|
|
395
|
+
)
|
|
183
396
|
```
|
|
184
397
|
|
|
185
|
-
##
|
|
398
|
+
## API Reference
|
|
186
399
|
|
|
187
|
-
|
|
400
|
+
### HtmlRenderer
|
|
188
401
|
|
|
189
|
-
|
|
402
|
+
The main renderer class implementing the `Renderer` interface.
|
|
403
|
+
|
|
404
|
+
#### Constructor
|
|
405
|
+
|
|
406
|
+
```text
|
|
407
|
+
new HtmlRenderer(parser: Parser)
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
- `parser` - A `Parser` instance (typically `NodeParser.init()`)
|
|
411
|
+
|
|
412
|
+
#### Methods
|
|
190
413
|
|
|
191
|
-
|
|
414
|
+
##### addLayout(name, layout)
|
|
192
415
|
|
|
193
|
-
|
|
416
|
+
Register a layout template.
|
|
194
417
|
|
|
195
|
-
|
|
418
|
+
```text
|
|
419
|
+
renderer.addLayout(name: string, layout: SourceInput): HtmlRenderer
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
- `name` - Unique identifier for the layout
|
|
423
|
+
- `layout` - Template source (object with `source` and `content` properties, or a `Reader` instance)
|
|
424
|
+
- Returns the renderer instance for chaining
|
|
425
|
+
|
|
426
|
+
##### addPage(name, page)
|
|
427
|
+
|
|
428
|
+
Register a page template.
|
|
429
|
+
|
|
430
|
+
```text
|
|
431
|
+
renderer.addPage(name: string, page: SourceInput): HtmlRenderer
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
- `name` - Unique identifier for the page
|
|
435
|
+
- `page` - Template source
|
|
436
|
+
- Returns the renderer instance for chaining
|
|
437
|
+
|
|
438
|
+
##### addPartial(name, partial)
|
|
439
|
+
|
|
440
|
+
Register a partial template.
|
|
441
|
+
|
|
442
|
+
```text
|
|
443
|
+
renderer.addPartial(name: string, partial: SourceInput): HtmlRenderer
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
- `name` - Unique identifier for the partial
|
|
447
|
+
- `partial` - Template source
|
|
448
|
+
- Returns the renderer instance for chaining
|
|
449
|
+
|
|
450
|
+
##### generate(context, layout?)
|
|
451
|
+
|
|
452
|
+
Generate HTML from a context object.
|
|
453
|
+
|
|
454
|
+
```text
|
|
455
|
+
renderer.generate(context: GenerateContext, layout?: string): string
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
- `context` - The UI-Doc context object to render
|
|
459
|
+
- `layout` - Optional layout name (defaults to `'default'`)
|
|
460
|
+
- Returns the generated HTML string
|
|
461
|
+
|
|
462
|
+
The `GenerateContext` includes:
|
|
463
|
+
|
|
464
|
+
- `title` - Document title
|
|
465
|
+
- `page` - Page context object
|
|
466
|
+
- `assets` - Array of asset objects with `type`, `src`, and optional `attrs`
|
|
467
|
+
- Additional properties from your UI-Doc configuration
|
|
468
|
+
|
|
469
|
+
##### page(name, context)
|
|
470
|
+
|
|
471
|
+
Render a specific page template with context.
|
|
472
|
+
|
|
473
|
+
```text
|
|
474
|
+
renderer.page(name: string, context: RenderContext): string
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
- `name` - Page template name (falls back to `'default'` if not found)
|
|
478
|
+
- `context` - Context object for rendering
|
|
479
|
+
- Returns the rendered HTML string
|
|
480
|
+
|
|
481
|
+
##### partial(name, context?)
|
|
482
|
+
|
|
483
|
+
Render a specific partial template with optional context.
|
|
484
|
+
|
|
485
|
+
```text
|
|
486
|
+
renderer.partial(name: string, context?: RenderContext): string
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
- `name` - Partial template name (falls back to `'default'` if not found)
|
|
490
|
+
- `context` - Optional context object (defaults to empty object)
|
|
491
|
+
- Returns the rendered HTML string
|
|
492
|
+
|
|
493
|
+
### NodeParser
|
|
494
|
+
|
|
495
|
+
Parser for the template syntax.
|
|
496
|
+
|
|
497
|
+
#### Static Methods
|
|
498
|
+
|
|
499
|
+
##### init()
|
|
500
|
+
|
|
501
|
+
Create and initialize a parser with all built-in tags.
|
|
502
|
+
|
|
503
|
+
```text
|
|
504
|
+
NodeParser.init(): NodeParser
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
Returns a configured `NodeParser` instance.
|
|
508
|
+
|
|
509
|
+
#### Methods
|
|
510
|
+
|
|
511
|
+
##### registerTagParser(tag)
|
|
512
|
+
|
|
513
|
+
Register a custom tag parser.
|
|
514
|
+
|
|
515
|
+
```text
|
|
516
|
+
parser.registerTagParser(tag: TagNodeParse): NodeParser
|
|
517
|
+
```
|
|
196
518
|
|
|
197
|
-
|
|
519
|
+
- `tag` - Tag parser definition
|
|
520
|
+
- Returns the parser instance for chaining
|
|
198
521
|
|
|
199
|
-
|
|
522
|
+
### TemplateLoader
|
|
200
523
|
|
|
201
|
-
|
|
524
|
+
Utility for loading templates from the file system.
|
|
202
525
|
|
|
526
|
+
#### Static Properties
|
|
527
|
+
|
|
528
|
+
##### TEMPLATES_PACKAGE
|
|
529
|
+
|
|
530
|
+
```text
|
|
531
|
+
static readonly TEMPLATES_PACKAGE: string
|
|
203
532
|
```
|
|
204
|
-
import { HtmlRenderer } from '@ui-doc/html-renderer'
|
|
205
533
|
|
|
206
|
-
|
|
207
|
-
|
|
534
|
+
Package identifier for built-in templates: `'@ui-doc/html-renderer/templates'`
|
|
535
|
+
|
|
536
|
+
#### Static Methods
|
|
537
|
+
|
|
538
|
+
##### load(options)
|
|
539
|
+
|
|
540
|
+
Load templates from a directory.
|
|
541
|
+
|
|
542
|
+
```text
|
|
543
|
+
static async load(options: {
|
|
544
|
+
renderer: HtmlRenderer
|
|
545
|
+
fileSystem: FileSystem
|
|
546
|
+
templatePath: string
|
|
547
|
+
}): Promise<void>
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
- `options.renderer` - The renderer to load templates into
|
|
551
|
+
- `options.fileSystem` - File system instance (typically `NodeFileSystem`)
|
|
552
|
+
- `options.templatePath` - Path to the templates directory
|
|
553
|
+
|
|
554
|
+
## Error Handling
|
|
555
|
+
|
|
556
|
+
The renderer throws specific errors for better debugging:
|
|
557
|
+
|
|
558
|
+
### HTMLRendererError
|
|
559
|
+
|
|
560
|
+
Thrown when a required template is not found.
|
|
561
|
+
|
|
562
|
+
```ts
|
|
563
|
+
try {
|
|
564
|
+
renderer.generate(context, 'nonexistent-layout')
|
|
565
|
+
} catch (error) {
|
|
566
|
+
if (error instanceof HTMLRendererError) {
|
|
567
|
+
console.error(`Template error: ${error.message}`)
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### HTMLRendererSyntaxError
|
|
573
|
+
|
|
574
|
+
Thrown when template syntax is invalid.
|
|
575
|
+
|
|
576
|
+
```ts
|
|
577
|
+
import { HTMLRendererSyntaxError } from '@ui-doc/html-renderer'
|
|
578
|
+
|
|
579
|
+
try {
|
|
580
|
+
renderer.addLayout('bad', {
|
|
581
|
+
source: 'inline',
|
|
582
|
+
content: '{{invalid:syntax',
|
|
583
|
+
})
|
|
584
|
+
} catch (error) {
|
|
585
|
+
if (error instanceof HTMLRendererSyntaxError) {
|
|
586
|
+
console.error(`Syntax error at line ${error.line}, column ${error.column}`)
|
|
587
|
+
console.error(error.message)
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
Properties:
|
|
593
|
+
|
|
594
|
+
- `message` - Error description
|
|
595
|
+
- `source` - Source identifier
|
|
596
|
+
- `line` - Line number where error occurred
|
|
597
|
+
- `column` - Column number where error occurred
|
|
598
|
+
- `code` - The problematic code snippet
|
|
599
|
+
|
|
600
|
+
## Custom Templates
|
|
601
|
+
|
|
602
|
+
You can create custom templates to match your design requirements.
|
|
603
|
+
|
|
604
|
+
### Example Custom Layout
|
|
605
|
+
|
|
606
|
+
```html
|
|
607
|
+
<!doctype html>
|
|
608
|
+
<html lang="en">
|
|
208
609
|
<head>
|
|
209
|
-
<meta charset="utf-8"
|
|
610
|
+
<meta charset="utf-8" />
|
|
611
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
210
612
|
<title>{{var:title}}</title>
|
|
613
|
+
{{var:styles}}
|
|
614
|
+
<link rel="stylesheet" href="custom-styles.css" />
|
|
211
615
|
</head>
|
|
212
|
-
<body>
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
</
|
|
616
|
+
<body class="custom-theme">
|
|
617
|
+
<header class="site-header">
|
|
618
|
+
<nav>{{partial:main-nav}}</nav>
|
|
619
|
+
</header>
|
|
216
620
|
|
|
217
|
-
|
|
218
|
-
|
|
621
|
+
<main class="site-content">
|
|
622
|
+
{{page:page.id page}}
|
|
623
|
+
</main>
|
|
219
624
|
|
|
220
|
-
|
|
221
|
-
<
|
|
222
|
-
|
|
625
|
+
<footer class="site-footer">
|
|
626
|
+
<p>© 2024 {{var:name}}</p>
|
|
627
|
+
</footer>
|
|
223
628
|
|
|
224
|
-
{{
|
|
225
|
-
|
|
226
|
-
|
|
629
|
+
{{var:scripts}}
|
|
630
|
+
<script src="custom-scripts.js"></script>
|
|
631
|
+
</body>
|
|
632
|
+
</html>
|
|
633
|
+
```
|
|
227
634
|
|
|
228
|
-
|
|
229
|
-
|
|
635
|
+
### Example Custom Page
|
|
636
|
+
|
|
637
|
+
```html
|
|
638
|
+
<article class="documentation-page">
|
|
639
|
+
<header class="page-header">
|
|
640
|
+
<h1>{{var:title}}</h1>
|
|
641
|
+
{{if:description}}
|
|
642
|
+
<div class="page-description">{{var:description}}</div>
|
|
643
|
+
{{/if}}
|
|
644
|
+
</header>
|
|
645
|
+
|
|
646
|
+
{{if:sections}}
|
|
647
|
+
<div class="page-sections">
|
|
648
|
+
{{for:sections}}
|
|
649
|
+
{{partial:custom-section}}
|
|
650
|
+
{{/for}}
|
|
651
|
+
</div>
|
|
652
|
+
{{/if}}
|
|
653
|
+
</article>
|
|
654
|
+
```
|
|
230
655
|
|
|
231
|
-
|
|
232
|
-
`
|
|
656
|
+
## Integration with Build Tools
|
|
233
657
|
|
|
234
|
-
|
|
658
|
+
While you can use the HTML renderer directly, it's typically used through build tool plugins:
|
|
235
659
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
renderer.addPartial('section', section)
|
|
660
|
+
- **Rollup** - Use [`@ui-doc/rollup`](../rollup/README.md)
|
|
661
|
+
- **Vite** - Use [`@ui-doc/vite`](../vite/README.md)
|
|
239
662
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
title: 'Example Page Title',
|
|
244
|
-
sections: [
|
|
245
|
-
{; content: "<p>Section 1 content</p>" },
|
|
246
|
-
{; title: "Section 2"; content: "<p>Section 2 content</p>" },
|
|
247
|
-
],
|
|
248
|
-
},
|
|
249
|
-
})
|
|
663
|
+
These plugins handle template loading, asset copying, and file watching automatically.
|
|
664
|
+
|
|
665
|
+
## TypeScript Support
|
|
250
666
|
|
|
667
|
+
The package includes full TypeScript definitions. All exported types are available for import:
|
|
668
|
+
|
|
669
|
+
```ts
|
|
670
|
+
import type {
|
|
671
|
+
Parser,
|
|
672
|
+
RenderContext,
|
|
673
|
+
Renderer,
|
|
674
|
+
SourceInput,
|
|
675
|
+
TagNodeParse,
|
|
676
|
+
} from '@ui-doc/html-renderer'
|
|
251
677
|
```
|
|
678
|
+
|
|
679
|
+
## Requirements
|
|
680
|
+
|
|
681
|
+
- Node.js >= 16.0.0
|
|
682
|
+
- `@ui-doc/core` (peer dependency)
|
|
683
|
+
|
|
684
|
+
## License
|
|
685
|
+
|
|
686
|
+
See [LICENSE.md](../../LICENSE.md) for license information.
|