@helping-ai-workflow/md2doc 2.7.0 → 2.8.1

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 (2) hide show
  1. package/lib/md2doc.js +244 -24
  2. package/package.json +2 -2
package/lib/md2doc.js CHANGED
@@ -1368,6 +1368,34 @@ const html = `<!DOCTYPE html>
1368
1368
  background: rgba(147, 197, 253, 0.35);
1369
1369
  box-shadow: inset 0 0 0 1px #93c5fd;
1370
1370
  }
1371
+ .lightbox-swatch {
1372
+ width: 16px;
1373
+ height: 16px;
1374
+ min-width: 16px;
1375
+ padding: 0;
1376
+ border-radius: 50%;
1377
+ border: 2px solid rgba(255, 255, 255, 0.4);
1378
+ cursor: pointer;
1379
+ align-self: center;
1380
+ }
1381
+ .lightbox-swatch.is-active {
1382
+ border-color: #ffffff;
1383
+ box-shadow: 0 0 0 2px #93c5fd;
1384
+ }
1385
+ /* Inline annotation overlay left behind after closing the lightbox:
1386
+ same-viewBox svg over the source figure, in-memory only. */
1387
+ .anno-inline-wrap {
1388
+ position: relative;
1389
+ display: inline-block;
1390
+ max-width: 100%;
1391
+ }
1392
+ .anno-inline {
1393
+ position: absolute;
1394
+ inset: 0;
1395
+ width: 100%;
1396
+ height: 100%;
1397
+ pointer-events: none;
1398
+ }
1371
1399
  .lightbox-sep {
1372
1400
  width: 1px;
1373
1401
  align-self: stretch;
@@ -2187,16 +2215,25 @@ ${mermaidInitTag}` : ''}
2187
2215
  // close/reopen keeps them, reload starts clean (they are reading-session
2188
2216
  // scratch, and localStorage keys would go stale when the doc regenerates).
2189
2217
  var ANNO_NS = 'http://www.w3.org/2000/svg';
2218
+ var ANNO_COLORS = ['#ef4444', '#3b82f6', '#22c55e', '#f59e0b', '#111827'];
2219
+ // Office-like absolute stroke widths: rendered px at fit zoom (S/M/L).
2220
+ var ANNO_WIDTHS = [1, 2, 4];
2190
2221
  var annoStore = (typeof WeakMap === 'function') ? new WeakMap() : null;
2191
2222
  var annoShapes = [];
2192
2223
  var annoSvg = null;
2193
- var annoMode = null; // null | 'f' | 'e' | 'r' | 'm'
2224
+ var annoMode = null; // null | 'f' | 'e' | 'r' | 'l' | 'a' | 'm'
2194
2225
  var annoSelected = null;
2195
2226
  var annoDraft = null;
2196
2227
  var annoUndoStack = [];
2197
2228
  var annoRedoStack = [];
2198
2229
  var annoStrokeW = 3;
2230
+ var annoColor = ANNO_COLORS[0];
2231
+ var annoWidth = ANNO_WIDTHS[1];
2199
2232
  var annoToolButtons = {};
2233
+ var annoStyleButtons = [];
2234
+ var annoSourceNode = null;
2235
+ var annoCloneEl = null;
2236
+ var annoBaseSrc = null;
2200
2237
 
2201
2238
  function lightboxIsOpen() {
2202
2239
  return !!lightboxEl && !lightboxEl.hidden;
@@ -2308,11 +2345,12 @@ ${mermaidInitTag}` : ''}
2308
2345
  function annoShapeEl(shape) {
2309
2346
  var tag = (shape.type === 'line' || shape.type === 'arrow') ? 'line' : shape.type;
2310
2347
  var el = document.createElementNS(ANNO_NS, tag);
2348
+ var color = shape.color || ANNO_COLORS[0];
2311
2349
  if (shape.type === 'line' || shape.type === 'arrow') {
2312
2350
  el.setAttribute('x1', shape.x1.toFixed(1)); el.setAttribute('y1', shape.y1.toFixed(1));
2313
2351
  el.setAttribute('x2', shape.x2.toFixed(1)); el.setAttribute('y2', shape.y2.toFixed(1));
2314
2352
  el.setAttribute('stroke-linecap', 'round');
2315
- if (shape.type === 'arrow') el.setAttribute('marker-end', 'url(#anno-arrow-head)');
2353
+ if (shape.type === 'arrow') el.setAttribute('marker-end', 'url(#anno-arrow-' + color.slice(1) + ')');
2316
2354
  } else if (shape.type === 'rect') {
2317
2355
  el.setAttribute('x', shape.x.toFixed(1)); el.setAttribute('y', shape.y.toFixed(1));
2318
2356
  el.setAttribute('width', Math.max(0.1, shape.w).toFixed(1));
@@ -2329,32 +2367,36 @@ ${mermaidInitTag}` : ''}
2329
2367
  el.setAttribute('stroke-linejoin', 'round');
2330
2368
  el.setAttribute('stroke-linecap', 'round');
2331
2369
  }
2332
- el.setAttribute('stroke', '#ef4444');
2333
- el.setAttribute('stroke-width', String(annoStrokeW));
2370
+ el.setAttribute('stroke', color);
2371
+ el.setAttribute('stroke-width', (shape.sw || annoStrokeW).toFixed(2));
2334
2372
  return el;
2335
2373
  }
2336
2374
 
2337
- function annoEnsureDefs() {
2375
+ function annoEnsureDefs(svg) {
2338
2376
  var defs = document.createElementNS(ANNO_NS, 'defs');
2339
- var marker = document.createElementNS(ANNO_NS, 'marker');
2340
- marker.setAttribute('id', 'anno-arrow-head');
2341
- marker.setAttribute('markerWidth', '8');
2342
- marker.setAttribute('markerHeight', '8');
2343
- marker.setAttribute('refX', '6.4');
2344
- marker.setAttribute('refY', '3');
2345
- marker.setAttribute('orient', 'auto');
2346
- var tip = document.createElementNS(ANNO_NS, 'path');
2347
- tip.setAttribute('d', 'M0 0 L7 3 L0 6 Z');
2348
- tip.setAttribute('fill', '#ef4444');
2349
- marker.appendChild(tip);
2350
- defs.appendChild(marker);
2351
- annoSvg.appendChild(defs);
2377
+ ANNO_COLORS.forEach(function (color) {
2378
+ var marker = document.createElementNS(ANNO_NS, 'marker');
2379
+ // Same id + content in every overlay svg, so document-wide url(#) lookups
2380
+ // always resolve to an identical marker.
2381
+ marker.setAttribute('id', 'anno-arrow-' + color.slice(1));
2382
+ marker.setAttribute('markerWidth', '8');
2383
+ marker.setAttribute('markerHeight', '8');
2384
+ marker.setAttribute('refX', '6.4');
2385
+ marker.setAttribute('refY', '3');
2386
+ marker.setAttribute('orient', 'auto');
2387
+ var tip = document.createElementNS(ANNO_NS, 'path');
2388
+ tip.setAttribute('d', 'M0 0 L7 3 L0 6 Z');
2389
+ tip.setAttribute('fill', color);
2390
+ marker.appendChild(tip);
2391
+ defs.appendChild(marker);
2392
+ });
2393
+ svg.appendChild(defs);
2352
2394
  }
2353
2395
 
2354
2396
  function annoRedraw() {
2355
2397
  if (!annoSvg) return;
2356
2398
  while (annoSvg.firstChild) annoSvg.removeChild(annoSvg.firstChild);
2357
- annoEnsureDefs();
2399
+ annoEnsureDefs(annoSvg);
2358
2400
  annoShapes.forEach(function (shape, index) {
2359
2401
  var g = document.createElementNS(ANNO_NS, 'g');
2360
2402
  g.setAttribute('data-anno-id', String(index));
@@ -2370,13 +2412,14 @@ ${mermaidInitTag}` : ''}
2370
2412
  }
2371
2413
  hit.setAttribute('fill', 'none');
2372
2414
  hit.setAttribute('stroke', 'transparent');
2373
- hit.setAttribute('stroke-width', String(annoStrokeW * 5));
2415
+ hit.setAttribute('stroke-width', String(Math.max((shape.sw || annoStrokeW) * 5, 10 / (lightboxFitZoom || 1))));
2374
2416
  hit.setAttribute('data-anno-hit', '');
2375
2417
  g.appendChild(hit);
2376
2418
  }
2377
2419
  annoSvg.appendChild(g);
2378
2420
  });
2379
2421
  if (annoSelected && annoShapes.indexOf(annoSelected) !== -1) {
2422
+ var u = 1.5 / (lightboxFitZoom || 1); // ~1.5px at fit zoom
2380
2423
  var box = annoBBox(annoSelected);
2381
2424
  var ui = document.createElementNS(ANNO_NS, 'rect');
2382
2425
  ui.setAttribute('data-anno-ui', '');
@@ -2384,10 +2427,10 @@ ${mermaidInitTag}` : ''}
2384
2427
  ui.setAttribute('width', Math.max(0.1, box.w)); ui.setAttribute('height', Math.max(0.1, box.h));
2385
2428
  ui.setAttribute('fill', 'none');
2386
2429
  ui.setAttribute('stroke', '#3b82f6');
2387
- ui.setAttribute('stroke-width', String(Math.max(1, annoStrokeW / 2)));
2388
- ui.setAttribute('stroke-dasharray', (annoStrokeW * 2) + ' ' + annoStrokeW);
2430
+ ui.setAttribute('stroke-width', String(u));
2431
+ ui.setAttribute('stroke-dasharray', (u * 4) + ' ' + (u * 2));
2389
2432
  annoSvg.appendChild(ui);
2390
- var hs = annoStrokeW * 3;
2433
+ var hs = u * 6;
2391
2434
  [[box.x, box.y], [box.x + box.w, box.y], [box.x, box.y + box.h], [box.x + box.w, box.y + box.h]]
2392
2435
  .forEach(function (corner, i) {
2393
2436
  var h = document.createElementNS(ANNO_NS, 'rect');
@@ -2404,6 +2447,7 @@ ${mermaidInitTag}` : ''}
2404
2447
  function annoPushOp(op) {
2405
2448
  annoUndoStack.push(op);
2406
2449
  annoRedoStack.length = 0;
2450
+ annoBake();
2407
2451
  }
2408
2452
 
2409
2453
  function annoApplyOp(op, reverse) {
@@ -2415,6 +2459,10 @@ ${mermaidInitTag}` : ''}
2415
2459
  else annoShapes.splice(annoShapes.indexOf(op.shape), 1);
2416
2460
  } else if (op.kind === 'geom') {
2417
2461
  annoSetGeom(op.shape, reverse ? op.before : op.after);
2462
+ } else if (op.kind === 'style') {
2463
+ var style = reverse ? op.before : op.after;
2464
+ op.shape.color = style.color;
2465
+ op.shape.sw = style.sw;
2418
2466
  } else if (op.kind === 'clear') {
2419
2467
  if (reverse) op.shapes.forEach(function (s) { annoShapes.push(s); });
2420
2468
  else annoShapes.length = 0;
@@ -2428,6 +2476,7 @@ ${mermaidInitTag}` : ''}
2428
2476
  annoRedoStack.push(op);
2429
2477
  annoSelected = null;
2430
2478
  annoRedraw();
2479
+ annoBake();
2431
2480
  }
2432
2481
 
2433
2482
  function annoRedo() {
@@ -2437,6 +2486,7 @@ ${mermaidInitTag}` : ''}
2437
2486
  annoUndoStack.push(op);
2438
2487
  annoSelected = null;
2439
2488
  annoRedraw();
2489
+ annoBake();
2440
2490
  }
2441
2491
 
2442
2492
  function annoClearAll() {
@@ -2457,6 +2507,129 @@ ${mermaidInitTag}` : ''}
2457
2507
  annoRedraw();
2458
2508
  }
2459
2509
 
2510
+ function setAnnoStyle(patch) {
2511
+ if (patch.color) annoColor = patch.color;
2512
+ if (patch.w) annoWidth = patch.w;
2513
+ annoStyleButtons.forEach(function (entry) {
2514
+ entry.button.classList.toggle('is-active',
2515
+ entry.kind === 'color' ? entry.value === annoColor : entry.value === annoWidth);
2516
+ });
2517
+ // With a selection, the pickers restyle it (undoably); otherwise they only
2518
+ // set the style for the next shape.
2519
+ if (annoSelected) {
2520
+ var beforeStyle = { color: annoSelected.color, sw: annoSelected.sw };
2521
+ annoSelected.color = patch.color || annoSelected.color;
2522
+ if (patch.w) annoSelected.sw = patch.w / (lightboxFitZoom || 1);
2523
+ annoPushOp({
2524
+ kind: 'style', shape: annoSelected,
2525
+ before: beforeStyle,
2526
+ after: { color: annoSelected.color, sw: annoSelected.sw },
2527
+ });
2528
+ annoRedraw();
2529
+ }
2530
+ }
2531
+
2532
+ // Re-bake the shown raster clone (image + shapes composited to a PNG data
2533
+ // URI) so a native right-click "Copy image" carries the annotations.
2534
+ function annoShapesSvgMarkup() {
2535
+ var svg = document.createElementNS(ANNO_NS, 'svg');
2536
+ svg.setAttribute('xmlns', ANNO_NS);
2537
+ svg.setAttribute('viewBox', '0 0 ' + lightboxNaturalW + ' ' + lightboxNaturalH);
2538
+ svg.setAttribute('width', lightboxNaturalW);
2539
+ svg.setAttribute('height', lightboxNaturalH);
2540
+ annoEnsureDefs(svg);
2541
+ annoShapes.forEach(function (shape) { svg.appendChild(annoShapeEl(shape)); });
2542
+ return new XMLSerializer().serializeToString(svg);
2543
+ }
2544
+
2545
+ function annoComposite(drawBase, scale, done) {
2546
+ var canvas = document.createElement('canvas');
2547
+ canvas.width = lightboxNaturalW * scale;
2548
+ canvas.height = lightboxNaturalH * scale;
2549
+ var ctx = canvas.getContext('2d');
2550
+ drawBase(ctx, canvas, function () {
2551
+ if (!annoShapes.length) { done(canvas); return; }
2552
+ var overlay = new Image();
2553
+ overlay.onload = function () {
2554
+ ctx.drawImage(overlay, 0, 0, canvas.width, canvas.height);
2555
+ done(canvas);
2556
+ };
2557
+ overlay.onerror = function () { done(canvas); };
2558
+ overlay.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(annoShapesSvgMarkup());
2559
+ });
2560
+ }
2561
+
2562
+ function annoBake() {
2563
+ if (!annoCloneEl || annoCloneEl.tagName !== 'IMG' || !annoBaseSrc) return;
2564
+ var expected = annoCloneEl;
2565
+ annoComposite(function (ctx, canvas, next) {
2566
+ var base = new Image();
2567
+ base.onload = function () { ctx.drawImage(base, 0, 0, canvas.width, canvas.height); next(); };
2568
+ base.onerror = function () { next(); };
2569
+ base.src = annoBaseSrc;
2570
+ }, 1, function (canvas) {
2571
+ if (annoCloneEl !== expected) return; // lightbox moved on to another image
2572
+ try { annoCloneEl.src = canvas.toDataURL('image/png'); }
2573
+ catch (e) { /* tainted canvas — keep the plain image */ }
2574
+ });
2575
+ }
2576
+
2577
+ function annoCopyImage() {
2578
+ var clone = annoCloneEl;
2579
+ if (!clone) return;
2580
+ var isImg = clone.tagName === 'IMG';
2581
+ annoComposite(function (ctx, canvas, next) {
2582
+ ctx.fillStyle = '#ffffff';
2583
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
2584
+ var base = new Image();
2585
+ base.onload = function () { ctx.drawImage(base, 0, 0, canvas.width, canvas.height); next(); };
2586
+ base.onerror = function () { next(); };
2587
+ base.src = isImg ? (annoBaseSrc || clone.src)
2588
+ : 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(new XMLSerializer().serializeToString(clone));
2589
+ }, isImg ? 1 : 2, function (canvas) {
2590
+ try {
2591
+ canvas.toBlob(function (blob) {
2592
+ if (!blob || typeof ClipboardItem === 'undefined' || !navigator.clipboard || !navigator.clipboard.write) return;
2593
+ navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]).catch(function () {});
2594
+ }, 'image/png');
2595
+ } catch (e) { /* clipboard unavailable */ }
2596
+ });
2597
+ }
2598
+
2599
+ // After Esc the drawings stay visible on the inline figure: a same-viewBox
2600
+ // overlay svg over the source element. In-memory only — gone on reload.
2601
+ function annoSyncInline() {
2602
+ var node = annoSourceNode;
2603
+ if (!node) return;
2604
+ var visual = lightboxSourceOf(node);
2605
+ if (!visual || !visual.parentNode) return;
2606
+ var wrap = visual.closest ? visual.closest('.anno-inline-wrap') : null;
2607
+ var shapes = annoShapes;
2608
+ if (!shapes.length) {
2609
+ if (wrap) {
2610
+ var old = wrap.querySelector('svg.anno-inline');
2611
+ if (old) wrap.removeChild(old);
2612
+ }
2613
+ return;
2614
+ }
2615
+ if (!wrap) {
2616
+ wrap = document.createElement('span');
2617
+ wrap.className = 'anno-inline-wrap';
2618
+ visual.parentNode.insertBefore(wrap, visual);
2619
+ wrap.appendChild(visual);
2620
+ }
2621
+ var overlay = wrap.querySelector('svg.anno-inline');
2622
+ if (!overlay) {
2623
+ overlay = document.createElementNS(ANNO_NS, 'svg');
2624
+ overlay.setAttribute('class', 'anno-inline');
2625
+ wrap.appendChild(overlay);
2626
+ }
2627
+ overlay.setAttribute('viewBox', '0 0 ' + lightboxNaturalW + ' ' + lightboxNaturalH);
2628
+ while (overlay.firstChild) overlay.removeChild(overlay.firstChild);
2629
+ annoEnsureDefs(overlay);
2630
+ shapes.forEach(function (shape) { overlay.appendChild(annoShapeEl(shape)); });
2631
+ }
2632
+
2460
2633
  function setAnnoMode(mode) {
2461
2634
  annoMode = (annoMode === mode) ? null : mode;
2462
2635
  if (annoMode !== 'm') annoSelected = null;
@@ -2519,6 +2692,11 @@ ${mermaidInitTag}` : ''}
2519
2692
  annoSelected = null;
2520
2693
  annoRedraw();
2521
2694
  }
2695
+ // The baked clone still shows the shape at its old spot — revert to the
2696
+ // base image for the gesture; the overlay alone renders the live shapes.
2697
+ if (annoDraft && annoCloneEl && annoCloneEl.tagName === 'IMG' && annoBaseSrc) {
2698
+ annoCloneEl.src = annoBaseSrc;
2699
+ }
2522
2700
  return;
2523
2701
  }
2524
2702
  var shape;
@@ -2527,6 +2705,8 @@ ${mermaidInitTag}` : ''}
2527
2705
  else if (annoMode === 'l') shape = { type: 'line', x1: pt.x, y1: pt.y, x2: pt.x, y2: pt.y };
2528
2706
  else if (annoMode === 'a') shape = { type: 'arrow', x1: pt.x, y1: pt.y, x2: pt.x, y2: pt.y };
2529
2707
  else shape = { type: 'rect', x: pt.x, y: pt.y, w: 0, h: 0 };
2708
+ shape.color = annoColor;
2709
+ shape.sw = annoWidth / (lightboxFitZoom || 1);
2530
2710
  annoDraft = { kind: 'draw', shape: shape, start: pt, el: annoShapeEl(shape), clientDist: 0, lastClient: [event.clientX, event.clientY] };
2531
2711
  annoSvg.appendChild(annoDraft.el);
2532
2712
  }
@@ -2593,11 +2773,16 @@ ${mermaidInitTag}` : ''}
2593
2773
  }
2594
2774
  if (d.moved) {
2595
2775
  annoPushOp({ kind: 'geom', shape: d.shape, before: d.before, after: annoGeomOf(d.shape) });
2776
+ } else {
2777
+ annoBake(); // gesture reverted the clone to the base image — restore it
2596
2778
  }
2597
2779
  annoRedraw();
2598
2780
  }
2599
2781
 
2600
2782
  function annoSetup(sourceNode) {
2783
+ annoSourceNode = sourceNode;
2784
+ annoCloneEl = lightboxCanvas.firstElementChild;
2785
+ annoBaseSrc = (annoCloneEl && annoCloneEl.tagName === 'IMG') ? annoCloneEl.src : null;
2601
2786
  annoShapes = [];
2602
2787
  if (annoStore) {
2603
2788
  annoShapes = annoStore.get(sourceNode);
@@ -2618,6 +2803,7 @@ ${mermaidInitTag}` : ''}
2618
2803
  lightboxCanvas.appendChild(annoSvg);
2619
2804
  annoMode = null;
2620
2805
  setAnnoMode(null);
2806
+ if (annoShapes.length) annoBake();
2621
2807
  }
2622
2808
 
2623
2809
  function buildLightbox() {
@@ -2658,6 +2844,25 @@ ${mermaidInitTag}` : ''}
2658
2844
  annoToolButtons[tool[0]] = button;
2659
2845
  bar.appendChild(button);
2660
2846
  });
2847
+ ANNO_COLORS.forEach(function (color) {
2848
+ var swatch = lightboxButton('', 'Stroke color ' + color, function () { setAnnoStyle({ color: color }); });
2849
+ swatch.className = 'lightbox-swatch';
2850
+ swatch.style.background = color;
2851
+ swatch.setAttribute('data-anno-color', color);
2852
+ if (color === annoColor) swatch.classList.add('is-active');
2853
+ annoStyleButtons.push({ kind: 'color', value: color, button: swatch });
2854
+ bar.appendChild(swatch);
2855
+ });
2856
+ [['S', ANNO_WIDTHS[0]], ['M', ANNO_WIDTHS[1]], ['L', ANNO_WIDTHS[2]]].forEach(function (width) {
2857
+ var button = lightboxButton(width[0], 'Stroke width ' + width[1] + 'px', function () { setAnnoStyle({ w: width[1] }); });
2858
+ button.setAttribute('data-anno-width', String(width[1]));
2859
+ if (width[1] === annoWidth) button.classList.add('is-active');
2860
+ annoStyleButtons.push({ kind: 'width', value: width[1], button: button });
2861
+ bar.appendChild(button);
2862
+ });
2863
+ var copyButton = lightboxButton('⧉', 'Copy image with annotations', annoCopyImage);
2864
+ copyButton.setAttribute('data-anno-copy', '');
2865
+ bar.appendChild(copyButton);
2661
2866
  var clearButton = lightboxButton('Clear', 'Clear all annotations', annoClearAll);
2662
2867
  clearButton.setAttribute('data-anno-clear', '');
2663
2868
  bar.appendChild(clearButton);
@@ -2752,7 +2957,18 @@ ${mermaidInitTag}` : ''}
2752
2957
 
2753
2958
  var isVector = !!(source.tagName && source.tagName.toLowerCase() === 'svg');
2754
2959
  var clone = source.cloneNode(true);
2755
- clone.removeAttribute('id');
2960
+ // Mermaid scopes its embedded <style> to the svg's #id — dropping the id
2961
+ // kills the theme. Rename it instead (avoids a duplicate id) and rewrite
2962
+ // the scoped selectors to the new name.
2963
+ if (isVector && source.id) {
2964
+ var lightboxCloneId = 'lightbox-' + source.id;
2965
+ clone.setAttribute('id', lightboxCloneId);
2966
+ Array.prototype.forEach.call(clone.querySelectorAll('style'), function (styleEl) {
2967
+ styleEl.textContent = styleEl.textContent.split('#' + source.id).join('#' + lightboxCloneId);
2968
+ });
2969
+ } else {
2970
+ clone.removeAttribute('id');
2971
+ }
2756
2972
  clone.removeAttribute('class');
2757
2973
  clone.removeAttribute('style');
2758
2974
  clone.removeAttribute('width');
@@ -2782,6 +2998,10 @@ ${mermaidInitTag}` : ''}
2782
2998
  lightboxEl.hidden = true;
2783
2999
  document.body.removeAttribute('data-lightbox-open');
2784
3000
  annoCancelDraft();
3001
+ annoSyncInline();
3002
+ annoSourceNode = null;
3003
+ annoCloneEl = null;
3004
+ annoBaseSrc = null;
2785
3005
  annoSvg = null;
2786
3006
  annoMode = null;
2787
3007
  setAnnoMode(null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@helping-ai-workflow/md2doc",
3
- "version": "2.7.0",
3
+ "version": "2.8.1",
4
4
  "description": "Markdown → HTML / PDF renderer with WaveDrom, Mermaid, and Graphviz support",
5
5
  "keywords": [
6
6
  "markdown",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "scripts": {
38
38
  "preinstall": "node scripts/preinstall.js",
39
- "test": "node test/md2doc.test.js && node test/images.test.js && node test/scroll-anchor.test.js && node test/lightbox.test.js && node test/lightbox-anno.test.js && node test/reader-panels.test.js && node test/cli.test.js && node test/code-operator.test.js"
39
+ "test": "node test/md2doc.test.js && node test/images.test.js && node test/scroll-anchor.test.js && node test/lightbox.test.js && node test/lightbox-anno.test.js && node test/lightbox-anno-style.test.js && node test/reader-panels.test.js && node test/cli.test.js && node test/code-operator.test.js"
40
40
  },
41
41
  "repository": {
42
42
  "type": "git",