@oml/markdown 0.9.0 → 0.11.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/out/md/md-executor.js +2 -9
- package/out/md/md-executor.js.map +1 -1
- package/out/md/md-runtime.js +2 -26
- package/out/md/md-runtime.js.map +1 -1
- package/out/renderers/chart-renderer.js +72 -4
- package/out/renderers/chart-renderer.js.map +1 -1
- package/out/renderers/diagram-renderer.js +738 -252
- package/out/renderers/diagram-renderer.js.map +1 -1
- package/out/renderers/graph-renderer.js +5 -9
- package/out/renderers/graph-renderer.js.map +1 -1
- package/out/renderers/renderer.d.ts +3 -0
- package/out/renderers/renderer.js +53 -0
- package/out/renderers/renderer.js.map +1 -1
- package/out/renderers/table-renderer.d.ts +8 -1
- package/out/renderers/table-renderer.js +22 -1
- package/out/renderers/table-renderer.js.map +1 -1
- package/out/renderers/text-renderer.d.ts +0 -1
- package/out/renderers/text-renderer.js +2 -9
- package/out/renderers/text-renderer.js.map +1 -1
- package/out/renderers/wikilink-utils.js +3 -10
- package/out/renderers/wikilink-utils.js.map +1 -1
- package/out/static/browser-runtime.bundle.js +1591 -6408
- package/out/static/browser-runtime.bundle.js.map +4 -4
- package/out/static/browser-runtime.js +3 -0
- package/out/static/browser-runtime.js.map +1 -1
- package/package.json +2 -2
- package/src/md/md-executor.ts +2 -9
- package/src/md/md-runtime.ts +2 -28
- package/src/renderers/chart-renderer.ts +93 -2
- package/src/renderers/diagram-renderer.ts +799 -258
- package/src/renderers/graph-renderer.ts +5 -9
- package/src/renderers/renderer.ts +66 -0
- package/src/renderers/table-renderer.ts +39 -3
- package/src/renderers/text-renderer.ts +2 -7
- package/src/renderers/wikilink-utils.ts +4 -10
- package/src/static/browser-runtime.ts +3 -0
- package/src/static/markdown-webview.css +1361 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
2
|
|
|
3
|
-
import { CanvasMarkdownBlockRenderer } from './renderer.js';
|
|
3
|
+
import { CanvasMarkdownBlockRenderer, displayLabelFromIri } from './renderer.js';
|
|
4
4
|
import type { MdBlockExecutionResult } from './types.js';
|
|
5
|
+
import { isIriValue, shortLabelFromIri } from './wikilink-utils.js';
|
|
5
6
|
|
|
6
7
|
// --- CSS variable constants for base styles (auto-update on VS Code theme) ---
|
|
7
8
|
const CSS_NODE_FILL = 'var(--vscode-button-secondaryBackground, var(--vscode-button-background, #5a5a8a))';
|
|
@@ -1637,15 +1638,10 @@ function shortLabel(value: string): string {
|
|
|
1637
1638
|
if (value.startsWith('_:')) {
|
|
1638
1639
|
return value;
|
|
1639
1640
|
}
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
return value.slice(hash + 1);
|
|
1641
|
+
if (isIriValue(value)) {
|
|
1642
|
+
return shortLabelFromIri(value);
|
|
1643
1643
|
}
|
|
1644
|
-
|
|
1645
|
-
if (slash >= 0 && slash < value.length - 1) {
|
|
1646
|
-
return value.slice(slash + 1);
|
|
1647
|
-
}
|
|
1648
|
-
return value;
|
|
1644
|
+
return displayLabelFromIri(value);
|
|
1649
1645
|
}
|
|
1650
1646
|
|
|
1651
1647
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
@@ -7,6 +7,72 @@ export interface MarkdownBlockRenderer {
|
|
|
7
7
|
render(result: MdBlockExecutionResult): HTMLElement;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
let iriLabelSnapshot: ReadonlyMap<string, string> | undefined;
|
|
11
|
+
|
|
12
|
+
export function setIriLabelSnapshot(snapshot?: ReadonlyMap<string, string> | Record<string, string>): void {
|
|
13
|
+
if (!snapshot) {
|
|
14
|
+
iriLabelSnapshot = undefined;
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (snapshot instanceof Map) {
|
|
18
|
+
iriLabelSnapshot = snapshot;
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
iriLabelSnapshot = new Map(
|
|
22
|
+
Object.entries(snapshot).map(([iri, label]) => [normalizeIriLabelKey(iri), String(label)] as const)
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function runWithIriLabelSnapshot<T>(
|
|
27
|
+
snapshot: ReadonlyMap<string, string> | Record<string, string> | undefined,
|
|
28
|
+
action: () => T
|
|
29
|
+
): T {
|
|
30
|
+
const previous = iriLabelSnapshot;
|
|
31
|
+
setIriLabelSnapshot(snapshot);
|
|
32
|
+
try {
|
|
33
|
+
return action();
|
|
34
|
+
} finally {
|
|
35
|
+
iriLabelSnapshot = previous;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function displayLabelFromIri(iri: string): string {
|
|
40
|
+
const normalized = normalizeIriLabelKey(iri);
|
|
41
|
+
if (!normalized) {
|
|
42
|
+
return iri;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const labeled = iriLabelSnapshot?.get(normalized);
|
|
46
|
+
if (typeof labeled === 'string' && labeled.length > 0) {
|
|
47
|
+
return labeled;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const fragmentIndex = normalized.lastIndexOf('#');
|
|
51
|
+
if (fragmentIndex >= 0 && fragmentIndex < normalized.length - 1) {
|
|
52
|
+
return decodeIriLabelSegment(normalized.slice(fragmentIndex + 1));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const withoutQuery = normalized.split('?')[0]?.replace(/\/+$/, '') ?? normalized;
|
|
56
|
+
const slashIndex = withoutQuery.lastIndexOf('/');
|
|
57
|
+
if (slashIndex >= 0 && slashIndex < withoutQuery.length - 1) {
|
|
58
|
+
return decodeIriLabelSegment(withoutQuery.slice(slashIndex + 1));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return normalized;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function normalizeIriLabelKey(iri: string): string {
|
|
65
|
+
return String(iri ?? '').trim().replace(/^<|>$/g, '');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function decodeIriLabelSegment(value: string): string {
|
|
69
|
+
try {
|
|
70
|
+
return decodeURIComponent(value);
|
|
71
|
+
} catch {
|
|
72
|
+
return value;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
10
76
|
export type TableBlockKind = 'table' | 'table-editor' | 'matrix' | 'tree';
|
|
11
77
|
export type CanvasBlockKind = 'graph' | 'diagram';
|
|
12
78
|
|
|
@@ -18,7 +18,6 @@ type TableEditorActionContext = {
|
|
|
18
18
|
datatypeIri?: string;
|
|
19
19
|
classIri?: string;
|
|
20
20
|
nodeKind?: string;
|
|
21
|
-
enumValues?: string[];
|
|
22
21
|
editor?: 'multiline';
|
|
23
22
|
}>;
|
|
24
23
|
blockSource?: string;
|
|
@@ -28,6 +27,14 @@ type TableEditorActionContext = {
|
|
|
28
27
|
pointerY?: number;
|
|
29
28
|
};
|
|
30
29
|
|
|
30
|
+
type TableRootWithAiContext = HTMLDivElement & {
|
|
31
|
+
__omlAiContext?: {
|
|
32
|
+
columns: string[];
|
|
33
|
+
rows: Array<{ iri: string; cells: string[] }>;
|
|
34
|
+
blockSource?: string;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
|
|
31
38
|
export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
32
39
|
protected readonly tableKinds: ReadonlyArray<TableBlockKind> = ['table'];
|
|
33
40
|
|
|
@@ -93,7 +100,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
93
100
|
options: Record<string, unknown> | undefined,
|
|
94
101
|
blockSource?: string
|
|
95
102
|
): HTMLElement {
|
|
96
|
-
const root = document.createElement('div');
|
|
103
|
+
const root = document.createElement('div') as TableRootWithAiContext;
|
|
97
104
|
root.className = 'table-root graph-root';
|
|
98
105
|
const isTree = this.tableKinds.includes('tree');
|
|
99
106
|
const allRowsWithIndex = rows.map((cells, index) => ({ index, cells }));
|
|
@@ -115,6 +122,16 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
115
122
|
...row,
|
|
116
123
|
cells: visibleColumnIndexes.map((columnIndex) => row.cells[columnIndex] ?? ''),
|
|
117
124
|
}));
|
|
125
|
+
root.__omlAiContext = {
|
|
126
|
+
columns: visibleColumns.slice(),
|
|
127
|
+
rows: rowsWithIndex
|
|
128
|
+
.map((row) => ({
|
|
129
|
+
iri: (row.cells[0] ?? '').trim(),
|
|
130
|
+
cells: row.cells.slice(),
|
|
131
|
+
}))
|
|
132
|
+
.filter((row) => row.iri.length > 0),
|
|
133
|
+
blockSource,
|
|
134
|
+
};
|
|
118
135
|
const columnContexts = createColumnContexts(visibleColumns, rowsWithIndex);
|
|
119
136
|
const treeModel = isTree
|
|
120
137
|
? this.createTreeModel(columns, allRowsWithIndex, visibleColumnIndexes, options)
|
|
@@ -219,10 +236,16 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
219
236
|
return;
|
|
220
237
|
}
|
|
221
238
|
const filtered = this.applyFiltersAndSorting(columns, sourceRows, state);
|
|
222
|
-
this.
|
|
239
|
+
const csvExport = this.transformCsvDownloadData(visibleColumns, filtered.map((entry) => entry.cells));
|
|
240
|
+
this.requestCsvDownload(csvExport.columns, csvExport.rows);
|
|
223
241
|
});
|
|
224
242
|
controlsRight.appendChild(downloadButton);
|
|
225
243
|
|
|
244
|
+
const uploadButton = this.createUploadCsvButton(visibleColumns, rowsWithIndex, isTree, blockSource);
|
|
245
|
+
if (uploadButton) {
|
|
246
|
+
controlsRight.appendChild(uploadButton);
|
|
247
|
+
}
|
|
248
|
+
|
|
226
249
|
controls.appendChild(controlsLeft);
|
|
227
250
|
controls.appendChild(controlsRight);
|
|
228
251
|
root.appendChild(controls);
|
|
@@ -958,6 +981,19 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
958
981
|
return value;
|
|
959
982
|
}
|
|
960
983
|
|
|
984
|
+
protected createUploadCsvButton(
|
|
985
|
+
_columns: string[],
|
|
986
|
+
_rows: Array<{ index: number; cells: string[] }>,
|
|
987
|
+
_isTree: boolean,
|
|
988
|
+
_blockSource: string | undefined
|
|
989
|
+
): HTMLElement | undefined {
|
|
990
|
+
return undefined;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
protected transformCsvDownloadData(columns: string[], rows: string[][]): { columns: string[]; rows: string[][] } {
|
|
994
|
+
return { columns, rows };
|
|
995
|
+
}
|
|
996
|
+
|
|
961
997
|
private requestCsvDownload(columns: string[], rows: string[][]): void {
|
|
962
998
|
if (columns.length === 0) {
|
|
963
999
|
return;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { QueryMarkdownBlockRenderer } from './renderer.js';
|
|
4
4
|
import type { MdBlockExecutionResult } from './types.js';
|
|
5
|
-
import
|
|
5
|
+
import { appendInlineValue } from './wikilink-utils.js';
|
|
6
6
|
|
|
7
7
|
type TextStyleSelectorKind = 'paragraph';
|
|
8
8
|
type TextStyleTarget = 'value';
|
|
@@ -23,11 +23,6 @@ type TextSelectorContext = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
export class TextMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
26
|
-
private readonly markdown = new MarkdownIt({
|
|
27
|
-
html: false,
|
|
28
|
-
linkify: true,
|
|
29
|
-
});
|
|
30
|
-
|
|
31
26
|
canRender(result: MdBlockExecutionResult): boolean {
|
|
32
27
|
return result.status === 'ok'
|
|
33
28
|
&& result.kind === 'text'
|
|
@@ -51,7 +46,7 @@ export class TextMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
51
46
|
const paragraph = document.createElement('p');
|
|
52
47
|
const valueSpan = document.createElement('span');
|
|
53
48
|
valueSpan.className = 'oml-md-result-text-value';
|
|
54
|
-
valueSpan
|
|
49
|
+
appendInlineValue(valueSpan, row[0] ?? '');
|
|
55
50
|
paragraph.appendChild(valueSpan);
|
|
56
51
|
|
|
57
52
|
const context = createParagraphSelectorContext(index, row[0] ?? '', payload.columns, row);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
2
|
|
|
3
|
+
import { displayLabelFromIri } from './renderer.js';
|
|
4
|
+
|
|
3
5
|
export function appendInlineValue(container: HTMLElement, value: string): void {
|
|
4
6
|
const wikilinkPattern = /\[\[([^\]]+)\]\]/g;
|
|
5
7
|
let cursor = 0;
|
|
@@ -44,7 +46,7 @@ export function appendTokenizedValueParts(container: HTMLElement, raw: string, p
|
|
|
44
46
|
if (isIriValue(token)) {
|
|
45
47
|
fragment.appendChild(createWikiLinkElement(token, shortLabelFromIri(token)));
|
|
46
48
|
} else {
|
|
47
|
-
fragment
|
|
49
|
+
appendInlineValue(fragment, token);
|
|
48
50
|
}
|
|
49
51
|
container.appendChild(fragment);
|
|
50
52
|
}
|
|
@@ -58,15 +60,7 @@ export function splitTokenizedValueParts(raw: string): string[] {
|
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
export function shortLabelFromIri(iri: string): string {
|
|
61
|
-
|
|
62
|
-
if (hash >= 0 && hash < iri.length - 1) {
|
|
63
|
-
return iri.slice(hash + 1);
|
|
64
|
-
}
|
|
65
|
-
const slash = iri.lastIndexOf('/');
|
|
66
|
-
if (slash >= 0 && slash < iri.length - 1) {
|
|
67
|
-
return iri.slice(slash + 1);
|
|
68
|
-
}
|
|
69
|
-
return iri;
|
|
63
|
+
return displayLabelFromIri(iri);
|
|
70
64
|
}
|
|
71
65
|
|
|
72
66
|
export function isIriValue(value: string): boolean {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
2
|
|
|
3
3
|
import { createMarkdownRendererRegistry } from '../renderers/registry.js';
|
|
4
|
+
import { setIriLabelSnapshot } from '../renderers/renderer.js';
|
|
4
5
|
|
|
5
6
|
const SUPPORTED = new Set(['table', 'tree', 'graph', 'chart', 'diagram', 'list', 'text', 'matrix', 'table-editor']);
|
|
6
7
|
|
|
@@ -203,6 +204,8 @@ async function applyExecutionResults(): Promise<void> {
|
|
|
203
204
|
const wikilinkIndex = parseJsonNode<Record<string, string>>('oml-md-wikilink-index', {});
|
|
204
205
|
const iriAliasIndex = parseJsonNode<Record<string, string>>('oml-md-wikilink-iri-aliases', {});
|
|
205
206
|
const wikilinkConfig = parseJsonNode<WikilinkConfig>('oml-md-wikilink-config', { linkingEnabled: false });
|
|
207
|
+
const memberLabelSnapshot = parseJsonNode<Record<string, string>>('oml-md-member-labels', {});
|
|
208
|
+
setIriLabelSnapshot(memberLabelSnapshot);
|
|
206
209
|
const linkingEnabled = Boolean(wikilinkConfig?.linkingEnabled);
|
|
207
210
|
// Resolve wikilinks in regular markdown content (outside code-block panels).
|
|
208
211
|
applyWikilinks(document, wikilinkIndex, iriAliasIndex, linkingEnabled);
|