@oml/markdown 0.7.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.
Files changed (112) hide show
  1. package/README.md +39 -0
  2. package/out/index.d.ts +2 -0
  3. package/out/index.js +4 -0
  4. package/out/index.js.map +1 -0
  5. package/out/md/index.d.ts +6 -0
  6. package/out/md/index.js +8 -0
  7. package/out/md/index.js.map +1 -0
  8. package/out/md/md-execution.d.ts +33 -0
  9. package/out/md/md-execution.js +3 -0
  10. package/out/md/md-execution.js.map +1 -0
  11. package/out/md/md-executor.d.ts +21 -0
  12. package/out/md/md-executor.js +498 -0
  13. package/out/md/md-executor.js.map +1 -0
  14. package/out/md/md-frontmatter.d.ts +4 -0
  15. package/out/md/md-frontmatter.js +48 -0
  16. package/out/md/md-frontmatter.js.map +1 -0
  17. package/out/md/md-registry.d.ts +7 -0
  18. package/out/md/md-registry.js +19 -0
  19. package/out/md/md-registry.js.map +1 -0
  20. package/out/md/md-runtime.d.ts +10 -0
  21. package/out/md/md-runtime.js +166 -0
  22. package/out/md/md-runtime.js.map +1 -0
  23. package/out/md/md-types.d.ts +40 -0
  24. package/out/md/md-types.js +3 -0
  25. package/out/md/md-types.js.map +1 -0
  26. package/out/md/md-yaml.d.ts +1 -0
  27. package/out/md/md-yaml.js +15 -0
  28. package/out/md/md-yaml.js.map +1 -0
  29. package/out/renderers/chart-renderer.d.ts +6 -0
  30. package/out/renderers/chart-renderer.js +392 -0
  31. package/out/renderers/chart-renderer.js.map +1 -0
  32. package/out/renderers/diagram-renderer.d.ts +7 -0
  33. package/out/renderers/diagram-renderer.js +2354 -0
  34. package/out/renderers/diagram-renderer.js.map +1 -0
  35. package/out/renderers/graph-renderer.d.ts +6 -0
  36. package/out/renderers/graph-renderer.js +1384 -0
  37. package/out/renderers/graph-renderer.js.map +1 -0
  38. package/out/renderers/index.d.ts +14 -0
  39. package/out/renderers/index.js +16 -0
  40. package/out/renderers/index.js.map +1 -0
  41. package/out/renderers/list-renderer.d.ts +6 -0
  42. package/out/renderers/list-renderer.js +252 -0
  43. package/out/renderers/list-renderer.js.map +1 -0
  44. package/out/renderers/matrix-renderer.d.ts +14 -0
  45. package/out/renderers/matrix-renderer.js +498 -0
  46. package/out/renderers/matrix-renderer.js.map +1 -0
  47. package/out/renderers/message-renderer.d.ts +6 -0
  48. package/out/renderers/message-renderer.js +14 -0
  49. package/out/renderers/message-renderer.js.map +1 -0
  50. package/out/renderers/registry.d.ts +9 -0
  51. package/out/renderers/registry.js +41 -0
  52. package/out/renderers/registry.js.map +1 -0
  53. package/out/renderers/renderer.d.ts +28 -0
  54. package/out/renderers/renderer.js +61 -0
  55. package/out/renderers/renderer.js.map +1 -0
  56. package/out/renderers/table-editor-renderer.d.ts +4 -0
  57. package/out/renderers/table-editor-renderer.js +9 -0
  58. package/out/renderers/table-editor-renderer.js.map +1 -0
  59. package/out/renderers/table-renderer.d.ts +95 -0
  60. package/out/renderers/table-renderer.js +1571 -0
  61. package/out/renderers/table-renderer.js.map +1 -0
  62. package/out/renderers/text-renderer.d.ts +7 -0
  63. package/out/renderers/text-renderer.js +219 -0
  64. package/out/renderers/text-renderer.js.map +1 -0
  65. package/out/renderers/tree-renderer.d.ts +4 -0
  66. package/out/renderers/tree-renderer.js +9 -0
  67. package/out/renderers/tree-renderer.js.map +1 -0
  68. package/out/renderers/types.d.ts +18 -0
  69. package/out/renderers/types.js +3 -0
  70. package/out/renderers/types.js.map +1 -0
  71. package/out/renderers/wikilink-utils.d.ts +6 -0
  72. package/out/renderers/wikilink-utils.js +100 -0
  73. package/out/renderers/wikilink-utils.js.map +1 -0
  74. package/out/static/browser-runtime.bundle.js +74155 -0
  75. package/out/static/browser-runtime.bundle.js.map +7 -0
  76. package/out/static/browser-runtime.d.ts +1 -0
  77. package/out/static/browser-runtime.js +218 -0
  78. package/out/static/browser-runtime.js.map +1 -0
  79. package/out/static/index.d.ts +1 -0
  80. package/out/static/index.js +3 -0
  81. package/out/static/index.js.map +1 -0
  82. package/out/static/runtime-assets.d.ts +2 -0
  83. package/out/static/runtime-assets.js +174 -0
  84. package/out/static/runtime-assets.js.map +1 -0
  85. package/package.json +74 -0
  86. package/src/index.ts +4 -0
  87. package/src/md/index.ts +8 -0
  88. package/src/md/md-execution.ts +51 -0
  89. package/src/md/md-executor.ts +598 -0
  90. package/src/md/md-frontmatter.ts +53 -0
  91. package/src/md/md-registry.ts +22 -0
  92. package/src/md/md-runtime.ts +191 -0
  93. package/src/md/md-types.ts +48 -0
  94. package/src/md/md-yaml.ts +17 -0
  95. package/src/renderers/chart-renderer.ts +473 -0
  96. package/src/renderers/diagram-renderer.ts +2520 -0
  97. package/src/renderers/graph-renderer.ts +1653 -0
  98. package/src/renderers/index.ts +16 -0
  99. package/src/renderers/list-renderer.ts +289 -0
  100. package/src/renderers/matrix-renderer.ts +616 -0
  101. package/src/renderers/message-renderer.ts +18 -0
  102. package/src/renderers/registry.ts +45 -0
  103. package/src/renderers/renderer.ts +84 -0
  104. package/src/renderers/table-editor-renderer.ts +8 -0
  105. package/src/renderers/table-renderer.ts +1868 -0
  106. package/src/renderers/text-renderer.ts +252 -0
  107. package/src/renderers/tree-renderer.ts +7 -0
  108. package/src/renderers/types.ts +22 -0
  109. package/src/renderers/wikilink-utils.ts +108 -0
  110. package/src/static/browser-runtime.ts +249 -0
  111. package/src/static/index.ts +3 -0
  112. package/src/static/runtime-assets.ts +175 -0
@@ -0,0 +1,16 @@
1
+ // Copyright (c) 2026 Modelware. All rights reserved.
2
+
3
+ export * from './types.js';
4
+ export * from './renderer.js';
5
+ export * from './table-editor-renderer.js';
6
+ export * from './table-renderer.js';
7
+ export * from './tree-renderer.js';
8
+ export * from './text-renderer.js';
9
+ export * from './message-renderer.js';
10
+ export * from './matrix-renderer.js';
11
+ export * from './list-renderer.js';
12
+ export * from './graph-renderer.js';
13
+ export * from './diagram-renderer.js';
14
+ export * from './chart-renderer.js';
15
+ export * from './registry.js';
16
+ export * from './wikilink-utils.js';
@@ -0,0 +1,289 @@
1
+ // Copyright (c) 2026 Modelware. All rights reserved.
2
+
3
+ import { QueryMarkdownBlockRenderer } from './renderer.js';
4
+ import type { MdBlockExecutionResult } from './types.js';
5
+ import { appendInlineValue } from './wikilink-utils.js';
6
+
7
+ type ListStyleSelectorKind = 'list' | 'item';
8
+ type ListStyleTarget = 'value' | 'marker';
9
+
10
+ type CompiledListStyleRule = {
11
+ selectors: Array<{ kind: ListStyleSelectorKind; condition?: string }>;
12
+ target: ListStyleTarget;
13
+ style: Record<string, string>;
14
+ };
15
+
16
+ type ListSelectorContext =
17
+ | { kind: 'list'; context: Record<string, never> }
18
+ | {
19
+ kind: 'item';
20
+ context: {
21
+ index: number;
22
+ value: string;
23
+ row: { get: (key?: unknown) => { value: string } | undefined };
24
+ };
25
+ };
26
+
27
+ export class ListMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
28
+ canRender(result: MdBlockExecutionResult): boolean {
29
+ return result.status === 'ok'
30
+ && result.kind === 'list'
31
+ && result.format === 'table'
32
+ && !!result.payload;
33
+ }
34
+
35
+ render(result: MdBlockExecutionResult): HTMLElement {
36
+ const container = this.createResultContainer(result.status);
37
+ container.classList.add('oml-md-result-plain');
38
+ const payload = result.payload;
39
+ if (!payload || payload.rows.length === 0) {
40
+ container.appendChild(this.createMessageContainer('No results.'));
41
+ return container;
42
+ }
43
+ const stylesheet = compileListStylesheet(result.options);
44
+
45
+ const list = document.createElement('ul');
46
+ list.className = 'oml-md-result-list';
47
+ const listContext: ListSelectorContext = { kind: 'list', context: {} };
48
+ for (const rule of stylesheet) {
49
+ if (!matchesListRule(rule, [listContext])) {
50
+ continue;
51
+ }
52
+ if (rule.target === 'marker') {
53
+ continue;
54
+ }
55
+ applyValueStyles(list, rule.style);
56
+ }
57
+
58
+ payload.rows.forEach((row, index) => {
59
+ const item = document.createElement('li');
60
+ const valueSpan = document.createElement('span');
61
+ valueSpan.className = 'oml-md-result-list-value';
62
+ appendInlineValue(valueSpan, row[0] ?? '');
63
+ item.appendChild(valueSpan);
64
+
65
+ const itemContext: ListSelectorContext = {
66
+ kind: 'item',
67
+ context: {
68
+ index,
69
+ value: row[0] ?? '',
70
+ row: createRowAccessor(payload.columns, row)
71
+ }
72
+ };
73
+ for (const rule of stylesheet) {
74
+ if (!matchesListRule(rule, [itemContext])) {
75
+ continue;
76
+ }
77
+ if (rule.target === 'marker') {
78
+ applyMarkerStyles(item, rule.style);
79
+ } else {
80
+ applyValueStyles(valueSpan, rule.style);
81
+ }
82
+ }
83
+ list.appendChild(item);
84
+ });
85
+
86
+ container.appendChild(list);
87
+ return container;
88
+ }
89
+ }
90
+
91
+ function compileListStylesheet(options: Record<string, unknown> | undefined): CompiledListStyleRule[] {
92
+ const rawStylesheet = options?.stylesheet;
93
+ if (!Array.isArray(rawStylesheet)) {
94
+ return [];
95
+ }
96
+ const compiled: CompiledListStyleRule[] = [];
97
+ for (const rawRule of rawStylesheet) {
98
+ if (!isRecord(rawRule)) {
99
+ continue;
100
+ }
101
+ const selectors = parseListSelectors(rawRule.selector);
102
+ if (selectors.length === 0) {
103
+ continue;
104
+ }
105
+ const style = normalizeStyle(rawRule.style);
106
+ if (Object.keys(style).length === 0) {
107
+ continue;
108
+ }
109
+ const target = rawRule.target === 'marker' ? 'marker' : 'value';
110
+ compiled.push({ selectors, target, style });
111
+ }
112
+ return compiled;
113
+ }
114
+
115
+ function matchesListRule(rule: CompiledListStyleRule, contexts: ReadonlyArray<ListSelectorContext>): boolean {
116
+ return rule.selectors.some((selector) => {
117
+ const contextEntry = contexts.find((entry) => entry.kind === selector.kind);
118
+ if (!contextEntry) {
119
+ return false;
120
+ }
121
+ return evaluateCondition(selector.condition, contextEntry.context);
122
+ });
123
+ }
124
+
125
+ function applyValueStyles(target: HTMLElement, style: Record<string, string>): void {
126
+ for (const [property, cssValue] of Object.entries(style)) {
127
+ target.style.setProperty(property, cssValue);
128
+ }
129
+ }
130
+
131
+ function applyMarkerStyles(listItem: HTMLElement, style: Record<string, string>): void {
132
+ for (const [property, cssValue] of Object.entries(style)) {
133
+ const normalized = property.trim().toLowerCase();
134
+ if (normalized === 'color') {
135
+ listItem.style.setProperty('--oml-list-marker-color', cssValue);
136
+ continue;
137
+ }
138
+ if (normalized === 'font-size') {
139
+ listItem.style.setProperty('--oml-list-marker-font-size', cssValue);
140
+ continue;
141
+ }
142
+ if (normalized === 'font-weight') {
143
+ listItem.style.setProperty('--oml-list-marker-font-weight', cssValue);
144
+ continue;
145
+ }
146
+ if (normalized === 'font-style') {
147
+ listItem.style.setProperty('--oml-list-marker-font-style', cssValue);
148
+ }
149
+ }
150
+ }
151
+
152
+ function parseListSelectors(rawSelector: unknown): Array<{ kind: ListStyleSelectorKind; condition?: string }> {
153
+ if (typeof rawSelector !== 'string') {
154
+ return [];
155
+ }
156
+ const parts = splitSelectors(rawSelector);
157
+ const selectors: Array<{ kind: ListStyleSelectorKind; condition?: string }> = [];
158
+ for (const part of parts) {
159
+ const parsed = parseListSelector(part);
160
+ if (parsed) {
161
+ selectors.push(parsed);
162
+ }
163
+ }
164
+ return selectors;
165
+ }
166
+
167
+ function splitSelectors(rawSelector: string): string[] {
168
+ const parts: string[] = [];
169
+ let current = '';
170
+ let bracketDepth = 0;
171
+ let quote: '"' | "'" | undefined;
172
+ for (let index = 0; index < rawSelector.length; index += 1) {
173
+ const char = rawSelector[index];
174
+ if (quote) {
175
+ current += char;
176
+ if (char === quote && rawSelector[index - 1] !== '\\') {
177
+ quote = undefined;
178
+ }
179
+ continue;
180
+ }
181
+ if (char === '"' || char === "'") {
182
+ quote = char;
183
+ current += char;
184
+ continue;
185
+ }
186
+ if (char === '[') {
187
+ bracketDepth += 1;
188
+ current += char;
189
+ continue;
190
+ }
191
+ if (char === ']' && bracketDepth > 0) {
192
+ bracketDepth -= 1;
193
+ current += char;
194
+ continue;
195
+ }
196
+ if (char === ',' && bracketDepth === 0) {
197
+ parts.push(current.trim());
198
+ current = '';
199
+ continue;
200
+ }
201
+ current += char;
202
+ }
203
+ if (current.trim()) {
204
+ parts.push(current.trim());
205
+ }
206
+ return parts;
207
+ }
208
+
209
+ function parseListSelector(selector: string): { kind: ListStyleSelectorKind; condition?: string } | undefined {
210
+ const trimmed = selector.trim();
211
+ if (!trimmed) {
212
+ return undefined;
213
+ }
214
+ const bracketStart = trimmed.indexOf('[');
215
+ if (bracketStart === -1) {
216
+ return toListSelector(trimmed, undefined);
217
+ }
218
+ if (!trimmed.endsWith(']')) {
219
+ return undefined;
220
+ }
221
+ const kind = trimmed.slice(0, bracketStart).trim();
222
+ const condition = trimmed.slice(bracketStart + 1, -1).trim();
223
+ return toListSelector(kind, condition || undefined);
224
+ }
225
+
226
+ function toListSelector(kind: string, condition: string | undefined): { kind: ListStyleSelectorKind; condition?: string } | undefined {
227
+ const normalized = kind.trim().toLowerCase();
228
+ if (normalized !== 'list' && normalized !== 'item') {
229
+ return undefined;
230
+ }
231
+ return { kind: normalized, condition };
232
+ }
233
+
234
+ function normalizeStyle(rawStyle: unknown): Record<string, string> {
235
+ if (!isRecord(rawStyle)) {
236
+ return {};
237
+ }
238
+ const style: Record<string, string> = {};
239
+ for (const [property, rawValue] of Object.entries(rawStyle)) {
240
+ if (!property.trim()) {
241
+ continue;
242
+ }
243
+ if (rawValue === undefined || rawValue === null) {
244
+ continue;
245
+ }
246
+ style[property] = String(rawValue);
247
+ }
248
+ return style;
249
+ }
250
+
251
+ function createRowAccessor(columns: string[], row: string[]): { get: (key?: unknown) => { value: string } | undefined } {
252
+ return {
253
+ get: (key?: unknown) => {
254
+ if (typeof key === 'number' && Number.isInteger(key)) {
255
+ const value = row[key];
256
+ return value === undefined ? undefined : { value };
257
+ }
258
+ if (typeof key === 'string') {
259
+ const index = columns.indexOf(key);
260
+ if (index < 0) {
261
+ return undefined;
262
+ }
263
+ const value = row[index];
264
+ return value === undefined ? undefined : { value };
265
+ }
266
+ return undefined;
267
+ }
268
+ };
269
+ }
270
+
271
+ function evaluateCondition(condition: string | undefined, context: object): boolean {
272
+ if (!condition) {
273
+ return true;
274
+ }
275
+ try {
276
+ const scope = Object.assign(Object.create(null), context) as Record<string, unknown>;
277
+ const keys = Object.keys(scope);
278
+ const values = keys.map((key) => scope[key]);
279
+ // eslint-disable-next-line no-new-func
280
+ const evaluator = new Function(...keys, `"use strict"; return (${condition});`);
281
+ return Boolean(evaluator(...values));
282
+ } catch {
283
+ return false;
284
+ }
285
+ }
286
+
287
+ function isRecord(value: unknown): value is Record<string, unknown> {
288
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
289
+ }