@openuji/render-respec 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.
@@ -0,0 +1,355 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <title>{{ title }}{% if subtitle %} — {{ subtitle }}{% endif %}</title>
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
+
9
+ <style>
10
+ /* ReSpec-inspired styling */
11
+ :root {
12
+ --main-bg: #fff;
13
+ --main-text: #000;
14
+ --heading-text: #005a9c;
15
+ --border-color: #ccc;
16
+ --code-bg: #f9f9f9;
17
+ --diagnostic-error: #d32f2f;
18
+ --diagnostic-warning: #f57c00;
19
+ --diagnostic-info: #0288d1;
20
+ }
21
+
22
+ body {
23
+ font-family: sans-serif;
24
+ line-height: 1.6;
25
+ max-width: 900px;
26
+ margin: 0 auto;
27
+ padding: 20px;
28
+ color: var(--main-text);
29
+ background: var(--main-bg);
30
+ }
31
+
32
+ /* Header styles */
33
+ .head {
34
+ border-bottom: 3px solid var(--border-color);
35
+ padding: 20px 0;
36
+ margin-bottom: 30px;
37
+ }
38
+
39
+ .head h1 {
40
+ color: var(--heading-text);
41
+ margin: 0 0 10px 0;
42
+ font-size: 2.5em;
43
+ }
44
+
45
+ .head h2 {
46
+ color: #666;
47
+ font-size: 1.2em;
48
+ font-weight: normal;
49
+ margin: 0;
50
+ }
51
+
52
+ .head dl {
53
+ margin: 20px 0 0 0;
54
+ }
55
+
56
+ .head dt {
57
+ font-weight: bold;
58
+ float: left;
59
+ clear: left;
60
+ width: 120px;
61
+ }
62
+
63
+ .head dd {
64
+ margin-left: 140px;
65
+ margin-bottom: 10px;
66
+ }
67
+
68
+ .head dd a {
69
+ color: var(--heading-text);
70
+ }
71
+
72
+ /* Status badge */
73
+ .status-badge {
74
+ display: inline-block;
75
+ padding: 5px 15px;
76
+ background: var(--heading-text);
77
+ color: white;
78
+ border-radius: 3px;
79
+ font-weight: bold;
80
+ margin-bottom: 10px;
81
+ }
82
+
83
+ /* TOC styles */
84
+ #toc {
85
+ border: 1px solid var(--border-color);
86
+ padding: 20px;
87
+ margin: 30px 0;
88
+ background: #f5f5f5;
89
+ }
90
+
91
+ #toc h2 {
92
+ margin-top: 0;
93
+ color: var(--heading-text);
94
+ }
95
+
96
+ #toc ol {
97
+ list-style: none;
98
+ counter-reset: item;
99
+ padding-left: 20px;
100
+ }
101
+
102
+ #toc li {
103
+ counter-increment: item;
104
+ margin: 5px 0;
105
+ }
106
+
107
+ #toc li::before {
108
+ content: counters(item, ".") ". ";
109
+ font-weight: bold;
110
+ margin-right: 5px;
111
+ }
112
+
113
+ #toc a {
114
+ color: var(--heading-text);
115
+ text-decoration: none;
116
+ }
117
+
118
+ #toc a:hover {
119
+ text-decoration: underline;
120
+ }
121
+
122
+ /* Section styles */
123
+ section {
124
+ margin: 30px 0;
125
+ }
126
+
127
+ section h2,
128
+ section h3,
129
+ section h4,
130
+ section h5,
131
+ section h6 {
132
+ color: var(--heading-text);
133
+ margin-top: 1.5em;
134
+ }
135
+
136
+ section#abstract {
137
+ padding: 15px;
138
+ border-left: 4px solid var(--heading-text);
139
+ background: #f0f8ff;
140
+ }
141
+
142
+ /* Definition and reference styles */
143
+ dfn {
144
+ font-weight: bold;
145
+ font-style: normal;
146
+ color: var(--heading-text);
147
+ }
148
+
149
+ a.internalDFN {
150
+ color: var(--heading-text);
151
+ text-decoration: underline dotted;
152
+ }
153
+
154
+ a.internalDFN:hover {
155
+ text-decoration: underline;
156
+ }
157
+
158
+ /* Code styles */
159
+ code {
160
+ background: var(--code-bg);
161
+ padding: 2px 5px;
162
+ border-radius: 3px;
163
+ font-family: Monaco, 'Courier New', monospace;
164
+ font-size: 0.9em;
165
+ }
166
+
167
+ pre {
168
+ background: var(--code-bg);
169
+ padding: 15px;
170
+ border-left: 3px solid var(--border-color);
171
+ overflow-x: auto;
172
+ }
173
+
174
+ pre code {
175
+ background: none;
176
+ padding: 0;
177
+ }
178
+
179
+ /* Diagnostics panel */
180
+ .diagnostics-panel {
181
+ margin: 30px 0;
182
+ padding: 20px;
183
+ background: #fff8e1;
184
+ border: 1px solid #ffd54f;
185
+ border-radius: 5px;
186
+ }
187
+
188
+ .diagnostics-panel h3 {
189
+ margin-top: 0;
190
+ color: #f57c00;
191
+ }
192
+
193
+ .diagnostic-summary {
194
+ font-weight: bold;
195
+ margin-bottom: 15px;
196
+ }
197
+
198
+ .diagnostic-file h4 {
199
+ color: #666;
200
+ margin: 15px 0 10px 0;
201
+ font-size: 1em;
202
+ }
203
+
204
+ .diagnostic-list {
205
+ list-style: none;
206
+ padding: 0;
207
+ }
208
+
209
+ .diagnostic-list li {
210
+ padding: 8px 12px;
211
+ margin: 5px 0;
212
+ border-radius: 3px;
213
+ }
214
+
215
+ .diagnostic-error {
216
+ background: #ffebee;
217
+ border-left: 4px solid var(--diagnostic-error);
218
+ }
219
+
220
+ .diagnostic-warning {
221
+ background: #fff3e0;
222
+ border-left: 4px solid var(--diagnostic-warning);
223
+ }
224
+
225
+ .diagnostic-info {
226
+ background: #e1f5fe;
227
+ border-left: 4px solid var(--diagnostic-info);
228
+ }
229
+
230
+ /* Lists */
231
+ ul,
232
+ ol {
233
+ margin: 15px 0;
234
+ }
235
+
236
+ li {
237
+ margin: 5px 0;
238
+ }
239
+
240
+ /* Links */
241
+ a {
242
+ color: var(--heading-text);
243
+ }
244
+
245
+ /* Footer */
246
+ footer {
247
+ margin-top: 50px;
248
+ padding-top: 20px;
249
+ border-top: 1px solid var(--border-color);
250
+ color: #666;
251
+ font-size: 0.9em;
252
+ }
253
+ </style>
254
+ </head>
255
+
256
+ <body>
257
+ <!-- Document Header -->
258
+ <div class="head">
259
+ <p>
260
+ {% if logos %}
261
+ {% for logo in logos %}
262
+ <a href="{{ logo.url or '#' }}">
263
+ <img src="{{ logo.src }}" alt="{{ logo.alt }}" {% if logo.width %}width="{{ logo.width }}" {% endif %}
264
+ {% if logo.height %}height="{{ logo.height }}" {% endif %}>
265
+ </a>
266
+ {% endfor %}
267
+ {% endif %}
268
+ </p>
269
+
270
+ <h1>{{ title }}</h1>
271
+ {% if subtitle %}
272
+ <h2>{{ subtitle }}</h2>
273
+ {% endif %}
274
+
275
+ <p class="status-badge">{{ specStatus }}</p>
276
+
277
+ <dl>
278
+ <dt>This version:</dt>
279
+ <dd>{{ publishDate }}</dd>
280
+
281
+ {% if previousPublishDate %}
282
+ <dt>Previous version:</dt>
283
+ <dd>{{ previousPublishDate }}</dd>
284
+ {% endif %}
285
+
286
+ {% if editors and editors.length > 0 %}
287
+ <dt>Editor{% if editors.length > 1 %}s{% endif %}:</dt>
288
+ <dd>
289
+ {% for editor in editors %}
290
+ {{ editor.name }}
291
+ {% if editor.company %}
292
+ (<a href="{{ editor.companyURL or '#' }}">{{ editor.company }}</a>)
293
+ {% endif %}
294
+ {% if editor.email %}
295
+ &lt;<a href="mailto:{{ editor.email }}">{{ editor.email }}</a>&gt;
296
+ {% endif %}
297
+ {% if not loop.last %}<br>{% endif %}
298
+ {% endfor %}
299
+ </dd>
300
+ {% endif %}
301
+
302
+ {% if authors and authors.length > 0 %}
303
+ <dt>Author{% if authors.length > 1 %}s{% endif %}:</dt>
304
+ <dd>
305
+ {% for author in authors %}
306
+ {{ author.name }}
307
+ {% if author.company %}
308
+ (<a href="{{ author.companyURL or '#' }}">{{ author.company }}</a>)
309
+ {% endif %}
310
+ {% if not loop.last %}<br>{% endif %}
311
+ {% endfor %}
312
+ </dd>
313
+ {% endif %}
314
+
315
+ {% if github %}
316
+ <dt>Repository:</dt>
317
+ <dd><a href="https://github.com/{{ github }}">{{ github }}</a></dd>
318
+ {% endif %}
319
+ </dl>
320
+
321
+ <p class="copyright">
322
+ Copyright © {{ copyrightStart }}{% if copyrightStart != publishDate|slice(0,4) %}-{{ publishDate|slice(0,4)
323
+ }}{% endif %}
324
+ </p>
325
+ </div>
326
+
327
+ <!-- Abstract -->
328
+ <section id="abstract">
329
+ <h2>Abstract</h2>
330
+ {{ abstract | safe }}
331
+ </section>
332
+
333
+ <!-- Table of Contents -->
334
+ {% if toc %}
335
+ <nav id="toc">
336
+ <h2>Table of Contents</h2>
337
+ <ol class="toc">
338
+ {{ toc | safe }}
339
+ </ol>
340
+ </nav>
341
+ {% endif %}
342
+
343
+ <!-- Diagnostics (if any) -->
344
+ {{ diagnostics | safe }}
345
+
346
+ <!-- Main Content -->
347
+ {{ content | safe }}
348
+
349
+ <!-- Footer -->
350
+ <footer>
351
+ <p>Generated by <strong>render-respec</strong> using the Speculator AST pipeline.</p>
352
+ </footer>
353
+ </body>
354
+
355
+ </html>
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@openuji/render-respec",
3
+ "version": "0.1.0",
4
+ "description": "Generate ReSpec-compatible HTML from specification source files using Speculator AST pipeline",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "render-respec": "dist/cli.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md"
20
+ ],
21
+ "keywords": [
22
+ "respec",
23
+ "specification",
24
+ "html",
25
+ "renderer",
26
+ "speculator",
27
+ "w3c"
28
+ ],
29
+ "license": "MIT",
30
+ "dependencies": {
31
+ "commander": "^12.0.0",
32
+ "nunjucks": "^3.2.4",
33
+ "prettier": "^3.1.0",
34
+ "zod": "^3.22.0",
35
+ "@openuji/speculator-lint": "0.1.0",
36
+ "@openuji/speculator": "0.5.1"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^20.10.0",
40
+ "@types/nunjucks": "^3.2.6",
41
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
42
+ "@typescript-eslint/parser": "^7.0.0",
43
+ "eslint": "^8.57.0",
44
+ "typescript": "^5.3.0",
45
+ "vitest": "^1.0.0"
46
+ },
47
+ "scripts": {
48
+ "build": "tsc && npm run postbuild",
49
+ "postbuild": "cp -r src/templates dist/",
50
+ "dev": "tsc --watch",
51
+ "test": "vitest run",
52
+ "test:watch": "vitest",
53
+ "lint": "eslint src --ext .ts",
54
+ "lint:fix": "eslint src --ext .ts --fix",
55
+ "typecheck": "tsc --noEmit"
56
+ }
57
+ }