@oml/markdown 0.10.0 → 0.12.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 (40) hide show
  1. package/out/md/md-execution.d.ts +16 -0
  2. package/out/md/md-executor.d.ts +1 -0
  3. package/out/md/md-executor.js +219 -35
  4. package/out/md/md-executor.js.map +1 -1
  5. package/out/renderers/chart-renderer.js +72 -4
  6. package/out/renderers/chart-renderer.js.map +1 -1
  7. package/out/renderers/diagram-renderer.js +896 -245
  8. package/out/renderers/diagram-renderer.js.map +1 -1
  9. package/out/renderers/graph-renderer.js +452 -18
  10. package/out/renderers/graph-renderer.js.map +1 -1
  11. package/out/renderers/matrix-renderer.d.ts +0 -2
  12. package/out/renderers/matrix-renderer.js +45 -40
  13. package/out/renderers/matrix-renderer.js.map +1 -1
  14. package/out/renderers/renderer.d.ts +4 -1
  15. package/out/renderers/renderer.js +98 -0
  16. package/out/renderers/renderer.js.map +1 -1
  17. package/out/renderers/table-renderer.d.ts +12 -2
  18. package/out/renderers/table-renderer.js +126 -39
  19. package/out/renderers/table-renderer.js.map +1 -1
  20. package/out/renderers/types.d.ts +16 -0
  21. package/out/renderers/wikilink-utils.d.ts +1 -0
  22. package/out/renderers/wikilink-utils.js +60 -32
  23. package/out/renderers/wikilink-utils.js.map +1 -1
  24. package/out/static/browser-runtime.bundle.js +8011 -1292
  25. package/out/static/browser-runtime.bundle.js.map +4 -4
  26. package/out/static/browser-runtime.js +15 -2
  27. package/out/static/browser-runtime.js.map +1 -1
  28. package/package.json +2 -2
  29. package/src/md/md-execution.ts +20 -0
  30. package/src/md/md-executor.ts +268 -40
  31. package/src/renderers/chart-renderer.ts +93 -2
  32. package/src/renderers/diagram-renderer.ts +964 -253
  33. package/src/renderers/graph-renderer.ts +512 -12
  34. package/src/renderers/matrix-renderer.ts +57 -44
  35. package/src/renderers/renderer.ts +105 -1
  36. package/src/renderers/table-renderer.ts +190 -41
  37. package/src/renderers/types.ts +20 -0
  38. package/src/renderers/wikilink-utils.ts +66 -31
  39. package/src/static/browser-runtime.ts +20 -2
  40. package/src/static/markdown-webview.css +44 -15
@@ -76,7 +76,15 @@ export class ChartMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
76
76
  const canvasEl = document.createElement('canvas');
77
77
  chartRoot.appendChild(canvasEl);
78
78
 
79
- initializeChartWhenReady(chartRoot, canvasEl, payload.columns, payload.rows, parsed, container);
79
+ initializeChartWhenReady(
80
+ chartRoot,
81
+ canvasEl,
82
+ payload.columns,
83
+ payload.rows,
84
+ parsed,
85
+ container,
86
+ (content) => this.requestTextFileDownload(content, 'chart', 'csv')
87
+ );
80
88
 
81
89
  return container;
82
90
  }
@@ -91,6 +99,7 @@ function initializeChartWhenReady(
91
99
  rows: string[][],
92
100
  parsed: ParsedChartOptions,
93
101
  messageContainer: HTMLElement,
102
+ downloadCsv: (content: string) => void,
94
103
  ): void {
95
104
  const maxAttempts = 20;
96
105
  let attempts = 0;
@@ -100,7 +109,7 @@ function initializeChartWhenReady(
100
109
  if (attempts < maxAttempts) requestAnimationFrame(tryInit);
101
110
  return;
102
111
  }
103
- void doChartInit(chartRoot, canvasEl, columns, rows, parsed).catch((err) => {
112
+ void doChartInit(chartRoot, canvasEl, columns, rows, parsed, downloadCsv).catch((err) => {
104
113
  const detail = err instanceof Error ? err.message : String(err);
105
114
  const msg = document.createElement('div');
106
115
  msg.className = 'oml-md-result-message';
@@ -117,6 +126,7 @@ async function doChartInit(
117
126
  columns: string[],
118
127
  rows: string[][],
119
128
  parsed: ParsedChartOptions,
129
+ downloadCsv: (content: string) => void,
120
130
  ): Promise<void> {
121
131
  const ChartCtor = await loadChartJs();
122
132
  let chart: any = null;
@@ -131,6 +141,7 @@ async function doChartInit(
131
141
  };
132
142
 
133
143
  buildAndRender();
144
+ installChartToolbar(chartRoot, columns, rows, downloadCsv);
134
145
 
135
146
  // Resize the canvas whenever the host element resizes.
136
147
  const resizeObserver = new ResizeObserver(() => {
@@ -215,6 +226,86 @@ async function doChartInit(
215
226
  resizeHandle.addEventListener('pointercancel', onResizePointerEnd);
216
227
  }
217
228
 
229
+ function installChartToolbar(
230
+ chartRoot: HTMLElement,
231
+ columns: string[],
232
+ rows: string[][],
233
+ downloadCsv: (content: string) => void
234
+ ): void {
235
+ if (chartRoot.querySelector('.graph-corner-toolbar')) {
236
+ return;
237
+ }
238
+
239
+ const hotspot = document.createElement('div');
240
+ hotspot.className = 'graph-corner-hotspot';
241
+ chartRoot.appendChild(hotspot);
242
+
243
+ const toolbar = document.createElement('div');
244
+ toolbar.className = 'graph-corner-toolbar';
245
+ const downloadButton = createDownloadButton();
246
+ downloadButton.addEventListener('click', () => {
247
+ downloadCsv(toCsv(columns, rows));
248
+ });
249
+ toolbar.appendChild(downloadButton);
250
+ chartRoot.appendChild(toolbar);
251
+
252
+ let hideTimer = 0;
253
+ const showToolbar = () => {
254
+ if (hideTimer) {
255
+ window.clearTimeout(hideTimer);
256
+ hideTimer = 0;
257
+ }
258
+ chartRoot.classList.add('graph-toolbar-visible');
259
+ };
260
+ const scheduleHideToolbar = () => {
261
+ hideTimer = window.setTimeout(() => {
262
+ chartRoot.classList.remove('graph-toolbar-visible');
263
+ hideTimer = 0;
264
+ }, 120);
265
+ };
266
+
267
+ hotspot.addEventListener('mouseenter', showToolbar);
268
+ toolbar.addEventListener('mouseenter', showToolbar);
269
+ hotspot.addEventListener('mouseleave', scheduleHideToolbar);
270
+ toolbar.addEventListener('mouseleave', scheduleHideToolbar);
271
+
272
+ const swallowPointer = (event: Event) => {
273
+ event.stopPropagation();
274
+ };
275
+ toolbar.addEventListener('pointerdown', swallowPointer, true);
276
+ toolbar.addEventListener('mousedown', swallowPointer, true);
277
+ downloadButton.addEventListener('pointerdown', swallowPointer, true);
278
+ downloadButton.addEventListener('mousedown', swallowPointer, true);
279
+ }
280
+
281
+ function createDownloadButton(): HTMLButtonElement {
282
+ const downloadButton = document.createElement('button');
283
+ downloadButton.className = 'tree-download-btn';
284
+ downloadButton.title = 'Download CSV';
285
+ downloadButton.setAttribute('aria-label', 'Download CSV');
286
+ const iconSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
287
+ iconSvg.setAttribute('viewBox', '0 0 24 24');
288
+ iconSvg.setAttribute('width', '20');
289
+ iconSvg.setAttribute('height', '20');
290
+ iconSvg.setAttribute('aria-hidden', 'true');
291
+ iconSvg.setAttribute('focusable', 'false');
292
+ iconSvg.style.fill = 'currentColor';
293
+ const iconPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
294
+ iconPath.setAttribute('d', 'M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z');
295
+ iconSvg.appendChild(iconPath);
296
+ downloadButton.appendChild(iconSvg);
297
+ return downloadButton;
298
+ }
299
+
300
+ function toCsv(columns: string[], rows: string[][]): string {
301
+ const escape = (value: string): string => `"${String(value ?? '').replace(/"/g, '""')}"`;
302
+ const lines = [columns.map(escape).join(',')];
303
+ for (const row of rows) {
304
+ lines.push(columns.map((_, index) => escape(row[index] ?? '')).join(','));
305
+ }
306
+ return lines.join('\n');
307
+ }
308
+
218
309
  // --- Chart.js loader ---
219
310
 
220
311
  async function loadChartJs(): Promise<new (canvas: HTMLCanvasElement, config: unknown) => any> {