markdown-design-doc-viewer-embed 1.5.1 → 1.5.3

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/README.ja.md CHANGED
@@ -78,6 +78,7 @@ viewer.destroy();
78
78
  | `tableTreeHighlight` | `true` | 木構造で表示した表の行の親子をハイライトします。 |
79
79
  | `frontMatter` | `true` | front matter を(設計書のヘッダ、または表として)表示します。 |
80
80
  | `headingNumbers` | `true` | 紐付いた見出しに `autonumber` の番号を表示します。 |
81
+ | `messageWrapWidth` | `40` | シーケンス図の矢印のラベルをこの文字数(全角は 2 文字と数える)で改行します。`0` にすると改行しません。 |
81
82
  | `onOpenLink` | `openLinkInNewTab` | `(href) => void`: 設計書のリンク(ビューアがスクロールする `#見出し` 以外)を開きます。既定では http(s) と mailto のリンクを新しいタブで開き、ほかは何もしません。 |
82
83
  | `onRevealLine` | | `(line) => void`: ビューアでダブルクリックした Markdown の行(0 始まり)で呼ばれます(エディタでその行を表示するなど)。ないときはダブルクリックしても何もしません。 |
83
84
 
package/README.md CHANGED
@@ -78,6 +78,7 @@ viewer.destroy();
78
78
  | `tableTreeHighlight` | `true` | Highlights the parent and children of a row of a table shown as a tree. |
79
79
  | `frontMatter` | `true` | Shows the front matter (as the header of a design document, or as a table). |
80
80
  | `headingNumbers` | `true` | Shows the `autonumber` numbers on the linked headings. |
81
+ | `messageWrapWidth` | `40` | Breaks the labels of the arrows of the sequence diagrams into lines at this many characters (a full-width one counts as 2). `0` does not break them. |
81
82
  | `onOpenLink` | `openLinkInNewTab` | `(href) => void`: opens a link of the document (other than `#heading`, which the viewer scrolls to). By default, http(s) and mailto links open in a new tab, and the others do nothing. |
82
83
  | `onRevealLine` | | `(line) => void`: called with the line (0-based) of the Markdown double-clicked in the viewer, e.g. to show it in an editor. Without it, a double-click does nothing. |
83
84
 
package/index.js CHANGED
@@ -14447,6 +14447,8 @@ var bundle_l10n_ja_default = {
14447
14447
  "neo: rounder shapes, with shadows on flowchart nodes. classic: flat, without shadows.": "neo: \u89D2\u304C\u4E38\u304F\u3001\u30D5\u30ED\u30FC\u30C1\u30E3\u30FC\u30C8\u306E\u30CE\u30FC\u30C9\u306B\u5F71\u304C\u4ED8\u304D\u307E\u3059\u3002classic: \u5E73\u5766\u3067\u3001\u5F71\u306F\u4ED8\u304D\u307E\u305B\u3093\u3002",
14448
14448
  "Side-by-Side Width (px)": "\u6A2A\u4E26\u3073\u306B\u3059\u308B\u5E45 (px)",
14449
14449
  "Shows the diagrams beside their step descriptions when the preview is at least this wide.": "\u30D7\u30EC\u30D3\u30E5\u30FC\u306E\u5E45\u304C\u3053\u308C\u4EE5\u4E0A\u306E\u3068\u304D\u3001\u56F3\u3068\u51E6\u7406\u6982\u8981\u3092\u6A2A\u306B\u4E26\u3079\u307E\u3059\u3002",
14450
+ "Arrow Label Width": "\u77E2\u5370\u306E\u30E9\u30D9\u30EB\u306E\u5E45",
14451
+ "Breaks the labels of the arrows of the sequence diagrams into lines at this many characters (a full-width one counts as 2). 0: not broken.": "\u30B7\u30FC\u30B1\u30F3\u30B9\u56F3\u306E\u77E2\u5370\u306E\u30E9\u30D9\u30EB\u3092\u3053\u306E\u6587\u5B57\u6570\uFF08\u5168\u89D2\u306F 2 \u6587\u5B57\u3068\u6570\u3048\u308B\uFF09\u3067\u6539\u884C\u3057\u307E\u3059\u30020 \u306B\u3059\u308B\u3068\u6539\u884C\u3057\u307E\u305B\u3093\u3002",
14450
14452
  "Table of Contents": "\u76EE\u6B21",
14451
14453
  "Shown when hovering the right edge of the preview.": "\u30D7\u30EC\u30D3\u30E5\u30FC\u306E\u53F3\u7AEF\u306B\u30DE\u30A6\u30B9\u3092\u4E57\u305B\u308B\u3068\u958B\u304D\u307E\u3059\u3002",
14452
14454
  "Heading Numbers": "\u898B\u51FA\u3057\u306E\u756A\u53F7",
@@ -14571,9 +14573,10 @@ var bundle_l10n_ja_default = {
14571
14573
  "@goto is ignored because the next line is not a note.": "\u6B21\u306E\u884C\u304C\u30CE\u30FC\u30C8\u3067\u306F\u306A\u3044\u305F\u3081\u3001@goto \u306F\u7121\u8996\u3055\u308C\u307E\u3059\u3002",
14572
14574
  "@goto is ignored because @anchor makes the note a label. A note is a label or a jump, not both.": "@anchor \u3067\u30CE\u30FC\u30C8\u3092\u30E9\u30D9\u30EB\u306B\u3057\u3066\u3044\u308B\u305F\u3081\u3001@goto \u306F\u7121\u8996\u3055\u308C\u307E\u3059\u30021 \u3064\u306E\u30CE\u30FC\u30C8\u306F\u30E9\u30D9\u30EB\u304B\u30B8\u30E3\u30F3\u30D7\u306E\u3069\u3061\u3089\u304B\u3067\u3059\u3002",
14573
14575
  'Label "{0}" is already defined in the sequence diagram.': "\u30E9\u30D9\u30EB\u300C{0}\u300D\u306F\u30B7\u30FC\u30B1\u30F3\u30B9\u56F3\u3067\u3059\u3067\u306B\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u307E\u3059\u3002",
14574
- '@goto target label "{0}" was not found in the sequence diagram.': "@goto \u3067\u6307\u5B9A\u3057\u305F\u30E9\u30D9\u30EB\u300C{0}\u300D\u304C\u30B7\u30FC\u30B1\u30F3\u30B9\u56F3\u306B\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002",
14576
+ '@goto target label "{0}" was not found in the sequence diagrams of the document.': "@goto \u3067\u6307\u5B9A\u3057\u305F\u30E9\u30D9\u30EB\u300C{0}\u300D\u304C\u6587\u66F8\u306E\u30B7\u30FC\u30B1\u30F3\u30B9\u56F3\u306B\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002",
14577
+ '@goto target label "{0}" is defined in more than one other sequence diagram. Name the label to jump to uniquely with @anchor.': "@goto \u3067\u6307\u5B9A\u3057\u305F\u30E9\u30D9\u30EB\u300C{0}\u300D\u306F\u307B\u304B\u306E\u8907\u6570\u306E\u30B7\u30FC\u30B1\u30F3\u30B9\u56F3\u3067\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u30B8\u30E3\u30F3\u30D7\u5148\u306E\u30E9\u30D9\u30EB\u306B @anchor \u3067\u4E00\u610F\u306A\u540D\u524D\u3092\u4ED8\u3051\u3066\u304F\u3060\u3055\u3044\u3002",
14575
14578
  "Make the next note (or section of a block) a label that notes can jump to.": "\u76F4\u5F8C\u306E\u30CE\u30FC\u30C8\uFF08\u307E\u305F\u306F\u30D6\u30ED\u30C3\u30AF\u306E\u5206\u5C90\uFF09\u3092\u3001\u30CE\u30FC\u30C8\u304B\u3089\u79FB\u52D5\u3067\u304D\u308B\u30E9\u30D9\u30EB\u306B\u3057\u307E\u3059\u3002",
14576
- "Make the next note jump to a label.": "\u76F4\u5F8C\u306E\u30CE\u30FC\u30C8\u3092\u3001\u30E9\u30D9\u30EB\u3078\u79FB\u52D5\u3059\u308B\u30CE\u30FC\u30C8\u306B\u3057\u307E\u3059\u3002",
14579
+ "Make the next note jump to a label of this or another sequence diagram of the document.": "\u76F4\u5F8C\u306E\u30CE\u30FC\u30C8\u3092\u3001\u3053\u306E\u56F3\u307E\u305F\u306F\u6587\u66F8\u306E\u307B\u304B\u306E\u30B7\u30FC\u30B1\u30F3\u30B9\u56F3\u306E\u30E9\u30D9\u30EB\u3078\u79FB\u52D5\u3059\u308B\u30CE\u30FC\u30C8\u306B\u3057\u307E\u3059\u3002",
14577
14580
  "Go to {0}": "{0} \u3078\u79FB\u52D5",
14578
14581
  "Back to the note you jumped from": "\u79FB\u52D5\u5143\u306E\u30CE\u30FC\u30C8\u306B\u623B\u308B"
14579
14582
  };
@@ -20230,20 +20233,16 @@ function noteJumpWording(t) {
20230
20233
  strayGoto: t("@goto is ignored because the next line is not a note."),
20231
20234
  gotoOnLabel: t("@goto is ignored because @anchor makes the note a label. A note is a label or a jump, not both."),
20232
20235
  duplicateAnchor: (name) => t('Label "{0}" is already defined in the sequence diagram.', name),
20233
- gotoNotFound: (name) => t('@goto target label "{0}" was not found in the sequence diagram.', name),
20236
+ gotoNotFound: (name) => t('@goto target label "{0}" was not found in the sequence diagrams of the document.', name),
20237
+ gotoAmbiguous: (name) => t('@goto target label "{0}" is defined in more than one other sequence diagram. Name the label to jump to uniquely with @anchor.', name),
20234
20238
  anchorDoc: t("Make the next note (or section of a block) a label that notes can jump to."),
20235
- gotoDoc: t("Make the next note jump to a label."),
20239
+ gotoDoc: t("Make the next note jump to a label of this or another sequence diagram of the document."),
20236
20240
  // `{0}` is filled in by the webview.
20237
20241
  gotoTitle: t("Go to {0}"),
20238
20242
  backTitle: t("Back to the note you jumped from")
20239
20243
  };
20240
20244
  }
20241
20245
 
20242
- // src/markdown/htmlTags.ts
20243
- var RAW_TEXT = "script|style|textarea|title";
20244
- var ATTR_RE = /([^\s"'>/=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
20245
- var decodeAttribute = (md2, value) => md2.utils.unescapeAll(value.replace(/\\/g, "\\\\"));
20246
-
20247
20246
  // src/diagrams/sequence.ts
20248
20247
  var ARROWS = [
20249
20248
  "<<-->>",
@@ -20520,6 +20519,104 @@ function stripStepNumber(heading2) {
20520
20519
  return void 0;
20521
20520
  }
20522
20521
 
20522
+ // src/diagrams/sequenceWrap.ts
20523
+ var DEFAULT_MESSAGE_WRAP_WIDTH = 40;
20524
+ var WIDE_RE = /[ᄀ-ᅟ⺀-〾ぁ-㏿㐀-䶿一-鿿ꀀ-꓏가-힣豈-﫿︰-﹏＀-⦆¢-₩\u{1F300}-\u{1F64F}\u{1F680}-\u{1F6FF}\u{1F900}-\u{1FAFF}\u{20000}-\u{3FFFD}]/u;
20525
+ var NO_START = new Set(Array.from("\u3001\u3002\uFF0C\uFF0E\u30FB\uFF1A\uFF1B\uFF1F\uFF01\u309D\u309E\u30FC\u30A1\u30A3\u30A5\u30A7\u30A9\u30C3\u30E3\u30E5\u30E7\u30EE\u30F5\u30F6\u3041\u3043\u3045\u3047\u3049\u3063\u3083\u3085\u3087\u308E\u3095\u3096\uFF09\u3015\uFF3D\uFF5D\u3009\u300B\u300D\u300F\u3011\u3019\u3017\u301F\u2019\u201D\uFF60\xBB,.:;!?)]}"));
20526
+ var NO_END = new Set(Array.from("\uFF08\u3014\uFF3B\uFF5B\u3008\u300A\u300C\u300E\u3010\u3018\u3016\u301D\u2018\u201C\uFF5F\xAB([{"));
20527
+ var KEEP_RE = /<br\s*\/?>|#|;|%%|\$\$|^:?(?:no)?wrap:/i;
20528
+ var TAG_RE = /<\/?[a-z][a-z0-9]*(?:\s[^>]*)?\/?>/;
20529
+ var keepsLabel = (text3) => KEEP_RE.test(text3) || TAG_RE.test(text3);
20530
+ var charWidth = (c) => WIDE_RE.test(c) ? 2 : 1;
20531
+ var textWidth = (text3) => Array.from(text3).reduce((sum, c) => sum + charWidth(c), 0);
20532
+ function canBreakBefore(chars, i) {
20533
+ const before = chars[i - 1];
20534
+ const after = chars[i];
20535
+ if (before === " " || after === " ") {
20536
+ return true;
20537
+ }
20538
+ if (NO_START.has(after) || NO_END.has(before)) {
20539
+ return false;
20540
+ }
20541
+ if (before === "/" && after !== "/") {
20542
+ return true;
20543
+ }
20544
+ return WIDE_RE.test(before) || WIDE_RE.test(after);
20545
+ }
20546
+ function fillLines(chars, limit) {
20547
+ const lines = [];
20548
+ let start = 0;
20549
+ while (start < chars.length) {
20550
+ while (chars[start] === " ") {
20551
+ start++;
20552
+ }
20553
+ if (start >= chars.length) {
20554
+ break;
20555
+ }
20556
+ let width = 0;
20557
+ let end = start;
20558
+ let lastBreak = -1;
20559
+ while (end < chars.length) {
20560
+ if (end > start && canBreakBefore(chars, end)) {
20561
+ lastBreak = end;
20562
+ }
20563
+ const w = charWidth(chars[end]);
20564
+ if (end > start && width + w > limit) {
20565
+ break;
20566
+ }
20567
+ width += w;
20568
+ end++;
20569
+ }
20570
+ const cut = end < chars.length && lastBreak > start ? lastBreak : end;
20571
+ lines.push(chars.slice(start, cut).join("").trimEnd());
20572
+ start = cut;
20573
+ }
20574
+ return lines;
20575
+ }
20576
+ function wrapLabel(text3, maxWidth) {
20577
+ const normalized = text3.replace(/\s+/g, " ").trim();
20578
+ const total = textWidth(normalized);
20579
+ if (maxWidth <= 0 || total <= maxWidth) {
20580
+ return [normalized];
20581
+ }
20582
+ const chars = Array.from(normalized);
20583
+ const count = fillLines(chars, maxWidth).length;
20584
+ for (let limit = Math.ceil(total / count); limit < maxWidth; limit++) {
20585
+ const lines = fillLines(chars, limit);
20586
+ if (lines.length <= count) {
20587
+ return lines;
20588
+ }
20589
+ }
20590
+ return fillLines(chars, maxWidth);
20591
+ }
20592
+ function wrapSequenceMessages(source, maxWidth) {
20593
+ if (!(maxWidth > 0) || !isSequenceDiagram(source)) {
20594
+ return source;
20595
+ }
20596
+ const { messages } = parseSequence(source, 0);
20597
+ const lines = source.split("\n");
20598
+ let changed = false;
20599
+ for (const { line } of messages) {
20600
+ const raw = lines[line];
20601
+ const colon = raw.indexOf(":");
20602
+ const label = raw.slice(colon + 1);
20603
+ const text3 = label.trim();
20604
+ if (keepsLabel(text3) || textWidth(text3) <= maxWidth) {
20605
+ continue;
20606
+ }
20607
+ const lead = /^\s*/.exec(label)[0];
20608
+ const trail = /\s*$/.exec(label)[0];
20609
+ lines[line] = `${raw.slice(0, colon + 1)}${lead}${wrapLabel(text3, maxWidth).join("<br>")}${trail}`;
20610
+ changed = true;
20611
+ }
20612
+ return changed ? lines.join("\n") : source;
20613
+ }
20614
+
20615
+ // src/markdown/htmlTags.ts
20616
+ var RAW_TEXT = "script|style|textarea|title";
20617
+ var ATTR_RE = /([^\s"'>/=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
20618
+ var decodeAttribute = (md2, value) => md2.utils.unescapeAll(value.replace(/\\/g, "\\\\"));
20619
+
20523
20620
  // src/diagrams/diagramNodes.ts
20524
20621
  function readNodes(lines, start, firstLine, rules, reader) {
20525
20622
  const excluded = reader.excluded ?? /* @__PURE__ */ new Set();
@@ -21618,13 +21715,35 @@ function noteJumps(sequence, marked, translate, warnings) {
21618
21715
  byName.set(anchor.name, { ...anchor });
21619
21716
  }
21620
21717
  }
21621
- for (const note of notes) {
21622
- if (note.goto !== void 0 && !byName.has(note.goto)) {
21623
- warnings.push({ line: note.gotoLine ?? note.line, message: wording.gotoNotFound(note.goto) });
21718
+ return { notes, anchors: [...byName.values()] };
21719
+ }
21720
+ function jumpsBetweenDiagrams(diagrams, translate, warnings) {
21721
+ const wording = noteJumpWording(translate);
21722
+ const byName = /* @__PURE__ */ new Map();
21723
+ for (const diagram of diagrams) {
21724
+ for (const anchor of diagram.anchors ?? []) {
21725
+ const found = byName.get(anchor.name) ?? [];
21726
+ found.push({ diagram, anchor });
21727
+ byName.set(anchor.name, found);
21728
+ }
21729
+ }
21730
+ for (const diagram of diagrams) {
21731
+ const own = new Set(diagram.anchors?.map((a) => a.name));
21732
+ for (const note of diagram.notes ?? []) {
21733
+ if (note.goto === void 0 || own.has(note.goto)) {
21734
+ continue;
21735
+ }
21736
+ const found = byName.get(note.goto) ?? [];
21737
+ if (found.length === 1) {
21738
+ note.gotoDiagram = found[0].diagram.id;
21739
+ found[0].anchor.jumpedFrom = true;
21740
+ continue;
21741
+ }
21742
+ const line = note.gotoLine ?? note.line;
21743
+ warnings.push({ line, message: found.length === 0 ? wording.gotoNotFound(note.goto) : wording.gotoAmbiguous(note.goto) });
21624
21744
  delete note.goto;
21625
21745
  }
21626
21746
  }
21627
- return { notes, anchors: [...byName.values()] };
21628
21747
  }
21629
21748
  function wireframeDiagram(token, index, id, translate, warnings) {
21630
21749
  const { src, options, file, parts } = wireframeOf(token);
@@ -21663,6 +21782,7 @@ function linkDiagrams(tokens, translate = formatMessage) {
21663
21782
  diagrams.push(wireframeDiagram(token, index, diagrams.length, translate, warnings));
21664
21783
  }
21665
21784
  });
21785
+ jumpsBetweenDiagrams(diagrams, translate, warnings);
21666
21786
  const pairedFences = new Set(diagrams.filter((d) => d.paired).map((d) => d.fenceIndex));
21667
21787
  for (const token of tokens) {
21668
21788
  if (token.level === 0 && token.type === "html_block" && LEGACY_END_MARKER_RE.test(token.content)) {
@@ -22069,16 +22189,17 @@ function diagramAttributes(token, env) {
22069
22189
  }))
22070
22190
  };
22071
22191
  const notes = diagram.notes ?? [];
22072
- if (notes.some((n) => n.anchor !== void 0 || n.goto !== void 0)) {
22192
+ if (notes.some((n) => n.anchor !== void 0 || n.goto !== void 0) || diagram.anchors?.some((a) => a.jumpedFrom)) {
22073
22193
  const wording = noteJumpWording(env?.t ?? formatMessage);
22074
- meta.notes = notes.map(({ index, line: line2, text: text3, anchor, goto }) => ({ index, line: line2, text: text3, anchor, goto }));
22075
- meta.anchors = diagram.anchors?.map(({ name, title, occurrence, firstTarget }) => ({ name, title, occurrence, firstTarget }));
22194
+ meta.notes = notes.map(({ index, line: line2, text: text3, anchor, goto, gotoDiagram }) => ({ index, line: line2, text: text3, anchor, goto, gotoDiagram }));
22195
+ meta.anchors = diagram.anchors?.map(({ name, title, occurrence, firstTarget, jumpedFrom }) => ({ name, title, occurrence, firstTarget, jumpedFrom }));
22076
22196
  meta.jumpTitles = { goto: wording.gotoTitle, back: wording.backTitle };
22077
22197
  }
22078
22198
  attrs += ` data-seqnotes-meta="${escapeHtml2(JSON.stringify(meta))}"`;
22079
22199
  }
22080
22200
  return attrs;
22081
22201
  }
22202
+ var mermaidSource = (content, env) => wrapSequenceMessages(content, env?.messageWrapWidth ?? DEFAULT_MESSAGE_WRAP_WIDTH);
22082
22203
  function mermaidFence(md2) {
22083
22204
  const defaultFence = md2.renderer.rules.fence;
22084
22205
  md2.renderer.rules.fence = (tokens, idx, options, env, self) => {
@@ -22086,7 +22207,7 @@ function mermaidFence(md2) {
22086
22207
  if (!isMermaidFence(token)) {
22087
22208
  return defaultFence(tokens, idx, options, env, self);
22088
22209
  }
22089
- return `<div class="seqnotes-mermaid"${diagramAttributes(token, env)}><pre class="seqnotes-mermaid-src">${escapeHtml2(token.content)}</pre></div>
22210
+ return `<div class="seqnotes-mermaid"${diagramAttributes(token, env)}><pre class="seqnotes-mermaid-src">${escapeHtml2(mermaidSource(token.content, env))}</pre></div>
22090
22211
  `;
22091
22212
  };
22092
22213
  }
@@ -25596,7 +25717,7 @@ var HOVER = "seqnotes-jump-hover";
25596
25717
  var FLASH = "seqnotes-flash";
25597
25718
  var JUMP_ELEMENTS = "svg [data-seqnotes-goto], svg [data-seqnotes-anchor]";
25598
25719
  var FLASH_MS = 1200;
25599
- function textWidth(text3, fontSize2) {
25720
+ function textWidth2(text3, fontSize2) {
25600
25721
  let em = 0;
25601
25722
  for (const c of text3) {
25602
25723
  em += /[ᄀ-ᅟ①-⓿⺀-꓏가-힣豈-﫿︰-﹏＀-⦆¢-₩]/.test(c) ? 1 : 0.6;
@@ -25620,7 +25741,8 @@ function makeBadge(group) {
25620
25741
  if (!(height > 0)) {
25621
25742
  return;
25622
25743
  }
25623
- if (texts.length === 1) {
25744
+ const larger = (t) => textWidth2(t.textContent ?? "", fontSize(t) * BADGE_FONT_SCALE) + height * 0.5;
25745
+ if (texts.length === 1 && larger(texts[0]) <= width) {
25624
25746
  const [text3] = texts;
25625
25747
  text3.style.fontSize = `${fontSize(text3) * BADGE_FONT_SCALE}px`;
25626
25748
  text3.setAttribute("y", String(num(rect, "y") + height / 2));
@@ -25632,7 +25754,7 @@ function makeBadge(group) {
25632
25754
  tspan.removeAttribute("y");
25633
25755
  }
25634
25756
  }
25635
- const textW = Math.max(...texts.map((t) => textWidth(t.textContent ?? "", fontSize(t))));
25757
+ const textW = Math.max(...texts.map((t) => textWidth2(t.textContent ?? "", fontSize(t))));
25636
25758
  const badge = Math.max(height, textW + height * 0.5);
25637
25759
  if (!(badge < width)) {
25638
25760
  return;
@@ -25706,6 +25828,7 @@ function annotateNotes(svg2, meta) {
25706
25828
  if (!notes) {
25707
25829
  return;
25708
25830
  }
25831
+ svg2.setAttribute("data-seqnotes-diagram", String(meta.id));
25709
25832
  const groups = Array.from(svg2.querySelectorAll('g[data-et="note"]'));
25710
25833
  let assigned;
25711
25834
  if (groups.length === notes.length) {
@@ -25734,6 +25857,9 @@ function annotateNotes(svg2, meta) {
25734
25857
  } else if (note.goto !== void 0) {
25735
25858
  group.classList.add("seqnotes-goto");
25736
25859
  group.setAttribute("data-seqnotes-goto", note.goto);
25860
+ if (note.gotoDiagram !== void 0) {
25861
+ group.setAttribute("data-seqnotes-goto-diagram", String(note.gotoDiagram));
25862
+ }
25737
25863
  const title = document.createElementNS(SVG_NS, "title");
25738
25864
  title.textContent = (meta.jumpTitles?.goto ?? "{0}").replace("{0}", note.goto);
25739
25865
  group.prepend(title);
@@ -25759,13 +25885,14 @@ function annotateNotes(svg2, meta) {
25759
25885
  const boxes = blockBoxes(svg2);
25760
25886
  for (const { els, name, fromLabel } of labels) {
25761
25887
  const el = els[0];
25762
- const firstTarget = meta.anchors?.find((a) => a.name === name)?.firstTarget;
25888
+ const anchor = meta.anchors?.find((a) => a.name === name);
25889
+ const firstTarget = anchor?.firstTarget;
25763
25890
  for (const e of els) {
25764
25891
  if (firstTarget !== void 0) {
25765
25892
  e.setAttribute("data-seqnotes-first-target", firstTarget);
25766
25893
  }
25767
25894
  }
25768
- if (notes.some((n) => n.goto === name)) {
25895
+ if (notes.some((n) => n.goto === name) || anchor?.jumpedFrom) {
25769
25896
  focusable(el, name);
25770
25897
  }
25771
25898
  const r = sectionRect(boxes, el, fromLabel);
@@ -25791,6 +25918,17 @@ function setupNoteJumps(root, { scroll, pin, signal }) {
25791
25918
  let hovered = [];
25792
25919
  const svgOf = (el) => el.closest("svg");
25793
25920
  const byAttr = (svg2, attr, name) => Array.from(svg2.querySelectorAll(`[${attr}="${CSS.escape(name)}"]`));
25921
+ const targetSvg = (note) => {
25922
+ const other = note.getAttribute("data-seqnotes-goto-diagram");
25923
+ return other === null ? svgOf(note) : root.querySelector(`svg[data-seqnotes-diagram="${CSS.escape(other)}"]`);
25924
+ };
25925
+ const notesTo = (svg2, name) => {
25926
+ const id = svg2.getAttribute("data-seqnotes-diagram");
25927
+ return byAttr(root, "data-seqnotes-goto", name).filter((n) => {
25928
+ const other = n.getAttribute("data-seqnotes-goto-diagram");
25929
+ return other === null ? svgOf(n) === svg2 : other === id;
25930
+ });
25931
+ };
25794
25932
  function clearHover() {
25795
25933
  hovered.forEach((el) => el.classList.remove(HOVER));
25796
25934
  hovered = [];
@@ -25851,22 +25989,26 @@ function setupNoteJumps(root, { scroll, pin, signal }) {
25851
25989
  }
25852
25990
  }
25853
25991
  function jump(from, keyboard) {
25854
- const svg2 = svgOf(from);
25992
+ const svg2 = targetSvg(from);
25855
25993
  const name = from.getAttribute("data-seqnotes-goto");
25856
25994
  const anchor = svg2 && name !== null ? byAttr(svg2, "data-seqnotes-anchor", name)[0] : void 0;
25857
25995
  if (!svg2 || name === null || !anchor) {
25858
25996
  return;
25859
25997
  }
25998
+ const target = anchor.getAttribute("data-seqnotes-first-target");
25999
+ const pair = anchor.closest(".seqnotes-pair");
26000
+ const sideBySide = pair !== null && isSideBySide(pair);
26001
+ if (sideBySide && svg2 !== svgOf(from)) {
26002
+ scroll.reveal(pair, "start", "auto");
26003
+ }
25860
26004
  scrollColumnTo(anchor, true, scroll);
25861
26005
  const branch = byAttr(svg2, "data-seqnotes-branch", name)[0];
25862
26006
  flash(branch ?? anchor);
25863
26007
  if (branch) {
25864
26008
  flash(anchor);
25865
26009
  }
25866
- const target = anchor.getAttribute("data-seqnotes-first-target");
25867
- const pair = anchor.closest(".seqnotes-pair");
25868
26010
  if (target !== null && pair) {
25869
- pin({ pair, target, kind: "message" }, isSideBySide(pair));
26011
+ pin({ pair, target, kind: "message" }, sideBySide);
25870
26012
  }
25871
26013
  showBack(anchor, from);
25872
26014
  if (keyboard) {
@@ -25879,7 +26021,7 @@ function setupNoteJumps(root, { scroll, pin, signal }) {
25879
26021
  if (!svg2 || name === null) {
25880
26022
  return;
25881
26023
  }
25882
- const notes = byAttr(svg2, "data-seqnotes-goto", name);
26024
+ const notes = notesTo(svg2, name);
25883
26025
  if (notes.length === 0) {
25884
26026
  return;
25885
26027
  }
@@ -25911,8 +26053,9 @@ function setupNoteJumps(root, { scroll, pin, signal }) {
25911
26053
  }
25912
26054
  const goto = el.getAttribute("data-seqnotes-goto");
25913
26055
  const name = goto ?? el.getAttribute("data-seqnotes-anchor");
25914
- const related = [...byAttr(svg2, "data-seqnotes-anchor", name), ...goto !== null ? [] : byAttr(svg2, "data-seqnotes-goto", name)];
25915
- hovered = [el, ...related, ...byAttr(svg2, "data-seqnotes-branch", name)];
26056
+ const labelSvg = goto !== null ? targetSvg(el) : svg2;
26057
+ const related = labelSvg ? [...byAttr(labelSvg, "data-seqnotes-anchor", name), ...byAttr(labelSvg, "data-seqnotes-branch", name)] : [];
26058
+ hovered = [el, ...related, ...goto !== null ? [] : notesTo(svg2, name)];
25916
26059
  hovered.forEach((r) => r.classList.add(HOVER));
25917
26060
  },
25918
26061
  { signal }
@@ -26338,8 +26481,13 @@ ${source}`;
26338
26481
  } else {
26339
26482
  const unused = [...meta.messages];
26340
26483
  assigned = groups.map((group) => {
26341
- const label = normalizeLabel(group.slice(0, -1).map((t) => t.textContent ?? "").join(" "));
26342
- const i = unused.findIndex((m) => normalizeLabel(m.text) === label);
26484
+ const lines = group.slice(0, -1).map((t) => t.textContent ?? "");
26485
+ const label = normalizeLabel(lines.join(" "));
26486
+ const compact = compactLabel(lines.join(""));
26487
+ let i = unused.findIndex((m) => normalizeLabel(m.text) === label);
26488
+ if (i < 0) {
26489
+ i = unused.findIndex((m) => compactLabel(m.text) === compact);
26490
+ }
26343
26491
  return i >= 0 ? unused.splice(i, 1)[0] : void 0;
26344
26492
  });
26345
26493
  }
@@ -27276,7 +27424,7 @@ function fetchFrom(baseUrl) {
27276
27424
  }
27277
27425
  };
27278
27426
  }
27279
- var CONTENT_OPTIONS = ["markdown", "baseUrl", "readFile", "resolveResource", "frontMatter", "headingNumbers"];
27427
+ var CONTENT_OPTIONS = ["markdown", "baseUrl", "readFile", "resolveResource", "frontMatter", "headingNumbers", "messageWrapWidth"];
27280
27428
  var VIEW_OPTIONS = ["documentId", "splitMinWidth", "toc", "diagramLook", "limitContentWidth", "stickyTableHeader", "tableTreeHighlight"];
27281
27429
  function createViewer(container, options) {
27282
27430
  let current = { ...options };
@@ -27364,7 +27512,7 @@ function createViewer(container, options) {
27364
27512
  return;
27365
27513
  }
27366
27514
  pending = false;
27367
- html2 = renderDocument(md, markdown, { t, frontMatter: current.frontMatter, headingNumbers: current.headingNumbers, wireframes: wireframes2, resolveResource });
27515
+ html2 = renderDocument(md, markdown, { t, frontMatter: current.frontMatter, headingNumbers: current.headingNumbers, messageWrapWidth: current.messageWrapWidth, wireframes: wireframes2, resolveResource });
27368
27516
  await show(html2);
27369
27517
  }
27370
27518
  rendering = render();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markdown-design-doc-viewer-embed",
3
- "version": "1.5.1",
3
+ "version": "1.5.3",
4
4
  "description": "The viewer of Markdown Design Doc Viewer to embed in a web app (React or not): design documents in Markdown with their mermaid sequence diagrams, flowcharts, ER and state diagrams and wireframes linked to the steps after them.",
5
5
  "license": "MIT",
6
6
  "repository": {
package/react.js CHANGED
@@ -26,14 +26,14 @@ var DesignDocViewer = forwardRef(function DesignDocViewer2({ className, style, .
26
26
  viewer.current = void 0;
27
27
  };
28
28
  }, [options.lang]);
29
- const { markdown, documentId, baseUrl, readFile, resolveResource, theme, diagramLook, splitMinWidth, toc, limitContentWidth, stickyTableHeader, tableTreeHighlight, frontMatter, headingNumbers } = options;
29
+ const { markdown, documentId, baseUrl, readFile, resolveResource, theme, diagramLook, splitMinWidth, toc, limitContentWidth, stickyTableHeader, tableTreeHighlight, frontMatter, headingNumbers, messageWrapWidth } = options;
30
30
  useEffect(() => {
31
31
  if (created.current) {
32
32
  created.current = false;
33
33
  return;
34
34
  }
35
35
  void viewer.current?.update(viewerOptions());
36
- }, [options.lang, markdown, documentId, baseUrl, readFile, resolveResource, theme, diagramLook, splitMinWidth, toc, limitContentWidth, stickyTableHeader, tableTreeHighlight, frontMatter, headingNumbers, revealing]);
36
+ }, [options.lang, markdown, documentId, baseUrl, readFile, resolveResource, theme, diagramLook, splitMinWidth, toc, limitContentWidth, stickyTableHeader, tableTreeHighlight, frontMatter, headingNumbers, messageWrapWidth, revealing]);
37
37
  useImperativeHandle(ref, () => ({
38
38
  scrollToLine: (line) => viewer.current?.scrollToLine(line),
39
39
  markLine: (line) => viewer.current?.markLine(line)
@@ -40,6 +40,11 @@ export interface ViewerOptions {
40
40
  frontMatter?: boolean;
41
41
  /** Shows the `autonumber` numbers on the linked headings. true by default. */
42
42
  headingNumbers?: boolean;
43
+ /**
44
+ * Breaks the labels of the arrows of the sequence diagrams into lines at this many characters (a full-width one
45
+ * counts as 2). 0 does not break them. 30 by default.
46
+ */
47
+ messageWrapWidth?: number;
43
48
  /**
44
49
  * Opens a link of the document (other than `#heading`, which the viewer scrolls to). By default, http(s) and mailto
45
50
  * links open in a new tab, and the others do nothing.
package/viewer.css CHANGED
@@ -1107,9 +1107,6 @@ html:has(> body[data-seqnotes-theme=dark]:is(.vscode-light, .vscode-high-contras
1107
1107
  fill: none !important;
1108
1108
  pointer-events: stroke;
1109
1109
  }
1110
- .messageText.seqnotes-linked {
1111
- text-decoration: underline dotted;
1112
- }
1113
1110
  .messageText.seqnotes-active {
1114
1111
  fill: var(--seqnotes-accent) !important;
1115
1112
  font-weight: bold;
@@ -1139,9 +1136,6 @@ text.seqnotes-anchor tspan {
1139
1136
  stroke: var(--seqnotes-accent) !important;
1140
1137
  stroke-dasharray: 5 3;
1141
1138
  }
1142
- .seqnotes-goto :is(text, tspan) {
1143
- text-decoration: underline dotted;
1144
- }
1145
1139
  .seqnotes-goto.seqnotes-jump-hover > rect,
1146
1140
  .seqnotes-note.seqnotes-anchor.seqnotes-jump-hover > rect {
1147
1141
  stroke-width: 3px !important;