@threadlabs/looma 0.31.5 → 0.32.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.
@@ -1,5 +1,5 @@
1
1
  import { n as TABLE_CELL_BACKGROUND_PRESETS } from "./table-backgrounds.js";
2
- import { _ as parseLoomaAttributes, b as splitLoomaFrontmatter, c as LOOMA_CONTAINER_NAMES, d as formatLoomaAttributes, f as loomaCodeFence, g as normalizeLoomaChipTone, h as normalizeLoomaCalloutTone, i as referenceDisplay, l as applyLoomaCodeNotation, m as loomaHeadingSlug, n as LoomaReferencePresentation, p as loomaContainerMarker, r as getReferenceDisplay, s as LOOMA_CHIP_TONES, t as LoomaReference, u as assignLoomaHeadingIds, v as parseLoomaFenceInfo, y as readLoomaAttributes } from "./reference-display.js";
2
+ import { _ as normalizeLoomaChipTone, b as readLoomaAttributes, c as LOOMA_CONTAINER_NAMES, d as assignLoomaHeadingIds, f as formatLoomaAttributes, g as normalizeLoomaCalloutTone, h as loomaHeadingSlug, i as referenceDisplay, l as LOOMA_MENTION_HANDLE, m as loomaContainerMarker, n as LoomaReferencePresentation, p as loomaCodeFence, r as getReferenceDisplay, s as LOOMA_CHIP_TONES, t as LoomaReference, u as applyLoomaCodeNotation, v as parseLoomaAttributes, x as splitLoomaFrontmatter, y as parseLoomaFenceInfo } from "./reference-display.js";
3
3
  import { Extension, InputRule, Mark, Node as Node$1, PasteRule, callOrReturn, canInsertNode, combineTransactionSteps, escapeForRegEx, findChildren, findChildrenInRange, findParentNodeClosestToPos, getAttributes, getChangedRanges, getExtensionField, getMarksBetween, getText, getTextSerializersFromSchema, isNodeEmpty, isNodeSelection, markInputRule, markPasteRule, mergeAttributes, nodeInputRule, textInputRule, textblockTypeInputRule, wrappingInputRule } from "@tiptap/core";
4
4
  import { NodeSelection, Plugin, PluginKey, Selection, TextSelection } from "@tiptap/pm/state";
5
5
  import { Decoration, DecorationSet } from "@tiptap/pm/view";
@@ -10072,7 +10072,7 @@ function taskLists(state) {
10072
10072
  function directive(state, silent) {
10073
10073
  const { src, pos } = state;
10074
10074
  if (src.charCodeAt(pos) !== 58) return false;
10075
- const name = /^:(chip|mention)\[/.exec(src.slice(pos, pos + 10))?.[1];
10075
+ const name = /^:(chip)\[/.exec(src.slice(pos, pos + 10))?.[1];
10076
10076
  if (!name) return false;
10077
10077
  let label = "";
10078
10078
  let index = pos + name.length + 2;
@@ -10086,7 +10086,6 @@ function directive(state, silent) {
10086
10086
  end: index + 1
10087
10087
  };
10088
10088
  if (!read || read.end > state.posMax) return false;
10089
- if (name === "mention" && typeof read.attributes.id !== "string") return false;
10090
10089
  if (!silent) {
10091
10090
  const token = state.push(`looma_${name}`, "span", 0);
10092
10091
  token.meta = {
@@ -10097,6 +10096,37 @@ function directive(state, silent) {
10097
10096
  state.pos = read.end;
10098
10097
  return true;
10099
10098
  }
10099
+ function mention(state, silent) {
10100
+ const { src, pos } = state;
10101
+ if (src.charCodeAt(pos) !== 64 || pos > 0 && !/\s/u.test(src[pos - 1])) return false;
10102
+ let index = pos + 1;
10103
+ let label = "";
10104
+ if (src[index] === "[") {
10105
+ for (index++; index < state.posMax && src[index] !== "]"; index++) {
10106
+ if (src[index] === "\\" && index + 1 < state.posMax) index++;
10107
+ label += src[index];
10108
+ }
10109
+ if (src[index] !== "]" || !label) return false;
10110
+ index++;
10111
+ } else {
10112
+ label = LOOMA_MENTION_HANDLE.exec(src.slice(index, state.posMax))?.[0] ?? "";
10113
+ if (!label) return false;
10114
+ index += label.length;
10115
+ }
10116
+ let ref = src[index] === "#" ? LOOMA_MENTION_HANDLE.exec(src.slice(index + 1, state.posMax))?.[0] : void 0;
10117
+ if (ref) index += ref.length + 1;
10118
+ const read = src[index] === "{" ? readLoomaAttributes(src, index) : null;
10119
+ if (read && read.end <= state.posMax) {
10120
+ if (typeof read.attributes.ref === "string") ref ??= read.attributes.ref;
10121
+ index = read.end;
10122
+ }
10123
+ if (!silent) state.push("looma_mention", "span", 0).meta = {
10124
+ label,
10125
+ ref
10126
+ };
10127
+ state.pos = index;
10128
+ return true;
10129
+ }
10100
10130
  function inlineText(token) {
10101
10131
  return (token?.children ?? []).map((child) => child.type === "image" ? inlineText(child) : child.content).join("");
10102
10132
  }
@@ -10318,6 +10348,7 @@ function loomaMarkdown$1(md, { codeNotation = "apply" } = {}) {
10318
10348
  "list"
10319
10349
  ] });
10320
10350
  md.inline.ruler.before("link", "looma_directive", directive);
10351
+ md.inline.ruler.before("link", "looma_mention", mention);
10321
10352
  md.inline.ruler.before("link", "looma_footnote_ref", footnoteReference);
10322
10353
  md.core.ruler.after("block", "looma_task_lists", taskLists);
10323
10354
  md.core.ruler.before("inline", "looma_alerts", alerts);
@@ -10367,9 +10398,8 @@ function loomaMarkdown$1(md, { codeNotation = "apply" } = {}) {
10367
10398
  return `<span data-looma-chip="" data-label="${escape(label)}" data-color="${tone}"${label ? "" : " data-placeholder=\"\""}>${escape(label)}</span>`;
10368
10399
  };
10369
10400
  rules.looma_mention = (tokens, index) => {
10370
- const { label, attributes } = tokens[index].meta;
10371
- const id = String(attributes.id);
10372
- return `<span data-type="mention" class="looma-mention" data-id="${escape(id)}" data-label="${escape(label || id)}">@${escape(label || id)}</span>`;
10401
+ const { label, ref } = tokens[index].meta;
10402
+ return `<span data-type="mention" class="looma-mention"${ref === void 0 ? "" : ` data-id="${escape(ref)}"`} data-label="${escape(label)}">@${escape(label)}</span>`;
10373
10403
  };
10374
10404
  const code = (content, info) => {
10375
10405
  const { language, meta } = parseLoomaFenceInfo(info);
@@ -10525,8 +10555,9 @@ var NODES = {
10525
10555
  state.write(`:chip[${label(String(node.attrs.label ?? ""))}]${formatLoomaAttributes({ tone: tone !== "neutral" ? tone : null })}`);
10526
10556
  },
10527
10557
  mention: (state, node) => {
10528
- const id = String(node.attrs.id ?? "");
10529
- state.write(`:mention[${label(String(node.attrs.label ?? id))}]${formatLoomaAttributes({ id }, { hashId: false })}`);
10558
+ const id = node.attrs.id == null ? "" : String(node.attrs.id);
10559
+ const reference = !id ? "" : LOOMA_MENTION_HANDLE.exec(id)?.[0] === id ? `#${id}` : formatLoomaAttributes({ ref: id });
10560
+ state.write(`@[${label(String(node.attrs.label || id))}]${reference}`);
10530
10561
  },
10531
10562
  loomaReference: (state, node) => {
10532
10563
  const wrapper = document.createElement("span");
@@ -44,6 +44,11 @@ function normalizeLoomaChipTone(value) {
44
44
  return LOOMA_CHIP_TONES.includes(value) ? value : "neutral";
45
45
  }
46
46
  /**
47
+ * A mention handle, as `@handle` and the `#ref` of `@[Label]#ref` spell it: a letter, number or
48
+ * underscore, then letters, marks, numbers, underscores and hyphens.
49
+ */
50
+ var LOOMA_MENTION_HANDLE = /^[\p{L}\p{N}_][\p{L}\p{M}\p{N}_-]*/u;
51
+ /**
47
52
  * Names that open a `:::` container, matched without regard to case. A container with any other
48
53
  * name is ordinary text.
49
54
  */
@@ -445,4 +450,4 @@ var LoomaReferencePresentation = Extension.create({
445
450
  }
446
451
  });
447
452
  //#endregion
448
- export { parseLoomaAttributes as _, setReferenceDisplay as a, splitLoomaFrontmatter as b, LOOMA_CONTAINER_NAMES as c, formatLoomaAttributes as d, loomaCodeFence as f, normalizeLoomaChipTone as g, normalizeLoomaCalloutTone as h, referenceDisplay as i, applyLoomaCodeNotation as l, loomaHeadingSlug as m, LoomaReferencePresentation as n, LOOMA_CALLOUT_TONES as o, loomaContainerMarker as p, getReferenceDisplay as r, LOOMA_CHIP_TONES as s, LoomaReference as t, assignLoomaHeadingIds as u, parseLoomaFenceInfo as v, readLoomaAttributes as y };
453
+ export { normalizeLoomaChipTone as _, setReferenceDisplay as a, readLoomaAttributes as b, LOOMA_CONTAINER_NAMES as c, assignLoomaHeadingIds as d, formatLoomaAttributes as f, normalizeLoomaCalloutTone as g, loomaHeadingSlug as h, referenceDisplay as i, LOOMA_MENTION_HANDLE as l, loomaContainerMarker as m, LoomaReferencePresentation as n, LOOMA_CALLOUT_TONES as o, loomaCodeFence as p, getReferenceDisplay as r, LOOMA_CHIP_TONES as s, LoomaReference as t, applyLoomaCodeNotation as u, parseLoomaAttributes as v, splitLoomaFrontmatter as x, parseLoomaFenceInfo as y };
@@ -1,4 +1,4 @@
1
- import { m as loomaHeadingSlug, o as LOOMA_CALLOUT_TONES, r as getReferenceDisplay, s as LOOMA_CHIP_TONES } from "./chunks/reference-display.js";
1
+ import { h as loomaHeadingSlug, o as LOOMA_CALLOUT_TONES, r as getReferenceDisplay, s as LOOMA_CHIP_TONES } from "./chunks/reference-display.js";
2
2
  import { parse, stringify } from "expressmark";
3
3
  //#region src/editor/expressmark.ts
4
4
  /**
@@ -96,7 +96,7 @@ var files = /* #__PURE__ */ Object.assign({
96
96
  "../../markdown-fixtures/lists/blocks.html": "<ul>\n<li>One\n<ul>\n<li>Nested</li>\n</ul>\n</li>\n<li>Two</li>\n</ul>\n<ol start=\"3\">\n<li>Three</li>\n<li>Four</li>\n</ol>\n<blockquote>\n<p>Quoted</p>\n</blockquote>\n<hr>\n",
97
97
  "../../markdown-fixtures/lists/blocks.md": "- One\n - Nested\n- Two\n\n3. Three\n4. Four\n\n> Quoted\n\n---\n",
98
98
  "../../markdown-fixtures/mentions/person.html": "<p>Thanks, <span data-type=\"mention\" class=\"looma-mention\" data-id=\"u1\" data-label=\"Ada Lovelace\">@Ada Lovelace</span>.</p>\n",
99
- "../../markdown-fixtures/mentions/person.md": "Thanks, :mention[Ada Lovelace]{id=u1}.\n",
99
+ "../../markdown-fixtures/mentions/person.md": "Thanks, @[Ada Lovelace]#u1.\n",
100
100
  "../../markdown-fixtures/tables/gfm.html": "<table>\n<thead>\n<tr>\n<th>Package</th>\n<th style=\"text-align:right\">Version</th>\n<th style=\"text-align:center\">Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>looma</td>\n<td style=\"text-align:right\">0.28</td>\n<td style=\"text-align:center\">Components</td>\n</tr>\n</tbody>\n</table>\n",
101
101
  "../../markdown-fixtures/tables/gfm.md": "| Package | Version | Notes |\n| --- | ---: | :---: |\n| looma | 0.28 | Components |\n",
102
102
  "../../markdown-fixtures/tables/left-aligned.html": "<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">Name</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">a | b</td>\n<td><code>x | y</code></td>\n</tr>\n</tbody>\n</table>\n",
@@ -32,6 +32,11 @@ export type LoomaChipTone = (typeof LOOMA_CHIP_TONES)[number];
32
32
  * @failure Unknown values become `neutral`.
33
33
  */
34
34
  export declare function normalizeLoomaChipTone(value: unknown): LoomaChipTone;
35
+ /**
36
+ * A mention handle, as `@handle` and the `#ref` of `@[Label]#ref` spell it: a letter, number or
37
+ * underscore, then letters, marks, numbers, underscores and hyphens.
38
+ */
39
+ export declare const LOOMA_MENTION_HANDLE: RegExp;
35
40
  /**
36
41
  * Names that open a `:::` container, matched without regard to case. A container with any other
37
42
  * name is ordinary text.
package/markdown/index.js CHANGED
@@ -66,6 +66,11 @@ function normalizeLoomaChipTone(value) {
66
66
  return LOOMA_CHIP_TONES.includes(value) ? value : "neutral";
67
67
  }
68
68
  /**
69
+ * A mention handle, as `@handle` and the `#ref` of `@[Label]#ref` spell it: a letter, number or
70
+ * underscore, then letters, marks, numbers, underscores and hyphens.
71
+ */
72
+ var LOOMA_MENTION_HANDLE = /^[\p{L}\p{N}_][\p{L}\p{M}\p{N}_-]*/u;
73
+ /**
69
74
  * Names that open a `:::` container, matched without regard to case. A container with any other
70
75
  * name is ordinary text.
71
76
  */
@@ -263,4 +268,4 @@ function loomaCodeFence(code) {
263
268
  return "`".repeat(Math.max(3, longest + 1));
264
269
  }
265
270
  //#endregion
266
- export { LOOMA_BADGE_TONES, LOOMA_CALLOUT_TONES, LOOMA_CALLOUT_TONE_ALIASES, LOOMA_CHIP_TONES, LOOMA_CONTAINER_NAMES, LOOMA_MEANING_TONES, applyLoomaCodeNotation, assignLoomaHeadingIds, formatLoomaAttributes, loomaCodeFence, loomaContainerMarker, loomaHeadingSlug, normalizeLoomaCalloutTone, normalizeLoomaChipTone, parseLoomaAttributes, parseLoomaFenceInfo, readLoomaAttributes, splitLoomaFrontmatter };
271
+ export { LOOMA_BADGE_TONES, LOOMA_CALLOUT_TONES, LOOMA_CALLOUT_TONE_ALIASES, LOOMA_CHIP_TONES, LOOMA_CONTAINER_NAMES, LOOMA_MEANING_TONES, LOOMA_MENTION_HANDLE, applyLoomaCodeNotation, assignLoomaHeadingIds, formatLoomaAttributes, loomaCodeFence, loomaContainerMarker, loomaHeadingSlug, normalizeLoomaCalloutTone, normalizeLoomaChipTone, parseLoomaAttributes, parseLoomaFenceInfo, readLoomaAttributes, splitLoomaFrontmatter };
@@ -1,4 +1,4 @@
1
- import { LOOMA_CONTAINER_NAMES, applyLoomaCodeNotation, assignLoomaHeadingIds, normalizeLoomaCalloutTone, normalizeLoomaChipTone, parseLoomaAttributes, parseLoomaFenceInfo, readLoomaAttributes, splitLoomaFrontmatter } from "./index.js";
1
+ import { LOOMA_CONTAINER_NAMES, LOOMA_MENTION_HANDLE, applyLoomaCodeNotation, assignLoomaHeadingIds, normalizeLoomaCalloutTone, normalizeLoomaChipTone, parseLoomaAttributes, parseLoomaFenceInfo, readLoomaAttributes, splitLoomaFrontmatter } from "./index.js";
2
2
  import MarkdownIt from "markdown-it";
3
3
  //#region src/markdown/markdown-it.ts
4
4
  var CONTAINER_OPEN = /^(:{3,})[ \t]*([A-Za-z][\w-]*)(?:[ \t]+(.*?))?[ \t]*$/;
@@ -210,7 +210,7 @@ function taskLists(state) {
210
210
  function directive(state, silent) {
211
211
  const { src, pos } = state;
212
212
  if (src.charCodeAt(pos) !== 58) return false;
213
- const name = /^:(chip|mention)\[/.exec(src.slice(pos, pos + 10))?.[1];
213
+ const name = /^:(chip)\[/.exec(src.slice(pos, pos + 10))?.[1];
214
214
  if (!name) return false;
215
215
  let label = "";
216
216
  let index = pos + name.length + 2;
@@ -224,7 +224,6 @@ function directive(state, silent) {
224
224
  end: index + 1
225
225
  };
226
226
  if (!read || read.end > state.posMax) return false;
227
- if (name === "mention" && typeof read.attributes.id !== "string") return false;
228
227
  if (!silent) {
229
228
  const token = state.push(`looma_${name}`, "span", 0);
230
229
  token.meta = {
@@ -235,6 +234,37 @@ function directive(state, silent) {
235
234
  state.pos = read.end;
236
235
  return true;
237
236
  }
237
+ function mention(state, silent) {
238
+ const { src, pos } = state;
239
+ if (src.charCodeAt(pos) !== 64 || pos > 0 && !/\s/u.test(src[pos - 1])) return false;
240
+ let index = pos + 1;
241
+ let label = "";
242
+ if (src[index] === "[") {
243
+ for (index++; index < state.posMax && src[index] !== "]"; index++) {
244
+ if (src[index] === "\\" && index + 1 < state.posMax) index++;
245
+ label += src[index];
246
+ }
247
+ if (src[index] !== "]" || !label) return false;
248
+ index++;
249
+ } else {
250
+ label = LOOMA_MENTION_HANDLE.exec(src.slice(index, state.posMax))?.[0] ?? "";
251
+ if (!label) return false;
252
+ index += label.length;
253
+ }
254
+ let ref = src[index] === "#" ? LOOMA_MENTION_HANDLE.exec(src.slice(index + 1, state.posMax))?.[0] : void 0;
255
+ if (ref) index += ref.length + 1;
256
+ const read = src[index] === "{" ? readLoomaAttributes(src, index) : null;
257
+ if (read && read.end <= state.posMax) {
258
+ if (typeof read.attributes.ref === "string") ref ??= read.attributes.ref;
259
+ index = read.end;
260
+ }
261
+ if (!silent) state.push("looma_mention", "span", 0).meta = {
262
+ label,
263
+ ref
264
+ };
265
+ state.pos = index;
266
+ return true;
267
+ }
238
268
  function inlineText(token) {
239
269
  return (token?.children ?? []).map((child) => child.type === "image" ? inlineText(child) : child.content).join("");
240
270
  }
@@ -456,6 +486,7 @@ function loomaMarkdown(md, { codeNotation = "apply" } = {}) {
456
486
  "list"
457
487
  ] });
458
488
  md.inline.ruler.before("link", "looma_directive", directive);
489
+ md.inline.ruler.before("link", "looma_mention", mention);
459
490
  md.inline.ruler.before("link", "looma_footnote_ref", footnoteReference);
460
491
  md.core.ruler.after("block", "looma_task_lists", taskLists);
461
492
  md.core.ruler.before("inline", "looma_alerts", alerts);
@@ -505,9 +536,8 @@ function loomaMarkdown(md, { codeNotation = "apply" } = {}) {
505
536
  return `<span data-looma-chip="" data-label="${escape(label)}" data-color="${tone}"${label ? "" : " data-placeholder=\"\""}>${escape(label)}</span>`;
506
537
  };
507
538
  rules.looma_mention = (tokens, index) => {
508
- const { label, attributes } = tokens[index].meta;
509
- const id = String(attributes.id);
510
- return `<span data-type="mention" class="looma-mention" data-id="${escape(id)}" data-label="${escape(label || id)}">@${escape(label || id)}</span>`;
539
+ const { label, ref } = tokens[index].meta;
540
+ return `<span data-type="mention" class="looma-mention"${ref === void 0 ? "" : ` data-id="${escape(ref)}"`} data-label="${escape(label)}">@${escape(label)}</span>`;
511
541
  };
512
542
  const code = (content, info) => {
513
543
  const { language, meta } = parseLoomaFenceInfo(info);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.31.5",
3
+ "version": "0.32.0",
4
4
  "type": "module",
5
5
  "description": "Looma components as HTML, Vue, and plain DOM, with design tokens.",
6
6
  "license": "MIT",