@oml/markdown 0.12.0 → 0.14.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/index.d.ts +1 -0
- package/out/index.js +1 -0
- package/out/index.js.map +1 -1
- package/out/md/md-execution.d.ts +3 -3
- package/out/md/md-execution.js +1 -1
- package/out/md/md-execution.js.map +1 -1
- package/out/md/md-executor.js +6 -8
- package/out/md/md-executor.js.map +1 -1
- package/out/md/md-frontmatter.d.ts +1 -1
- package/out/md/md-frontmatter.js +15 -10
- package/out/md/md-frontmatter.js.map +1 -1
- package/out/md/md-runtime.js +1 -1
- package/out/md/md-runtime.js.map +1 -1
- package/out/md/md-types.d.ts +2 -2
- package/out/renderers/diagram-renderer.js +231 -12
- package/out/renderers/diagram-renderer.js.map +1 -1
- package/out/renderers/graph-renderer.js +2 -2
- package/out/renderers/graph-renderer.js.map +1 -1
- package/out/renderers/table-renderer.js +25 -10
- package/out/renderers/table-renderer.js.map +1 -1
- package/out/static/browser-runtime.bundle.js +489 -25
- package/out/static/browser-runtime.bundle.js.map +3 -3
- package/out/static/browser-runtime.js +258 -0
- package/out/static/browser-runtime.js.map +1 -1
- package/out/static/runtime-assets.d.ts +1 -1
- package/out/static/runtime-assets.js +1 -0
- package/out/static/runtime-assets.js.map +1 -1
- package/out/template/binder.d.ts +2 -0
- package/out/template/binder.js +56 -0
- package/out/template/binder.js.map +1 -0
- package/out/template/catalog.d.ts +8 -0
- package/out/template/catalog.js +26 -0
- package/out/template/catalog.js.map +1 -0
- package/out/template/compose.d.ts +7 -0
- package/out/template/compose.js +93 -0
- package/out/template/compose.js.map +1 -0
- package/out/template/definition.d.ts +3 -0
- package/out/template/definition.js +204 -0
- package/out/template/definition.js.map +1 -0
- package/out/template/engine.d.ts +8 -0
- package/out/template/engine.js +30 -0
- package/out/template/engine.js.map +1 -0
- package/out/template/index.d.ts +7 -0
- package/out/template/index.js +9 -0
- package/out/template/index.js.map +1 -0
- package/out/template/resolver.d.ts +4 -0
- package/out/template/resolver.js +58 -0
- package/out/template/resolver.js.map +1 -0
- package/out/template/types.d.ts +82 -0
- package/out/template/types.js +3 -0
- package/out/template/types.js.map +1 -0
- package/package.json +2 -2
- package/src/index.ts +1 -0
- package/src/md/md-execution.ts +3 -3
- package/src/md/md-executor.ts +6 -9
- package/src/md/md-frontmatter.ts +15 -10
- package/src/md/md-runtime.ts +1 -1
- package/src/md/md-types.ts +2 -2
- package/src/renderers/diagram-renderer.ts +229 -12
- package/src/renderers/graph-renderer.ts +2 -2
- package/src/renderers/table-renderer.ts +26 -10
- package/src/static/browser-runtime.ts +305 -0
- package/src/static/markdown-webview.css +13 -0
- package/src/static/runtime-assets.ts +1 -0
- package/src/template/binder.ts +70 -0
- package/src/template/catalog.ts +35 -0
- package/src/template/compose.ts +107 -0
- package/src/template/definition.ts +222 -0
- package/src/template/engine.ts +45 -0
- package/src/template/index.ts +9 -0
- package/src/template/resolver.ts +75 -0
- package/src/template/types.ts +111 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
|
+
import { extractLeadingFrontMatter } from '../md/md-frontmatter.js';
|
|
3
|
+
export function parseTemplateDefinition(content, sourceUri) {
|
|
4
|
+
const frontMatter = extractLeadingFrontMatter(content);
|
|
5
|
+
const data = frontMatter?.data;
|
|
6
|
+
if (!data) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
const rawTemplate = data.template;
|
|
10
|
+
if (!isRecord(rawTemplate)) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
const id = normalizeTemplateType(typeof rawTemplate.id === 'string' ? rawTemplate.id : '');
|
|
14
|
+
if (!id) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const name = typeof rawTemplate.name === 'string' && rawTemplate.name.trim().length > 0
|
|
18
|
+
? rawTemplate.name.trim()
|
|
19
|
+
: undefined;
|
|
20
|
+
const rank = parseRank(rawTemplate.rank);
|
|
21
|
+
const exposures = parseTemplateExposures(rawTemplate.expose);
|
|
22
|
+
const parameters = parseTemplateParameters(rawTemplate.params);
|
|
23
|
+
return {
|
|
24
|
+
id,
|
|
25
|
+
name,
|
|
26
|
+
rank,
|
|
27
|
+
exposures,
|
|
28
|
+
parameters,
|
|
29
|
+
body: content,
|
|
30
|
+
sourceUri,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function deriveContextLabelFromIri(iri) {
|
|
34
|
+
const normalized = iri.trim().replace(/^<|>$/g, '');
|
|
35
|
+
if (!normalized) {
|
|
36
|
+
return 'IRI';
|
|
37
|
+
}
|
|
38
|
+
const hashIndex = normalized.lastIndexOf('#');
|
|
39
|
+
if (hashIndex >= 0 && hashIndex < normalized.length - 1) {
|
|
40
|
+
return decodeIriSegment(normalized.slice(hashIndex + 1));
|
|
41
|
+
}
|
|
42
|
+
const withoutTrailingSlash = normalized.replace(/\/+$/, '');
|
|
43
|
+
const slashIndex = withoutTrailingSlash.lastIndexOf('/');
|
|
44
|
+
if (slashIndex >= 0 && slashIndex < withoutTrailingSlash.length - 1) {
|
|
45
|
+
return decodeIriSegment(withoutTrailingSlash.slice(slashIndex + 1));
|
|
46
|
+
}
|
|
47
|
+
return decodeIriSegment(withoutTrailingSlash);
|
|
48
|
+
}
|
|
49
|
+
function normalizeTemplateType(value) {
|
|
50
|
+
let normalized = value.trim();
|
|
51
|
+
const wikilinkMatch = /^\[\[([^\]]+)\]\]$/.exec(normalized);
|
|
52
|
+
if (wikilinkMatch) {
|
|
53
|
+
normalized = (wikilinkMatch[1] ?? '').trim();
|
|
54
|
+
}
|
|
55
|
+
return normalized.replace(/^<|>$/g, '');
|
|
56
|
+
}
|
|
57
|
+
function parseTemplateExposures(raw) {
|
|
58
|
+
const entries = Array.isArray(raw) ? raw : raw ? [raw] : [];
|
|
59
|
+
const exposures = [];
|
|
60
|
+
for (const entry of entries) {
|
|
61
|
+
if (!isRecord(entry) || typeof entry.kind !== 'string') {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const kind = entry.kind.trim();
|
|
65
|
+
if (kind === 'navigation') {
|
|
66
|
+
const match = isRecord(entry.match) ? entry.match : undefined;
|
|
67
|
+
const anyTypeOf = asNormalizedStringArray(match?.anyTypeOf);
|
|
68
|
+
const allTypesOf = asNormalizedStringArray(match?.allTypesOf);
|
|
69
|
+
exposures.push({
|
|
70
|
+
kind: 'navigation',
|
|
71
|
+
match: (anyTypeOf.length > 0 || allTypesOf.length > 0)
|
|
72
|
+
? { anyTypeOf, allTypesOf }
|
|
73
|
+
: undefined
|
|
74
|
+
});
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (kind === 'compose') {
|
|
78
|
+
const placementRaw = typeof entry.placement === 'string' ? entry.placement.trim() : '';
|
|
79
|
+
const placement = placementRaw === 'prepend' || placementRaw === 'append' ? placementRaw : undefined;
|
|
80
|
+
exposures.push({ kind: 'compose', placement });
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (kind === 'call') {
|
|
84
|
+
const selection = isRecord(entry.selection) ? entry.selection : undefined;
|
|
85
|
+
const min = toNonNegativeInteger(selection?.min);
|
|
86
|
+
const max = toNonNegativeInteger(selection?.max);
|
|
87
|
+
exposures.push({
|
|
88
|
+
kind: 'call',
|
|
89
|
+
selection: min !== undefined || max !== undefined ? { min, max } : undefined
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return exposures;
|
|
94
|
+
}
|
|
95
|
+
function parseTemplateParameters(raw) {
|
|
96
|
+
if (!Array.isArray(raw)) {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
const params = [];
|
|
100
|
+
for (const entry of raw) {
|
|
101
|
+
if (!isRecord(entry)) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const id = typeof entry.id === 'string' ? entry.id.trim() : '';
|
|
105
|
+
const type = typeof entry.type === 'string' ? entry.type.trim() : '';
|
|
106
|
+
if (!id || !isSupportedParameterType(type)) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const required = typeof entry.required === 'boolean' ? entry.required : undefined;
|
|
110
|
+
const fromValue = typeof entry.from === 'string' ? entry.from.trim() : '';
|
|
111
|
+
const from = isSupportedBindingSource(fromValue) ? fromValue : undefined;
|
|
112
|
+
const description = typeof entry.description === 'string' && entry.description.trim().length > 0
|
|
113
|
+
? entry.description.trim()
|
|
114
|
+
: undefined;
|
|
115
|
+
params.push({
|
|
116
|
+
id,
|
|
117
|
+
type,
|
|
118
|
+
required,
|
|
119
|
+
from,
|
|
120
|
+
defaultValue: toTemplateValue(entry.defaultValue),
|
|
121
|
+
description,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return params;
|
|
125
|
+
}
|
|
126
|
+
function isSupportedParameterType(value) {
|
|
127
|
+
return value === 'iri'
|
|
128
|
+
|| value === 'string'
|
|
129
|
+
|| value === 'number'
|
|
130
|
+
|| value === 'boolean'
|
|
131
|
+
|| value === 'iri[]'
|
|
132
|
+
|| value === 'json';
|
|
133
|
+
}
|
|
134
|
+
function isSupportedBindingSource(value) {
|
|
135
|
+
return value === 'context.member'
|
|
136
|
+
|| value === 'context.ontology'
|
|
137
|
+
|| value === 'context.modelUri'
|
|
138
|
+
|| value === 'context.selection[*]'
|
|
139
|
+
|| /^context\.selection\[\d+]$/.test(value)
|
|
140
|
+
|| value === 'user';
|
|
141
|
+
}
|
|
142
|
+
function toTemplateValue(value) {
|
|
143
|
+
if (value === null) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
147
|
+
return value;
|
|
148
|
+
}
|
|
149
|
+
if (Array.isArray(value)) {
|
|
150
|
+
return value.every((entry) => typeof entry === 'string') ? value : undefined;
|
|
151
|
+
}
|
|
152
|
+
if (isRecord(value)) {
|
|
153
|
+
return value;
|
|
154
|
+
}
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
function parseRank(value) {
|
|
158
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
159
|
+
return value;
|
|
160
|
+
}
|
|
161
|
+
if (typeof value === 'string') {
|
|
162
|
+
const parsed = Number(value.trim());
|
|
163
|
+
if (Number.isFinite(parsed)) {
|
|
164
|
+
return parsed;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return 0;
|
|
168
|
+
}
|
|
169
|
+
function asNormalizedStringArray(value) {
|
|
170
|
+
if (!Array.isArray(value)) {
|
|
171
|
+
return [];
|
|
172
|
+
}
|
|
173
|
+
return value
|
|
174
|
+
.filter((entry) => typeof entry === 'string')
|
|
175
|
+
.map((entry) => normalizeTemplateType(entry))
|
|
176
|
+
.filter((entry) => entry.length > 0);
|
|
177
|
+
}
|
|
178
|
+
function toNonNegativeInteger(value) {
|
|
179
|
+
if (typeof value === 'number' && Number.isInteger(value) && value >= 0) {
|
|
180
|
+
return value;
|
|
181
|
+
}
|
|
182
|
+
if (typeof value === 'string') {
|
|
183
|
+
const parsed = Number.parseInt(value.trim(), 10);
|
|
184
|
+
if (Number.isInteger(parsed) && parsed >= 0) {
|
|
185
|
+
return parsed;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
190
|
+
function isRecord(value) {
|
|
191
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
192
|
+
}
|
|
193
|
+
function decodeIriSegment(value) {
|
|
194
|
+
if (!value) {
|
|
195
|
+
return 'IRI';
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
return decodeURIComponent(value);
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
return value;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=definition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definition.js","sourceRoot":"","sources":["../../src/template/definition.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TemplateDefinition, TemplateInvocation, TemplateValue } from './types.js';
|
|
2
|
+
export interface TemplateRenderResult {
|
|
3
|
+
output: string;
|
|
4
|
+
values: Record<string, TemplateValue>;
|
|
5
|
+
missingRequired: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function renderTemplate(template: TemplateDefinition, invocation: TemplateInvocation): TemplateRenderResult;
|
|
8
|
+
export declare function interpolateTemplateBody(source: string, values: Readonly<Record<string, TemplateValue>>): string;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
|
+
import { bindTemplateParameters } from './binder.js';
|
|
3
|
+
export function renderTemplate(template, invocation) {
|
|
4
|
+
const bound = bindTemplateParameters(template, invocation.context, invocation.args);
|
|
5
|
+
const output = interpolateTemplateBody(template.body, bound.values);
|
|
6
|
+
return {
|
|
7
|
+
output,
|
|
8
|
+
values: bound.values,
|
|
9
|
+
missingRequired: bound.missingRequired
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function interpolateTemplateBody(source, values) {
|
|
13
|
+
return source.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (_match, key) => {
|
|
14
|
+
if (!(key in values)) {
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
const value = values[key];
|
|
18
|
+
if (Array.isArray(value)) {
|
|
19
|
+
return value.map((entry) => String(entry)).join(', ');
|
|
20
|
+
}
|
|
21
|
+
if (value === null || value === undefined) {
|
|
22
|
+
return '';
|
|
23
|
+
}
|
|
24
|
+
if (typeof value === 'object') {
|
|
25
|
+
return JSON.stringify(value);
|
|
26
|
+
}
|
|
27
|
+
return String(value);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/template/engine.ts"],"names":[],"mappings":"AAAA,qDAAqD;AAErD,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AASrD,MAAM,UAAU,cAAc,CAC1B,QAA4B,EAC5B,UAA8B;IAE9B,MAAM,KAAK,GAAG,sBAAsB,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACpF,MAAM,MAAM,GAAG,uBAAuB,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpE,OAAO;QACH,MAAM;QACN,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,eAAe,EAAE,KAAK,CAAC,eAAe;KACzC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,uBAAuB,CACnC,MAAc,EACd,MAA+C;IAE/C,OAAO,MAAM,CAAC,OAAO,CAAC,iCAAiC,EAAE,CAAC,MAAc,EAAE,GAAW,EAAU,EAAE;QAC7F,IAAI,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC,EAAE,CAAC;YACnB,OAAO,EAAE,CAAC;QACd,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxC,OAAO,EAAE,CAAC;QACd,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
|
+
export * from './types.js';
|
|
3
|
+
export * from './catalog.js';
|
|
4
|
+
export * from './resolver.js';
|
|
5
|
+
export * from './binder.js';
|
|
6
|
+
export * from './engine.js';
|
|
7
|
+
export * from './compose.js';
|
|
8
|
+
export * from './definition.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/template/index.ts"],"names":[],"mappings":"AAAA,qDAAqD;AAErD,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type TemplateCatalog } from './catalog.js';
|
|
2
|
+
import type { TemplateDefinition, TemplateResolutionResult } from './types.js';
|
|
3
|
+
export declare function resolveTemplateById(catalog: TemplateCatalog, templateId: string): TemplateDefinition | undefined;
|
|
4
|
+
export declare function resolveTemplateForNavigation(catalog: TemplateCatalog, rdfTypes: ReadonlyArray<string>): TemplateResolutionResult;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
|
+
import { getTemplateById } from './catalog.js';
|
|
3
|
+
export function resolveTemplateById(catalog, templateId) {
|
|
4
|
+
return getTemplateById(catalog, templateId);
|
|
5
|
+
}
|
|
6
|
+
export function resolveTemplateForNavigation(catalog, rdfTypes) {
|
|
7
|
+
const candidates = collectNavigationCandidates(catalog, rdfTypes);
|
|
8
|
+
const template = selectBestTemplate(candidates);
|
|
9
|
+
return { template, candidates };
|
|
10
|
+
}
|
|
11
|
+
function collectNavigationCandidates(catalog, rdfTypes) {
|
|
12
|
+
const normalizedTypes = [...new Set(rdfTypes.map(normalizeIri).filter((value) => value.length > 0))];
|
|
13
|
+
const normalizedTypeSet = new Set(normalizedTypes);
|
|
14
|
+
const results = [];
|
|
15
|
+
for (const template of catalog.all) {
|
|
16
|
+
const exposures = template.exposures?.filter((exposure) => exposure.kind === 'navigation') ?? [];
|
|
17
|
+
if (exposures.length === 0) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
let bestScoreForTemplate;
|
|
21
|
+
for (const exposure of exposures) {
|
|
22
|
+
const score = scoreNavigationExposure(exposure, normalizedTypeSet);
|
|
23
|
+
if (score === undefined) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (bestScoreForTemplate === undefined || score > bestScoreForTemplate) {
|
|
27
|
+
bestScoreForTemplate = score;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (bestScoreForTemplate === undefined) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const rank = Number.isFinite(template.rank) ? Number(template.rank) : 0;
|
|
34
|
+
results.push({ template, score: bestScoreForTemplate + rank });
|
|
35
|
+
}
|
|
36
|
+
return results.sort((left, right) => right.score - left.score || left.template.id.localeCompare(right.template.id));
|
|
37
|
+
}
|
|
38
|
+
function scoreNavigationExposure(exposure, rdfTypeSet) {
|
|
39
|
+
const anyTypeOf = (exposure.match?.anyTypeOf ?? []).map(normalizeIri).filter((value) => value.length > 0);
|
|
40
|
+
const allTypesOf = (exposure.match?.allTypesOf ?? []).map(normalizeIri).filter((value) => value.length > 0);
|
|
41
|
+
if (allTypesOf.length > 0 && allTypesOf.some((iri) => !rdfTypeSet.has(iri))) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
if (anyTypeOf.length > 0 && !anyTypeOf.some((iri) => rdfTypeSet.has(iri))) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
if (allTypesOf.length === 0 && anyTypeOf.length === 0) {
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
return (allTypesOf.length * 10) + anyTypeOf.length;
|
|
51
|
+
}
|
|
52
|
+
function selectBestTemplate(candidates) {
|
|
53
|
+
return candidates.length > 0 ? candidates[0].template : undefined;
|
|
54
|
+
}
|
|
55
|
+
function normalizeIri(value) {
|
|
56
|
+
return value.trim().replace(/^<|>$/g, '');
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../src/template/resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export type TemplateValue = string | number | boolean | null | string[] | Record<string, unknown>;
|
|
2
|
+
export type TemplateParameterType = 'iri' | 'string' | 'number' | 'boolean' | 'iri[]' | 'json';
|
|
3
|
+
export type TemplateBindingSource = 'context.member' | 'context.ontology' | 'context.modelUri' | `context.selection[${number}]` | 'context.selection[*]' | 'user';
|
|
4
|
+
export interface TemplateParameterDefinition {
|
|
5
|
+
id: string;
|
|
6
|
+
type: TemplateParameterType;
|
|
7
|
+
required?: boolean;
|
|
8
|
+
from?: TemplateBindingSource;
|
|
9
|
+
defaultValue?: TemplateValue;
|
|
10
|
+
description?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface TemplateNavigationMatch {
|
|
13
|
+
anyTypeOf?: string[];
|
|
14
|
+
allTypesOf?: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface TemplateNavigationExposure {
|
|
17
|
+
kind: 'navigation';
|
|
18
|
+
match?: TemplateNavigationMatch;
|
|
19
|
+
}
|
|
20
|
+
export interface TemplateComposeExposure {
|
|
21
|
+
kind: 'compose';
|
|
22
|
+
placement?: 'prepend' | 'append';
|
|
23
|
+
}
|
|
24
|
+
export interface TemplateCallExposure {
|
|
25
|
+
kind: 'call';
|
|
26
|
+
selection?: {
|
|
27
|
+
min?: number;
|
|
28
|
+
max?: number;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export type TemplateExposure = TemplateNavigationExposure | TemplateComposeExposure | TemplateCallExposure;
|
|
32
|
+
export interface TemplateDefinition {
|
|
33
|
+
id: string;
|
|
34
|
+
name?: string;
|
|
35
|
+
rank?: number;
|
|
36
|
+
exposures?: TemplateExposure[];
|
|
37
|
+
parameters?: TemplateParameterDefinition[];
|
|
38
|
+
body: string;
|
|
39
|
+
sourceUri?: string;
|
|
40
|
+
}
|
|
41
|
+
export type TemplateInvocationMode = 'navigation' | 'compose' | 'call' | 'preview' | 'inline' | 'newDocument';
|
|
42
|
+
export interface TemplateInvocationContext {
|
|
43
|
+
invocation: {
|
|
44
|
+
mode: TemplateInvocationMode;
|
|
45
|
+
sourceDocumentUri?: string;
|
|
46
|
+
referenceDocumentUri?: string;
|
|
47
|
+
};
|
|
48
|
+
model?: {
|
|
49
|
+
ontologyIri?: string;
|
|
50
|
+
modelUri?: string;
|
|
51
|
+
};
|
|
52
|
+
focus?: {
|
|
53
|
+
memberIri?: string;
|
|
54
|
+
rdfTypes?: string[];
|
|
55
|
+
};
|
|
56
|
+
selection?: {
|
|
57
|
+
iris?: string[];
|
|
58
|
+
rows?: Array<{
|
|
59
|
+
iri: string;
|
|
60
|
+
cells: Record<string, string>;
|
|
61
|
+
}>;
|
|
62
|
+
};
|
|
63
|
+
vars?: Record<string, TemplateValue>;
|
|
64
|
+
}
|
|
65
|
+
export interface TemplateInvocation {
|
|
66
|
+
templateId: string;
|
|
67
|
+
mode: TemplateInvocationMode;
|
|
68
|
+
context: TemplateInvocationContext;
|
|
69
|
+
args?: Record<string, TemplateValue>;
|
|
70
|
+
}
|
|
71
|
+
export interface TemplateResolutionCandidate {
|
|
72
|
+
template: TemplateDefinition;
|
|
73
|
+
score: number;
|
|
74
|
+
}
|
|
75
|
+
export interface TemplateResolutionResult {
|
|
76
|
+
template?: TemplateDefinition;
|
|
77
|
+
candidates: TemplateResolutionCandidate[];
|
|
78
|
+
}
|
|
79
|
+
export interface TemplateBindResult {
|
|
80
|
+
values: Record<string, TemplateValue>;
|
|
81
|
+
missingRequired: string[];
|
|
82
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/template/types.ts"],"names":[],"mappings":"AAAA,qDAAqD"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oml/markdown",
|
|
3
3
|
"description": "Markdown runtime and execution contracts for OML",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.14.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=20.10.0",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@antv/x6": "^3.1.6",
|
|
58
58
|
"@dagrejs/dagre": "^2.0.4",
|
|
59
|
-
"@oml/owl": "0.
|
|
59
|
+
"@oml/owl": "0.14.0",
|
|
60
60
|
"chart.js": "^4.4.0",
|
|
61
61
|
"markdown-it": "^14.1.1",
|
|
62
62
|
"reflect-metadata": "^0.2.2",
|
package/src/index.ts
CHANGED
package/src/md/md-execution.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
2
|
|
|
3
|
-
export const MarkdownExecutionRequest = 'oml/markdown
|
|
3
|
+
export const MarkdownExecutionRequest = 'oml/markdown';
|
|
4
4
|
|
|
5
5
|
export type MdBlockKind =
|
|
6
6
|
| 'table'
|
|
@@ -24,8 +24,8 @@ export interface MdExecutableBlock {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export interface MdExecuteBlocksParams {
|
|
27
|
-
|
|
28
|
-
modelUri
|
|
27
|
+
markdownUri: string;
|
|
28
|
+
modelUri: string;
|
|
29
29
|
blocks: MdExecutableBlock[];
|
|
30
30
|
}
|
|
31
31
|
|
package/src/md/md-executor.ts
CHANGED
|
@@ -24,14 +24,11 @@ export class MarkdownExecutor {
|
|
|
24
24
|
constructor(private readonly backend: MarkdownExecutionBackend) {}
|
|
25
25
|
|
|
26
26
|
async executeBlocks(params: MdExecuteBlocksParams): Promise<MdExecuteBlocksResult> {
|
|
27
|
-
const resolvedModelUri = params.modelUri
|
|
28
|
-
const contextQuadCount =
|
|
27
|
+
const resolvedModelUri = params.modelUri.trim();
|
|
28
|
+
const contextQuadCount = this.backend.countContextQuads
|
|
29
29
|
? await this.backend.countContextQuads(resolvedModelUri)
|
|
30
30
|
: undefined;
|
|
31
|
-
|
|
32
|
-
if (resolvedModelUri) {
|
|
33
|
-
await this.backend.ensureContext(resolvedModelUri);
|
|
34
|
-
}
|
|
31
|
+
await this.backend.ensureContext(resolvedModelUri);
|
|
35
32
|
|
|
36
33
|
const results: MdBlockExecutionResult[] = [];
|
|
37
34
|
for (const block of params.blocks) {
|
|
@@ -405,14 +402,14 @@ export class MarkdownExecutor {
|
|
|
405
402
|
}
|
|
406
403
|
|
|
407
404
|
function preprocessQuerySource(backend: MarkdownExecutionBackend, modelUri: string, source: string): string {
|
|
408
|
-
if (!source.includes('${
|
|
405
|
+
if (!source.includes('${ontologyIri}')) {
|
|
409
406
|
return source;
|
|
410
407
|
}
|
|
411
|
-
return source.split('${
|
|
408
|
+
return source.split('${ontologyIri}').join(backend.resolveContextIri(modelUri));
|
|
412
409
|
}
|
|
413
410
|
|
|
414
411
|
function missingContext(blockId: string, kind: MdBlockExecutionResult['kind']): MdBlockExecutionResult {
|
|
415
|
-
return queryFailed(blockId, kind, 'No
|
|
412
|
+
return queryFailed(blockId, kind, 'No ontologyIri model is available for this markdown document.');
|
|
416
413
|
}
|
|
417
414
|
|
|
418
415
|
function queryFailed(blockId: string, kind: MdBlockExecutionResult['kind'], message: string): MdBlockExecutionResult {
|
package/src/md/md-frontmatter.ts
CHANGED
|
@@ -14,40 +14,45 @@ export function stripLeadingFrontMatter(markdown: string): string {
|
|
|
14
14
|
|
|
15
15
|
export function extractLeadingFrontMatter(markdown: string): MarkdownFrontMatter | undefined {
|
|
16
16
|
const normalized = markdown.replace(/^\uFEFF/, '');
|
|
17
|
-
const yamlMatch = /^(
|
|
17
|
+
const yamlMatch = /^(---[ \t]*\r?\n[\s\S]*?\r?\n---[ \t]*(?:\r?\n|$))/.exec(normalized);
|
|
18
18
|
if (yamlMatch) {
|
|
19
19
|
const yamlBody = yamlMatch[1]
|
|
20
|
-
.replace(
|
|
21
|
-
.replace(/\r?\n---(?:\
|
|
20
|
+
.replace(/^---[ \t]*\r?\n/, '')
|
|
21
|
+
.replace(/\r?\n---[ \t]*(?:\r?\n|$)$/, '');
|
|
22
22
|
const yamlData = parseYamlMap(yamlBody);
|
|
23
23
|
return {
|
|
24
24
|
raw: yamlMatch[1],
|
|
25
|
-
|
|
25
|
+
contextOntologyIri: extractContextIriFromData(yamlData) ?? extractContextIri(yamlMatch[1]),
|
|
26
26
|
data: yamlData,
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
|
-
const tomlMatch = /^(
|
|
29
|
+
const tomlMatch = /^(\+\+\+[ \t]*\r?\n[\s\S]*?\r?\n\+\+\+[ \t]*(?:\r?\n|$))/.exec(normalized);
|
|
30
30
|
if (tomlMatch) {
|
|
31
31
|
return {
|
|
32
32
|
raw: tomlMatch[1],
|
|
33
|
-
|
|
33
|
+
contextOntologyIri: extractContextIri(tomlMatch[1])
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
return undefined;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
export function
|
|
40
|
-
const match = /^
|
|
39
|
+
export function extractContextIri(frontMatterRaw: string): string | undefined {
|
|
40
|
+
const match = /^ontologyIri\s*:\s*(.+)$/m.exec(frontMatterRaw)
|
|
41
|
+
?? /^ontology\s*:\s*(.+)$/m.exec(frontMatterRaw);
|
|
41
42
|
if (!match) {
|
|
42
43
|
return undefined;
|
|
43
44
|
}
|
|
44
45
|
return match[1].trim().replace(/^['"]|['"]$/g, '');
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
function
|
|
48
|
+
function extractContextIriFromData(data: Record<string, unknown> | undefined): string | undefined {
|
|
48
49
|
if (!data) {
|
|
49
50
|
return undefined;
|
|
50
51
|
}
|
|
51
|
-
const value = data.
|
|
52
|
+
const value = typeof data.ontologyIri === 'string'
|
|
53
|
+
? data.ontologyIri
|
|
54
|
+
: typeof data.ontology === 'string'
|
|
55
|
+
? data.ontology
|
|
56
|
+
: undefined;
|
|
52
57
|
return typeof value === 'string' ? value : undefined;
|
|
53
58
|
}
|
package/src/md/md-runtime.ts
CHANGED
package/src/md/md-types.ts
CHANGED
|
@@ -12,7 +12,7 @@ export interface ParsedCodeBlock {
|
|
|
12
12
|
|
|
13
13
|
export interface MarkdownFrontMatter {
|
|
14
14
|
raw: string;
|
|
15
|
-
|
|
15
|
+
contextOntologyIri?: string;
|
|
16
16
|
data?: Record<string, unknown>;
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -25,7 +25,7 @@ export interface PreparedMarkdownDocument {
|
|
|
25
25
|
markdown: string;
|
|
26
26
|
renderedHtml: string;
|
|
27
27
|
frontMatter?: MarkdownFrontMatter;
|
|
28
|
-
|
|
28
|
+
contextOntologyIri?: string;
|
|
29
29
|
codeBlocks: ParsedCodeBlock[];
|
|
30
30
|
executableBlocks: PreparedCodeBlock[];
|
|
31
31
|
}
|