@matter/general 0.13.1-alpha.0-20250508-047aa0277 → 0.13.1-alpha.0-20250509-28e1567e1

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.
@@ -144,16 +144,16 @@ export declare const Transaction: {
144
144
  */
145
145
  act<T>(via: string, actor: (transaction: Transaction) => MaybePromise<T>): MaybePromise<T>;
146
146
  ReadOnly: {
147
- "__#15412@#participants": Set<Participant>;
148
- "__#15412@#roles": Map<{}, Participant>;
149
- "__#15412@#resources": Set<Resource>;
150
- "__#15412@#status": Status;
151
- "__#15412@#waitingOn"?: Iterable<Transaction>;
152
- "__#15412@#via": string;
153
- "__#15412@#shared"?: import("../index.js").Observable<[]>;
154
- "__#15412@#closed"?: import("../index.js").Observable<[]>;
155
- "__#15412@#isAsync": boolean;
156
- "__#15412@#reportingLocks": boolean;
147
+ "__#15442@#participants": Set<Participant>;
148
+ "__#15442@#roles": Map<{}, Participant>;
149
+ "__#15442@#resources": Set<Resource>;
150
+ "__#15442@#status": Status;
151
+ "__#15442@#waitingOn"?: Iterable<Transaction>;
152
+ "__#15442@#via": string;
153
+ "__#15442@#shared"?: import("../index.js").Observable<[]>;
154
+ "__#15442@#closed"?: import("../index.js").Observable<[]>;
155
+ "__#15442@#isAsync": boolean;
156
+ "__#15442@#reportingLocks": boolean;
157
157
  close(): void;
158
158
  readonly via: string;
159
159
  readonly status: Status;
@@ -175,15 +175,15 @@ export declare const Transaction: {
175
175
  waitFor(others: Set<Transaction>): Promise<void>;
176
176
  toString(): string;
177
177
  treatAsSlow(): void;
178
- "__#15412@#finalize"(status: Status, why: string, finalizer: () => MaybePromise): Promise<void> | undefined;
179
- "__#15412@#executePreCommit"(): MaybePromise<void>;
180
- "__#15412@#executeCommit"(): MaybePromise;
181
- "__#15412@#executeCommit1"(): MaybePromise;
182
- "__#15412@#executeCommit2"(): Promise<void> | undefined;
183
- "__#15412@#executePostCommit"(participants: Participant[]): MaybePromise;
184
- "__#15412@#executeRollback"(): Promise<void> | undefined;
185
- "__#15412@#locksChanged"(resources: Set<Resource>, how?: string): void;
186
- "__#15412@#assertAvailable"(): void;
178
+ "__#15442@#finalize"(status: Status, why: string, finalizer: () => MaybePromise): Promise<void> | undefined;
179
+ "__#15442@#executePreCommit"(): MaybePromise<void>;
180
+ "__#15442@#executeCommit"(): MaybePromise;
181
+ "__#15442@#executeCommit1"(): MaybePromise;
182
+ "__#15442@#executeCommit2"(): Promise<void> | undefined;
183
+ "__#15442@#executePostCommit"(participants: Participant[]): MaybePromise;
184
+ "__#15442@#executeRollback"(): Promise<void> | undefined;
185
+ "__#15442@#locksChanged"(resources: Set<Resource>, how?: string): void;
186
+ "__#15442@#assertAvailable"(): void;
187
187
  };
188
188
  Status: typeof Status;
189
189
  Resource: typeof Resource;
@@ -8,7 +8,30 @@ export { camelize, describeList, serialize } from "./String.js";
8
8
  * Performs word wrap. Input is assumed to be a series of paragraphs separated by a newline. Output is an array of
9
9
  * formatted lines.
10
10
  *
11
- * Contains specialized support for lists, ESDoc directives ans ANSI escape codes.
11
+ * Contains specialized support for lists, ESDoc directives and ANSI escape codes.
12
12
  */
13
13
  export declare function FormattedText(text: string, width?: number): string[];
14
+ /**
15
+ * Types of things we consider "blocks". Most blocks are lists but we also support markdown-style quotes prefixed with
16
+ * ">".
17
+ */
18
+ export declare enum BlockKind {
19
+ Simple = "simple",
20
+ Bullet1 = "\u2022",
21
+ Bullet2 = "\u25E6",
22
+ Bullet3 = "\u25AA",
23
+ Bullet4 = "\u25CB",
24
+ Bullet5 = "\u25CF",
25
+ Bullet6 = "\u2023",
26
+ Bullet7 = "\u2043",
27
+ Bullet8 = "\u25D8",
28
+ Quote = ">",
29
+ Number = "number",
30
+ LowerAlpha = "alpha",
31
+ UpperAlpha = "ALPHA",
32
+ LowerRoman = "roman",
33
+ UpperRoman = "ROMAN"
34
+ }
35
+ export declare const Bullets: BlockKind[];
36
+ export declare function looksLikeListItem(text: string): boolean;
14
37
  //# sourceMappingURL=FormattedText.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FormattedText.d.ts","sourceRoot":"","sources":["../../../src/util/FormattedText.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEhE;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAM,YAGtD"}
1
+ {"version":3,"file":"FormattedText.d.ts","sourceRoot":"","sources":["../../../src/util/FormattedText.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEhE;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAM,YAGtD;AAED;;;GAGG;AACH,oBAAY,SAAS;IACjB,MAAM,WAAW;IACjB,OAAO,WAAM;IACb,OAAO,WAAM;IACb,OAAO,WAAM;IACb,OAAO,WAAM;IACb,OAAO,WAAM;IACb,OAAO,WAAM;IACb,OAAO,WAAM;IACb,OAAO,WAAM;IACb,KAAK,MAAM;IACX,MAAM,WAAW;IACjB,UAAU,UAAU;IACpB,UAAU,UAAU;IACpB,UAAU,UAAU;IACpB,UAAU,UAAU;CACvB;AAED,eAAO,MAAM,OAAO,aAEU,CAAC;AAK/B,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,WAE7C"}
@@ -18,9 +18,12 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var FormattedText_exports = {};
20
20
  __export(FormattedText_exports, {
21
+ BlockKind: () => BlockKind,
22
+ Bullets: () => Bullets,
21
23
  FormattedText: () => FormattedText,
22
24
  camelize: () => import_String.camelize,
23
25
  describeList: () => import_String.describeList,
26
+ looksLikeListItem: () => looksLikeListItem,
24
27
  serialize: () => import_String.serialize
25
28
  });
26
29
  module.exports = __toCommonJS(FormattedText_exports);
@@ -30,107 +33,97 @@ var import_String = require("./String.js");
30
33
  * Copyright 2022-2025 Matter.js Authors
31
34
  * SPDX-License-Identifier: Apache-2.0
32
35
  */
33
- const LIST_INDENT = 2;
36
+ const INDENT = " ";
34
37
  function FormattedText(text, width = 120) {
35
38
  const structure = detectStructure(text);
36
- return formatStructure(structure, width);
39
+ return formatBlock(structure, width);
37
40
  }
38
- var ListType = /* @__PURE__ */ ((ListType2) => {
39
- ListType2["Bullet1"] = "\u2022";
40
- ListType2["Bullet2"] = "\u25E6";
41
- ListType2["Bullet3"] = "\u25AA";
42
- ListType2["Bullet4"] = "\u25CB";
43
- ListType2["Bullet5"] = "\u25CF";
44
- ListType2["Bullet6"] = "\u2023";
45
- ListType2["Bullet7"] = "\u2043";
46
- ListType2["Bullet8"] = "\u25D8";
47
- ListType2["Number"] = "number";
48
- ListType2["LowerAlpha"] = "alpha";
49
- ListType2["UpperAlpha"] = "ALPHA";
50
- ListType2["LowerRoman"] = "roman";
51
- ListType2["UpperRoman"] = "ROMAN";
52
- return ListType2;
53
- })(ListType || {});
54
- function detectList(text, listState) {
55
- function enterList(listType) {
56
- const existing = listState.indexOf(listType);
57
- if (existing == -1) {
58
- listState.push(listType);
59
- } else {
60
- listState.length = existing + 1;
61
- }
41
+ var BlockKind = /* @__PURE__ */ ((BlockKind2) => {
42
+ BlockKind2["Simple"] = "simple";
43
+ BlockKind2["Bullet1"] = "\u2022";
44
+ BlockKind2["Bullet2"] = "\u25E6";
45
+ BlockKind2["Bullet3"] = "\u25AA";
46
+ BlockKind2["Bullet4"] = "\u25CB";
47
+ BlockKind2["Bullet5"] = "\u25CF";
48
+ BlockKind2["Bullet6"] = "\u2023";
49
+ BlockKind2["Bullet7"] = "\u2043";
50
+ BlockKind2["Bullet8"] = "\u25D8";
51
+ BlockKind2["Quote"] = ">";
52
+ BlockKind2["Number"] = "number";
53
+ BlockKind2["LowerAlpha"] = "alpha";
54
+ BlockKind2["UpperAlpha"] = "ALPHA";
55
+ BlockKind2["LowerRoman"] = "roman";
56
+ BlockKind2["UpperRoman"] = "ROMAN";
57
+ return BlockKind2;
58
+ })(BlockKind || {});
59
+ const Bullets = Object.entries(BlockKind).filter(([key]) => key.startsWith("Bullet")).map(([, value]) => value);
60
+ const enumTest = "(?:\\d+|[ivx]+|[a-z])\\.";
61
+ const listItemTest = new RegExp(`^(?:[${Bullets.join("")}]|${enumTest})\\s`, "i");
62
+ function looksLikeListItem(text) {
63
+ return !!listItemTest.exec(text);
64
+ }
65
+ const Empty = {
66
+ kind: "simple" /* Simple */,
67
+ indentWidth: 0,
68
+ entries: []
69
+ };
70
+ function detectBlock(text, breadcrumb) {
71
+ const match = text.match(/^\s*(\S+)/);
72
+ if (!match) {
73
+ return;
62
74
  }
63
- for (const value of Object.values(ListType)) {
64
- if (text[0] === value && text[1] === " ") {
65
- enterList(text[0]);
75
+ const [, marker] = match;
76
+ if (Bullets.includes(marker) || marker === ">" /* Quote */) {
77
+ enterBlock(marker);
78
+ return;
79
+ }
80
+ if (detectEnumeration(/^\d+\.$/, "1", "number" /* Number */)) return;
81
+ if (detectEnumeration(/^[ivx]+\.$/, "i", "roman" /* LowerRoman */)) return;
82
+ if (detectEnumeration(/^[IVX]+\.$/, "I", "ROMAN" /* UpperRoman */)) return;
83
+ if (detectEnumeration(/^[a-z]+\.$/, "a", "alpha" /* LowerAlpha */)) return;
84
+ if (detectEnumeration(/^[A-Z]+\.$/, "A", "ALPHA" /* UpperAlpha */)) return;
85
+ breadcrumb.length = 1;
86
+ function enterBlock(kind) {
87
+ const level = breadcrumb.findIndex((entry) => entry.kind === kind);
88
+ if (level !== -1) {
89
+ breadcrumb.length = level + 1;
66
90
  return;
67
91
  }
92
+ const block = {
93
+ kind,
94
+ indentWidth: (breadcrumb[breadcrumb.length - 1]?.indentWidth ?? 0) + kind === ">" /* Quote */ ? 0 : 2,
95
+ entries: []
96
+ };
97
+ breadcrumb[breadcrumb.length - 1].entries.push(block);
98
+ breadcrumb.push(block);
68
99
  }
69
- function detectEnumeration(test, listType, first) {
70
- if (!text.match(test)) {
100
+ function detectEnumeration(test, startsWith, kind) {
101
+ if (!marker.match(test)) {
71
102
  return false;
72
103
  }
73
- if (listState.indexOf(listType) != -1 || text.startsWith(`${first}.`)) {
74
- enterList(listType);
75
- return true;
104
+ if (!breadcrumb.find((block) => block.kind === kind)) {
105
+ if (marker !== `${startsWith}.`) {
106
+ return false;
107
+ }
76
108
  }
77
- return false;
109
+ enterBlock(kind);
110
+ return true;
78
111
  }
79
- if (detectEnumeration(/^\d+\./, "number" /* Number */, "1")) return;
80
- if (detectEnumeration(/^[ivx]+\./, "roman" /* LowerRoman */, "i")) return;
81
- if (detectEnumeration(/^[IVX]+\./, "ROMAN" /* UpperRoman */, "I")) return;
82
- if (detectEnumeration(/^[a-z]+\./, "alpha" /* LowerAlpha */, "a")) return;
83
- if (detectEnumeration(/^[A-Z]+\./, "ALPHA" /* UpperAlpha */, "A")) return;
84
- listState.length = 0;
85
- }
86
- function extractPrefix(text) {
87
- const match = text.match(/^(\S+)\s+($|\S.*$)/);
88
- if (match) {
89
- return { prefix: match[1], text: match[2] };
90
- }
91
- return { prefix: text, text: "" };
92
112
  }
93
113
  function detectStructure(text) {
94
- if (text == "") {
95
- return { prefixWidth: 0, entries: [] };
114
+ const lines = text.split(/\n+/).map((line) => line.trimEnd());
115
+ if (!lines.some((p) => p)) {
116
+ return Empty;
96
117
  }
97
- const paragraphs = text.split(/\n+/).map((paragraph) => paragraph.trim().replace(/\s+/g, " "));
98
- if (!paragraphs.length) {
99
- return { prefixWidth: 0, entries: [] };
118
+ const breadcrumb = [{ ...Empty, entries: [] }];
119
+ for (const line of lines) {
120
+ detectBlock(line, breadcrumb);
121
+ breadcrumb[breadcrumb.length - 1].entries.push(line.trim().replace(/\s+/g, " "));
100
122
  }
101
- const listState = Array();
102
- let index = 0;
103
- function processLevel() {
104
- const level = listState.length;
105
- const structure = {
106
- prefixWidth: 0,
107
- entries: []
108
- };
109
- while (index < paragraphs.length) {
110
- detectList(paragraphs[index], listState);
111
- if (listState.length < level) {
112
- break;
113
- }
114
- if (listState.length > level) {
115
- structure.entries.push(processLevel());
116
- if (listState.length < level || index >= paragraphs.length) {
117
- break;
118
- }
119
- }
120
- structure.entries.push(paragraphs[index]);
121
- if (level) {
122
- const { prefix } = extractPrefix(paragraphs[index]);
123
- if (prefix.length > structure.prefixWidth) {
124
- structure.prefixWidth = prefix.length;
125
- }
126
- }
127
- index++;
128
- }
129
- return structure;
130
- }
131
- return processLevel();
123
+ return breadcrumb[0];
132
124
  }
133
- function wrapParagraph(input, into, wrapWidth, padding, prefixWidth) {
125
+ function wrapParagraph(input, into, wrapWidth, initialPrefix, wrapPrefix) {
126
+ const prefixWidth = visibleWidthOf(initialPrefix);
134
127
  const segments = input.split(/\s+/);
135
128
  if (!segments) {
136
129
  return;
@@ -146,35 +139,23 @@ function wrapParagraph(input, into, wrapWidth, padding, prefixWidth) {
146
139
  }
147
140
  }
148
141
  }
149
- let wrapPrefix;
150
- if (prefixWidth) {
151
- wrapPrefix = "".padStart(prefixWidth + 1, " ");
152
- } else {
153
- wrapPrefix = "";
154
- }
155
- const line = Array();
156
- let length = 0;
142
+ const line = [initialPrefix];
143
+ let width = prefixWidth;
157
144
  let pushedOne = false;
158
- let needWrapPrefix = false;
159
145
  for (const s of segments) {
160
- const segmentLength = visibleLengthOf(s);
161
- if (length && length + segmentLength > wrapWidth) {
146
+ const segmentWidth = visibleWidthOf(s);
147
+ if (width && width + segmentWidth > wrapWidth) {
162
148
  addLine();
163
- line.length = length = 0;
164
- needWrapPrefix = true;
165
- }
166
- if (!line.length && padding) {
167
- line.push("".padStart(padding, " "));
168
- length += padding;
149
+ line.length = 0;
150
+ width = prefixWidth;
169
151
  }
170
- if (needWrapPrefix) {
171
- needWrapPrefix = false;
152
+ if (!line.length) {
172
153
  line.push(wrapPrefix);
173
- length += wrapPrefix.length;
154
+ width = prefixWidth;
174
155
  }
175
156
  line.push(s);
176
157
  line.push(" ");
177
- length += segmentLength + 1;
158
+ width += segmentWidth + 1;
178
159
  }
179
160
  line.length = line.length - 1;
180
161
  if (line.length) {
@@ -190,21 +171,45 @@ function wrapParagraph(input, into, wrapWidth, padding, prefixWidth) {
190
171
  into.push(line.join(""));
191
172
  }
192
173
  }
193
- function formatStructure(structure, width) {
174
+ function separatePrefixFromContent(text) {
175
+ const match = text.match(/^(\S+\s)\s*(\S.*$)/);
176
+ if (match) {
177
+ return { prefix: match[1], text: match[2] };
178
+ }
179
+ return { prefix: "", text };
180
+ }
181
+ function formatBlock(block, width) {
194
182
  const lines = Array();
195
- function formatLevel(structure2, padding) {
196
- for (const entry of structure2.entries) {
183
+ function formatLevel(block2, parentPrefix) {
184
+ for (const entry of block2.entries) {
197
185
  if (typeof entry == "string") {
198
- wrapParagraph(entry, lines, width, padding, structure2.prefixWidth);
186
+ let prefix, text;
187
+ if (block2.kind === "simple" /* Simple */) {
188
+ prefix = "";
189
+ text = entry;
190
+ } else {
191
+ ({ prefix, text } = separatePrefixFromContent(entry));
192
+ }
193
+ wrapParagraph(
194
+ text,
195
+ lines,
196
+ width,
197
+ parentPrefix + prefix,
198
+ parentPrefix + " ".repeat(visibleWidthOf(prefix))
199
+ );
199
200
  } else {
200
- formatLevel(entry, padding + LIST_INDENT);
201
+ let childPrefix = parentPrefix;
202
+ if (entry.kind !== ">" /* Quote */ || parentPrefix !== "") {
203
+ childPrefix += INDENT;
204
+ }
205
+ formatLevel(entry, childPrefix);
201
206
  }
202
207
  }
203
208
  }
204
- formatLevel(structure, 0);
209
+ formatLevel(block, "");
205
210
  return lines;
206
211
  }
207
- function visibleLengthOf(text) {
212
+ function visibleWidthOf(text) {
208
213
  let length = 0;
209
214
  for (let i = 0; i < text.length; ) {
210
215
  switch (text[i]) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/util/FormattedText.ts"],
4
- "mappings": "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",
5
- "names": ["ListType", "structure"]
4
+ "mappings": "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",
5
+ "names": ["BlockKind", "block"]
6
6
  }
@@ -144,16 +144,16 @@ export declare const Transaction: {
144
144
  */
145
145
  act<T>(via: string, actor: (transaction: Transaction) => MaybePromise<T>): MaybePromise<T>;
146
146
  ReadOnly: {
147
- "__#15412@#participants": Set<Participant>;
148
- "__#15412@#roles": Map<{}, Participant>;
149
- "__#15412@#resources": Set<Resource>;
150
- "__#15412@#status": Status;
151
- "__#15412@#waitingOn"?: Iterable<Transaction>;
152
- "__#15412@#via": string;
153
- "__#15412@#shared"?: import("../index.js").Observable<[]>;
154
- "__#15412@#closed"?: import("../index.js").Observable<[]>;
155
- "__#15412@#isAsync": boolean;
156
- "__#15412@#reportingLocks": boolean;
147
+ "__#15442@#participants": Set<Participant>;
148
+ "__#15442@#roles": Map<{}, Participant>;
149
+ "__#15442@#resources": Set<Resource>;
150
+ "__#15442@#status": Status;
151
+ "__#15442@#waitingOn"?: Iterable<Transaction>;
152
+ "__#15442@#via": string;
153
+ "__#15442@#shared"?: import("../index.js").Observable<[]>;
154
+ "__#15442@#closed"?: import("../index.js").Observable<[]>;
155
+ "__#15442@#isAsync": boolean;
156
+ "__#15442@#reportingLocks": boolean;
157
157
  close(): void;
158
158
  readonly via: string;
159
159
  readonly status: Status;
@@ -175,15 +175,15 @@ export declare const Transaction: {
175
175
  waitFor(others: Set<Transaction>): Promise<void>;
176
176
  toString(): string;
177
177
  treatAsSlow(): void;
178
- "__#15412@#finalize"(status: Status, why: string, finalizer: () => MaybePromise): Promise<void> | undefined;
179
- "__#15412@#executePreCommit"(): MaybePromise<void>;
180
- "__#15412@#executeCommit"(): MaybePromise;
181
- "__#15412@#executeCommit1"(): MaybePromise;
182
- "__#15412@#executeCommit2"(): Promise<void> | undefined;
183
- "__#15412@#executePostCommit"(participants: Participant[]): MaybePromise;
184
- "__#15412@#executeRollback"(): Promise<void> | undefined;
185
- "__#15412@#locksChanged"(resources: Set<Resource>, how?: string): void;
186
- "__#15412@#assertAvailable"(): void;
178
+ "__#15442@#finalize"(status: Status, why: string, finalizer: () => MaybePromise): Promise<void> | undefined;
179
+ "__#15442@#executePreCommit"(): MaybePromise<void>;
180
+ "__#15442@#executeCommit"(): MaybePromise;
181
+ "__#15442@#executeCommit1"(): MaybePromise;
182
+ "__#15442@#executeCommit2"(): Promise<void> | undefined;
183
+ "__#15442@#executePostCommit"(participants: Participant[]): MaybePromise;
184
+ "__#15442@#executeRollback"(): Promise<void> | undefined;
185
+ "__#15442@#locksChanged"(resources: Set<Resource>, how?: string): void;
186
+ "__#15442@#assertAvailable"(): void;
187
187
  };
188
188
  Status: typeof Status;
189
189
  Resource: typeof Resource;
@@ -8,7 +8,30 @@ export { camelize, describeList, serialize } from "./String.js";
8
8
  * Performs word wrap. Input is assumed to be a series of paragraphs separated by a newline. Output is an array of
9
9
  * formatted lines.
10
10
  *
11
- * Contains specialized support for lists, ESDoc directives ans ANSI escape codes.
11
+ * Contains specialized support for lists, ESDoc directives and ANSI escape codes.
12
12
  */
13
13
  export declare function FormattedText(text: string, width?: number): string[];
14
+ /**
15
+ * Types of things we consider "blocks". Most blocks are lists but we also support markdown-style quotes prefixed with
16
+ * ">".
17
+ */
18
+ export declare enum BlockKind {
19
+ Simple = "simple",
20
+ Bullet1 = "\u2022",
21
+ Bullet2 = "\u25E6",
22
+ Bullet3 = "\u25AA",
23
+ Bullet4 = "\u25CB",
24
+ Bullet5 = "\u25CF",
25
+ Bullet6 = "\u2023",
26
+ Bullet7 = "\u2043",
27
+ Bullet8 = "\u25D8",
28
+ Quote = ">",
29
+ Number = "number",
30
+ LowerAlpha = "alpha",
31
+ UpperAlpha = "ALPHA",
32
+ LowerRoman = "roman",
33
+ UpperRoman = "ROMAN"
34
+ }
35
+ export declare const Bullets: BlockKind[];
36
+ export declare function looksLikeListItem(text: string): boolean;
14
37
  //# sourceMappingURL=FormattedText.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FormattedText.d.ts","sourceRoot":"","sources":["../../../src/util/FormattedText.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEhE;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAM,YAGtD"}
1
+ {"version":3,"file":"FormattedText.d.ts","sourceRoot":"","sources":["../../../src/util/FormattedText.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEhE;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAM,YAGtD;AAED;;;GAGG;AACH,oBAAY,SAAS;IACjB,MAAM,WAAW;IACjB,OAAO,WAAM;IACb,OAAO,WAAM;IACb,OAAO,WAAM;IACb,OAAO,WAAM;IACb,OAAO,WAAM;IACb,OAAO,WAAM;IACb,OAAO,WAAM;IACb,OAAO,WAAM;IACb,KAAK,MAAM;IACX,MAAM,WAAW;IACjB,UAAU,UAAU;IACpB,UAAU,UAAU;IACpB,UAAU,UAAU;IACpB,UAAU,UAAU;CACvB;AAED,eAAO,MAAM,OAAO,aAEU,CAAC;AAK/B,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,WAE7C"}
@@ -3,108 +3,98 @@
3
3
  * Copyright 2022-2025 Matter.js Authors
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- const LIST_INDENT = 2;
6
+ const INDENT = " ";
7
7
  import { camelize, describeList, serialize } from "./String.js";
8
8
  function FormattedText(text, width = 120) {
9
9
  const structure = detectStructure(text);
10
- return formatStructure(structure, width);
10
+ return formatBlock(structure, width);
11
11
  }
12
- var ListType = /* @__PURE__ */ ((ListType2) => {
13
- ListType2["Bullet1"] = "\u2022";
14
- ListType2["Bullet2"] = "\u25E6";
15
- ListType2["Bullet3"] = "\u25AA";
16
- ListType2["Bullet4"] = "\u25CB";
17
- ListType2["Bullet5"] = "\u25CF";
18
- ListType2["Bullet6"] = "\u2023";
19
- ListType2["Bullet7"] = "\u2043";
20
- ListType2["Bullet8"] = "\u25D8";
21
- ListType2["Number"] = "number";
22
- ListType2["LowerAlpha"] = "alpha";
23
- ListType2["UpperAlpha"] = "ALPHA";
24
- ListType2["LowerRoman"] = "roman";
25
- ListType2["UpperRoman"] = "ROMAN";
26
- return ListType2;
27
- })(ListType || {});
28
- function detectList(text, listState) {
29
- function enterList(listType) {
30
- const existing = listState.indexOf(listType);
31
- if (existing == -1) {
32
- listState.push(listType);
33
- } else {
34
- listState.length = existing + 1;
35
- }
12
+ var BlockKind = /* @__PURE__ */ ((BlockKind2) => {
13
+ BlockKind2["Simple"] = "simple";
14
+ BlockKind2["Bullet1"] = "\u2022";
15
+ BlockKind2["Bullet2"] = "\u25E6";
16
+ BlockKind2["Bullet3"] = "\u25AA";
17
+ BlockKind2["Bullet4"] = "\u25CB";
18
+ BlockKind2["Bullet5"] = "\u25CF";
19
+ BlockKind2["Bullet6"] = "\u2023";
20
+ BlockKind2["Bullet7"] = "\u2043";
21
+ BlockKind2["Bullet8"] = "\u25D8";
22
+ BlockKind2["Quote"] = ">";
23
+ BlockKind2["Number"] = "number";
24
+ BlockKind2["LowerAlpha"] = "alpha";
25
+ BlockKind2["UpperAlpha"] = "ALPHA";
26
+ BlockKind2["LowerRoman"] = "roman";
27
+ BlockKind2["UpperRoman"] = "ROMAN";
28
+ return BlockKind2;
29
+ })(BlockKind || {});
30
+ const Bullets = Object.entries(BlockKind).filter(([key]) => key.startsWith("Bullet")).map(([, value]) => value);
31
+ const enumTest = "(?:\\d+|[ivx]+|[a-z])\\.";
32
+ const listItemTest = new RegExp(`^(?:[${Bullets.join("")}]|${enumTest})\\s`, "i");
33
+ function looksLikeListItem(text) {
34
+ return !!listItemTest.exec(text);
35
+ }
36
+ const Empty = {
37
+ kind: "simple" /* Simple */,
38
+ indentWidth: 0,
39
+ entries: []
40
+ };
41
+ function detectBlock(text, breadcrumb) {
42
+ const match = text.match(/^\s*(\S+)/);
43
+ if (!match) {
44
+ return;
36
45
  }
37
- for (const value of Object.values(ListType)) {
38
- if (text[0] === value && text[1] === " ") {
39
- enterList(text[0]);
46
+ const [, marker] = match;
47
+ if (Bullets.includes(marker) || marker === ">" /* Quote */) {
48
+ enterBlock(marker);
49
+ return;
50
+ }
51
+ if (detectEnumeration(/^\d+\.$/, "1", "number" /* Number */)) return;
52
+ if (detectEnumeration(/^[ivx]+\.$/, "i", "roman" /* LowerRoman */)) return;
53
+ if (detectEnumeration(/^[IVX]+\.$/, "I", "ROMAN" /* UpperRoman */)) return;
54
+ if (detectEnumeration(/^[a-z]+\.$/, "a", "alpha" /* LowerAlpha */)) return;
55
+ if (detectEnumeration(/^[A-Z]+\.$/, "A", "ALPHA" /* UpperAlpha */)) return;
56
+ breadcrumb.length = 1;
57
+ function enterBlock(kind) {
58
+ const level = breadcrumb.findIndex((entry) => entry.kind === kind);
59
+ if (level !== -1) {
60
+ breadcrumb.length = level + 1;
40
61
  return;
41
62
  }
63
+ const block = {
64
+ kind,
65
+ indentWidth: (breadcrumb[breadcrumb.length - 1]?.indentWidth ?? 0) + kind === ">" /* Quote */ ? 0 : 2,
66
+ entries: []
67
+ };
68
+ breadcrumb[breadcrumb.length - 1].entries.push(block);
69
+ breadcrumb.push(block);
42
70
  }
43
- function detectEnumeration(test, listType, first) {
44
- if (!text.match(test)) {
71
+ function detectEnumeration(test, startsWith, kind) {
72
+ if (!marker.match(test)) {
45
73
  return false;
46
74
  }
47
- if (listState.indexOf(listType) != -1 || text.startsWith(`${first}.`)) {
48
- enterList(listType);
49
- return true;
75
+ if (!breadcrumb.find((block) => block.kind === kind)) {
76
+ if (marker !== `${startsWith}.`) {
77
+ return false;
78
+ }
50
79
  }
51
- return false;
80
+ enterBlock(kind);
81
+ return true;
52
82
  }
53
- if (detectEnumeration(/^\d+\./, "number" /* Number */, "1")) return;
54
- if (detectEnumeration(/^[ivx]+\./, "roman" /* LowerRoman */, "i")) return;
55
- if (detectEnumeration(/^[IVX]+\./, "ROMAN" /* UpperRoman */, "I")) return;
56
- if (detectEnumeration(/^[a-z]+\./, "alpha" /* LowerAlpha */, "a")) return;
57
- if (detectEnumeration(/^[A-Z]+\./, "ALPHA" /* UpperAlpha */, "A")) return;
58
- listState.length = 0;
59
- }
60
- function extractPrefix(text) {
61
- const match = text.match(/^(\S+)\s+($|\S.*$)/);
62
- if (match) {
63
- return { prefix: match[1], text: match[2] };
64
- }
65
- return { prefix: text, text: "" };
66
83
  }
67
84
  function detectStructure(text) {
68
- if (text == "") {
69
- return { prefixWidth: 0, entries: [] };
85
+ const lines = text.split(/\n+/).map((line) => line.trimEnd());
86
+ if (!lines.some((p) => p)) {
87
+ return Empty;
70
88
  }
71
- const paragraphs = text.split(/\n+/).map((paragraph) => paragraph.trim().replace(/\s+/g, " "));
72
- if (!paragraphs.length) {
73
- return { prefixWidth: 0, entries: [] };
89
+ const breadcrumb = [{ ...Empty, entries: [] }];
90
+ for (const line of lines) {
91
+ detectBlock(line, breadcrumb);
92
+ breadcrumb[breadcrumb.length - 1].entries.push(line.trim().replace(/\s+/g, " "));
74
93
  }
75
- const listState = Array();
76
- let index = 0;
77
- function processLevel() {
78
- const level = listState.length;
79
- const structure = {
80
- prefixWidth: 0,
81
- entries: []
82
- };
83
- while (index < paragraphs.length) {
84
- detectList(paragraphs[index], listState);
85
- if (listState.length < level) {
86
- break;
87
- }
88
- if (listState.length > level) {
89
- structure.entries.push(processLevel());
90
- if (listState.length < level || index >= paragraphs.length) {
91
- break;
92
- }
93
- }
94
- structure.entries.push(paragraphs[index]);
95
- if (level) {
96
- const { prefix } = extractPrefix(paragraphs[index]);
97
- if (prefix.length > structure.prefixWidth) {
98
- structure.prefixWidth = prefix.length;
99
- }
100
- }
101
- index++;
102
- }
103
- return structure;
104
- }
105
- return processLevel();
94
+ return breadcrumb[0];
106
95
  }
107
- function wrapParagraph(input, into, wrapWidth, padding, prefixWidth) {
96
+ function wrapParagraph(input, into, wrapWidth, initialPrefix, wrapPrefix) {
97
+ const prefixWidth = visibleWidthOf(initialPrefix);
108
98
  const segments = input.split(/\s+/);
109
99
  if (!segments) {
110
100
  return;
@@ -120,35 +110,23 @@ function wrapParagraph(input, into, wrapWidth, padding, prefixWidth) {
120
110
  }
121
111
  }
122
112
  }
123
- let wrapPrefix;
124
- if (prefixWidth) {
125
- wrapPrefix = "".padStart(prefixWidth + 1, " ");
126
- } else {
127
- wrapPrefix = "";
128
- }
129
- const line = Array();
130
- let length = 0;
113
+ const line = [initialPrefix];
114
+ let width = prefixWidth;
131
115
  let pushedOne = false;
132
- let needWrapPrefix = false;
133
116
  for (const s of segments) {
134
- const segmentLength = visibleLengthOf(s);
135
- if (length && length + segmentLength > wrapWidth) {
117
+ const segmentWidth = visibleWidthOf(s);
118
+ if (width && width + segmentWidth > wrapWidth) {
136
119
  addLine();
137
- line.length = length = 0;
138
- needWrapPrefix = true;
139
- }
140
- if (!line.length && padding) {
141
- line.push("".padStart(padding, " "));
142
- length += padding;
120
+ line.length = 0;
121
+ width = prefixWidth;
143
122
  }
144
- if (needWrapPrefix) {
145
- needWrapPrefix = false;
123
+ if (!line.length) {
146
124
  line.push(wrapPrefix);
147
- length += wrapPrefix.length;
125
+ width = prefixWidth;
148
126
  }
149
127
  line.push(s);
150
128
  line.push(" ");
151
- length += segmentLength + 1;
129
+ width += segmentWidth + 1;
152
130
  }
153
131
  line.length = line.length - 1;
154
132
  if (line.length) {
@@ -164,21 +142,45 @@ function wrapParagraph(input, into, wrapWidth, padding, prefixWidth) {
164
142
  into.push(line.join(""));
165
143
  }
166
144
  }
167
- function formatStructure(structure, width) {
145
+ function separatePrefixFromContent(text) {
146
+ const match = text.match(/^(\S+\s)\s*(\S.*$)/);
147
+ if (match) {
148
+ return { prefix: match[1], text: match[2] };
149
+ }
150
+ return { prefix: "", text };
151
+ }
152
+ function formatBlock(block, width) {
168
153
  const lines = Array();
169
- function formatLevel(structure2, padding) {
170
- for (const entry of structure2.entries) {
154
+ function formatLevel(block2, parentPrefix) {
155
+ for (const entry of block2.entries) {
171
156
  if (typeof entry == "string") {
172
- wrapParagraph(entry, lines, width, padding, structure2.prefixWidth);
157
+ let prefix, text;
158
+ if (block2.kind === "simple" /* Simple */) {
159
+ prefix = "";
160
+ text = entry;
161
+ } else {
162
+ ({ prefix, text } = separatePrefixFromContent(entry));
163
+ }
164
+ wrapParagraph(
165
+ text,
166
+ lines,
167
+ width,
168
+ parentPrefix + prefix,
169
+ parentPrefix + " ".repeat(visibleWidthOf(prefix))
170
+ );
173
171
  } else {
174
- formatLevel(entry, padding + LIST_INDENT);
172
+ let childPrefix = parentPrefix;
173
+ if (entry.kind !== ">" /* Quote */ || parentPrefix !== "") {
174
+ childPrefix += INDENT;
175
+ }
176
+ formatLevel(entry, childPrefix);
175
177
  }
176
178
  }
177
179
  }
178
- formatLevel(structure, 0);
180
+ formatLevel(block, "");
179
181
  return lines;
180
182
  }
181
- function visibleLengthOf(text) {
183
+ function visibleWidthOf(text) {
182
184
  let length = 0;
183
185
  for (let i = 0; i < text.length; ) {
184
186
  switch (text[i]) {
@@ -215,9 +217,12 @@ function visibleLengthOf(text) {
215
217
  return length;
216
218
  }
217
219
  export {
220
+ BlockKind,
221
+ Bullets,
218
222
  FormattedText,
219
223
  camelize,
220
224
  describeList,
225
+ looksLikeListItem,
221
226
  serialize
222
227
  };
223
228
  //# sourceMappingURL=FormattedText.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/util/FormattedText.ts"],
4
- "mappings": "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",
5
- "names": ["ListType", "structure"]
4
+ "mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,MAAM,SAAS;AAEf,SAAS,UAAU,cAAc,iBAAiB;AAQ3C,SAAS,cAAc,MAAc,QAAQ,KAAK;AACrD,QAAM,YAAY,gBAAgB,IAAI;AACtC,SAAO,YAAY,WAAW,KAAK;AACvC;AAMO,IAAK,YAAL,kBAAKA,eAAL;AACH,EAAAA,WAAA,YAAS;AACT,EAAAA,WAAA,aAAU;AACV,EAAAA,WAAA,aAAU;AACV,EAAAA,WAAA,aAAU;AACV,EAAAA,WAAA,aAAU;AACV,EAAAA,WAAA,aAAU;AACV,EAAAA,WAAA,aAAU;AACV,EAAAA,WAAA,aAAU;AACV,EAAAA,WAAA,aAAU;AACV,EAAAA,WAAA,WAAQ;AACR,EAAAA,WAAA,YAAS;AACT,EAAAA,WAAA,gBAAa;AACb,EAAAA,WAAA,gBAAa;AACb,EAAAA,WAAA,gBAAa;AACb,EAAAA,WAAA,gBAAa;AAfL,SAAAA;AAAA,GAAA;AAkBL,MAAM,UAAU,OAAO,QAAQ,SAAS,EAC1C,OAAO,CAAC,CAAC,GAAG,MAAM,IAAI,WAAW,QAAQ,CAAC,EAC1C,IAAI,CAAC,CAAC,EAAE,KAAK,MAAM,KAAK;AAE7B,MAAM,WAAW;AACjB,MAAM,eAAe,IAAI,OAAO,QAAQ,QAAQ,KAAK,EAAE,CAAC,KAAK,QAAQ,QAAQ,GAAG;AAEzE,SAAS,kBAAkB,MAAc;AAC5C,SAAO,CAAC,CAAC,aAAa,KAAK,IAAI;AACnC;AAQA,MAAM,QAAe;AAAA,EACjB,MAAM;AAAA,EACN,aAAa;AAAA,EACb,SAAS,CAAC;AACd;AAOA,SAAS,YAAY,MAAc,YAAqB;AACpD,QAAM,QAAQ,KAAK,MAAM,WAAW;AACpC,MAAI,CAAC,OAAO;AACR;AAAA,EACJ;AAEA,QAAM,CAAC,EAAE,MAAM,IAAI;AAEnB,MAAI,QAAQ,SAAS,MAAmB,KAAK,WAAW,iBAAiB;AACrE,eAAW,MAAmB;AAC9B;AAAA,EACJ;AAEA,MAAI,kBAAkB,WAAW,KAAK,qBAAgB,EAAG;AACzD,MAAI,kBAAkB,cAAc,KAAK,wBAAoB,EAAG;AAChE,MAAI,kBAAkB,cAAc,KAAK,wBAAoB,EAAG;AAChE,MAAI,kBAAkB,cAAc,KAAK,wBAAoB,EAAG;AAChE,MAAI,kBAAkB,cAAc,KAAK,wBAAoB,EAAG;AAGhE,aAAW,SAAS;AAEpB,WAAS,WAAW,MAAiB;AAEjC,UAAM,QAAQ,WAAW,UAAU,WAAS,MAAM,SAAS,IAAI;AAC/D,QAAI,UAAU,IAAI;AACd,iBAAW,SAAS,QAAQ;AAC5B;AAAA,IACJ;AAGA,UAAM,QAAQ;AAAA,MACV;AAAA,MACA,cAAc,WAAW,WAAW,SAAS,CAAC,GAAG,eAAe,KAAK,SAAS,kBAAkB,IAAI;AAAA,MACpG,SAAS,CAAC;AAAA,IACd;AAEA,eAAW,WAAW,SAAS,CAAC,EAAE,QAAQ,KAAK,KAAK;AACpD,eAAW,KAAK,KAAK;AAAA,EACzB;AAEA,WAAS,kBAAkB,MAAc,YAAoB,MAAiB;AAC1E,QAAI,CAAC,OAAO,MAAM,IAAI,GAAG;AACrB,aAAO;AAAA,IACX;AAIA,QAAI,CAAC,WAAW,KAAK,WAAS,MAAM,SAAS,IAAI,GAAG;AAChD,UAAI,WAAW,GAAG,UAAU,KAAK;AAC7B,eAAO;AAAA,MACX;AAAA,IACJ;AAEA,eAAW,IAAI;AACf,WAAO;AAAA,EACX;AACJ;AAKA,SAAS,gBAAgB,MAAqB;AAC1C,QAAM,QAAQ,KAAK,MAAM,KAAK,EAAE,IAAI,UAAQ,KAAK,QAAQ,CAAC;AAC1D,MAAI,CAAC,MAAM,KAAK,OAAK,CAAC,GAAG;AACrB,WAAO;AAAA,EACX;AAEA,QAAM,aAAsB,CAAC,EAAE,GAAG,OAAO,SAAS,CAAC,EAAE,CAAC;AAEtD,aAAW,QAAQ,OAAO;AACtB,gBAAY,MAAM,UAAU;AAC5B,eAAW,WAAW,SAAS,CAAC,EAAE,QAAQ,KAAK,KAAK,KAAK,EAAE,QAAQ,QAAQ,GAAG,CAAC;AAAA,EACnF;AAEA,SAAO,WAAW,CAAC;AACvB;AAEA,SAAS,cAAc,OAAe,MAAgB,WAAmB,eAAuB,YAAoB;AAChH,QAAM,cAAc,eAAe,aAAa;AAChD,QAAM,WAAW,MAAM,MAAM,KAAK;AAClC,MAAI,CAAC,UAAU;AACX;AAAA,EACJ;AAIA,WAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACvC,QAAI,CAAC,SAAS,CAAC,EAAE,SAAS,IAAI,GAAG;AAC7B;AAAA,IACJ;AACA,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACtC,UAAI,SAAS,CAAC,EAAE,SAAS,GAAG,GAAG;AAC3B,iBAAS,OAAO,GAAG,IAAI,IAAI,GAAG,SAAS,MAAM,GAAG,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC;AAChE;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAGA,QAAM,OAAO,CAAC,aAAa;AAC3B,MAAI,QAAQ;AAGZ,MAAI,YAAY;AAChB,aAAW,KAAK,UAAU;AACtB,UAAM,eAAe,eAAe,CAAC;AAGrC,QAAI,SAAS,QAAQ,eAAe,WAAW;AAC3C,cAAQ;AACR,WAAK,SAAS;AACd,cAAQ;AAAA,IACZ;AAGA,QAAI,CAAC,KAAK,QAAQ;AACd,WAAK,KAAK,UAAU;AACpB,cAAQ;AAAA,IACZ;AAGA,SAAK,KAAK,CAAC;AACX,SAAK,KAAK,GAAG;AACb,aAAS,eAAe;AAAA,EAC5B;AAGA,OAAK,SAAS,KAAK,SAAS;AAC5B,MAAI,KAAK,QAAQ;AACb,YAAQ;AAAA,EACZ;AAEA,WAAS,UAAU;AACf,QAAI,CAAC,WAAW;AACZ,UAAI,KAAK,QAAQ;AACb,aAAK,KAAK,EAAE;AAAA,MAChB;AACA,kBAAY;AAAA,IAChB;AAEA,SAAK,KAAK,KAAK,KAAK,EAAE,CAAC;AAAA,EAC3B;AACJ;AAEA,SAAS,0BAA0B,MAAc;AAC7C,QAAM,QAAQ,KAAK,MAAM,oBAAoB;AAC7C,MAAI,OAAO;AACP,WAAO,EAAE,QAAQ,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,EAAE;AAAA,EAC9C;AACA,SAAO,EAAE,QAAQ,IAAI,KAAK;AAC9B;AAEA,SAAS,YAAY,OAAc,OAAe;AAC9C,QAAM,QAAQ,MAAc;AAE5B,WAAS,YAAYC,QAAc,cAAsB;AACrD,eAAW,SAASA,OAAM,SAAS;AAC/B,UAAI,OAAO,SAAS,UAAU;AAC1B,YAAI,QAAQ;AACZ,YAAIA,OAAM,SAAS,uBAAkB;AACjC,mBAAS;AACT,iBAAO;AAAA,QACX,OAAO;AACH,WAAC,EAAE,QAAQ,KAAK,IAAI,0BAA0B,KAAK;AAAA,QACvD;AAEA;AAAA,UACI;AAAA,UACA;AAAA,UACA;AAAA,UACA,eAAe;AAAA,UACf,eAAe,IAAI,OAAO,eAAe,MAAM,CAAC;AAAA,QACpD;AAAA,MACJ,OAAO;AACH,YAAI,cAAc;AAClB,YAAI,MAAM,SAAS,mBAAmB,iBAAiB,IAAI;AACvD,yBAAe;AAAA,QACnB;AACA,oBAAY,OAAO,WAAW;AAAA,MAClC;AAAA,IACJ;AAAA,EACJ;AAEA,cAAY,OAAO,EAAE;AAErB,SAAO;AACX;AAEA,SAAS,eAAe,MAAc;AAClC,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,KAAK,UAAU;AAC/B,YAAQ,KAAK,CAAC,GAAG;AAAA,MACb,KAAK;AAED;AACA,cAAM,OAAO,KAAK,CAAC;AAEnB,YAAK,QAAQ,OAAO,QAAQ,OAAQ,SAAS,OAAO,SAAS,KAAK;AAE9D;AACA;AAAA,QACJ;AAEA,YAAI,SAAS,KAAK;AAEd;AACA,iBAAO,KAAK,CAAC,KAAK,OAAO,KAAK,CAAC,KAAK,KAAK;AAErC;AAAA,UACJ;AACA,iBAAO,KAAK,CAAC,KAAK,OAAO,KAAK,CAAC,KAAK,KAAK;AAErC;AAAA,UACJ;AACA,cAAI,KAAK,CAAC,KAAK,OAAO,KAAK,CAAC,KAAK,KAAK;AAElC;AACA;AAAA,UACJ;AAAA,QACJ;AAEA;AAAA,MAEJ,KAAK;AAED;AACA;AAAA,MAEJ;AACI;AACA;AACA;AAAA,IACR;AAAA,EACJ;AACA,SAAO;AACX;",
5
+ "names": ["BlockKind", "block"]
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matter/general",
3
- "version": "0.13.1-alpha.0-20250508-047aa0277",
3
+ "version": "0.13.1-alpha.0-20250509-28e1567e1",
4
4
  "description": "Non-Matter support for Matter.js",
5
5
  "keywords": [
6
6
  "iot",
@@ -36,7 +36,7 @@
36
36
  "@noble/curves": "^1.8.2"
37
37
  },
38
38
  "devDependencies": {
39
- "@matter/testing": "0.13.1-alpha.0-20250508-047aa0277"
39
+ "@matter/testing": "0.13.1-alpha.0-20250509-28e1567e1"
40
40
  },
41
41
  "files": [
42
42
  "dist/**/*",
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
- const LIST_INDENT = 2;
7
+ const INDENT = " ";
8
8
 
9
9
  export { camelize, describeList, serialize } from "./String.js";
10
10
 
@@ -12,14 +12,19 @@ export { camelize, describeList, serialize } from "./String.js";
12
12
  * Performs word wrap. Input is assumed to be a series of paragraphs separated by a newline. Output is an array of
13
13
  * formatted lines.
14
14
  *
15
- * Contains specialized support for lists, ESDoc directives ans ANSI escape codes.
15
+ * Contains specialized support for lists, ESDoc directives and ANSI escape codes.
16
16
  */
17
17
  export function FormattedText(text: string, width = 120) {
18
18
  const structure = detectStructure(text);
19
- return formatStructure(structure, width);
19
+ return formatBlock(structure, width);
20
20
  }
21
21
 
22
- enum ListType {
22
+ /**
23
+ * Types of things we consider "blocks". Most blocks are lists but we also support markdown-style quotes prefixed with
24
+ * ">".
25
+ */
26
+ export enum BlockKind {
27
+ Simple = "simple",
23
28
  Bullet1 = "•",
24
29
  Bullet2 = "◦",
25
30
  Bullet3 = "▪",
@@ -28,6 +33,7 @@ enum ListType {
28
33
  Bullet6 = "‣",
29
34
  Bullet7 = "⁃",
30
35
  Bullet8 = "◘",
36
+ Quote = ">",
31
37
  Number = "number",
32
38
  LowerAlpha = "alpha",
33
39
  UpperAlpha = "ALPHA",
@@ -35,115 +41,114 @@ enum ListType {
35
41
  UpperRoman = "ROMAN",
36
42
  }
37
43
 
38
- function detectList(text: string, listState: ListType[]) {
39
- function enterList(listType: ListType) {
40
- const existing = listState.indexOf(listType);
41
- if (existing == -1) {
42
- listState.push(listType);
43
- } else {
44
- listState.length = existing + 1;
45
- }
46
- }
47
-
48
- for (const value of Object.values(ListType)) {
49
- if (text[0] === value && text[1] === " ") {
50
- enterList(text[0] as ListType);
51
- return;
52
- }
53
- }
54
-
55
- function detectEnumeration(test: RegExp, listType: ListType, first: string) {
56
- if (!text.match(test)) {
57
- return false;
58
- }
59
-
60
- if (listState.indexOf(listType) != -1 || text.startsWith(`${first}.`)) {
61
- enterList(listType);
62
- return true;
63
- }
64
-
65
- return false;
66
- }
44
+ export const Bullets = Object.entries(BlockKind)
45
+ .filter(([key]) => key.startsWith("Bullet"))
46
+ .map(([, value]) => value);
67
47
 
68
- if (detectEnumeration(/^\d+\./, ListType.Number, "1")) return;
69
- if (detectEnumeration(/^[ivx]+\./, ListType.LowerRoman, "i")) return;
70
- if (detectEnumeration(/^[IVX]+\./, ListType.UpperRoman, "I")) return;
71
- if (detectEnumeration(/^[a-z]+\./, ListType.LowerAlpha, "a")) return;
72
- if (detectEnumeration(/^[A-Z]+\./, ListType.UpperAlpha, "A")) return;
48
+ const enumTest = "(?:\\d+|[ivx]+|[a-z])\\.";
49
+ const listItemTest = new RegExp(`^(?:[${Bullets.join("")}]|${enumTest})\\s`, "i");
73
50
 
74
- listState.length = 0;
51
+ export function looksLikeListItem(text: string) {
52
+ return !!listItemTest.exec(text);
75
53
  }
76
54
 
77
- type TextStructure = {
78
- prefixWidth: number;
79
- entries: (string | TextStructure)[];
55
+ type Block = {
56
+ kind: BlockKind;
57
+ indentWidth: number;
58
+ entries: (string | Block)[];
80
59
  };
81
60
 
82
- function extractPrefix(text: string) {
83
- const match = text.match(/^(\S+)\s+($|\S.*$)/);
84
- if (match) {
85
- return { prefix: match[1], text: match[2] };
86
- }
87
- return { prefix: text, text: "" };
88
- }
61
+ const Empty: Block = {
62
+ kind: BlockKind.Simple,
63
+ indentWidth: 0,
64
+ entries: [],
65
+ };
89
66
 
90
- function detectStructure(text: string): TextStructure {
91
- if (text == "") {
92
- return { prefixWidth: 0, entries: [] };
67
+ /**
68
+ * Detect block prefixes. This is designed to handle scavenged, poorly formatted text so does not use indentation. It
69
+ * just focus on the prefix characters of the paragraph/line (which are the same thing as paragraphs do not include
70
+ * newlines).
71
+ */
72
+ function detectBlock(text: string, breadcrumb: Block[]) {
73
+ const match = text.match(/^\s*(\S+)/);
74
+ if (!match) {
75
+ return;
93
76
  }
94
- const paragraphs = text.split(/\n+/).map(paragraph => paragraph.trim().replace(/\s+/g, " "));
95
- if (!paragraphs.length) {
96
- return { prefixWidth: 0, entries: [] };
77
+
78
+ const [, marker] = match;
79
+
80
+ if (Bullets.includes(marker as BlockKind) || marker === BlockKind.Quote) {
81
+ enterBlock(marker as BlockKind);
82
+ return;
97
83
  }
98
84
 
99
- const listState = Array<ListType>();
100
- let index = 0;
85
+ if (detectEnumeration(/^\d+\.$/, "1", BlockKind.Number)) return;
86
+ if (detectEnumeration(/^[ivx]+\.$/, "i", BlockKind.LowerRoman)) return;
87
+ if (detectEnumeration(/^[IVX]+\.$/, "I", BlockKind.UpperRoman)) return;
88
+ if (detectEnumeration(/^[a-z]+\.$/, "a", BlockKind.LowerAlpha)) return;
89
+ if (detectEnumeration(/^[A-Z]+\.$/, "A", BlockKind.UpperAlpha)) return;
90
+
91
+ // Not in a block
92
+ breadcrumb.length = 1;
93
+
94
+ function enterBlock(kind: BlockKind) {
95
+ // If we are already in block of this kind, ensure it is the deepest level
96
+ const level = breadcrumb.findIndex(entry => entry.kind === kind);
97
+ if (level !== -1) {
98
+ breadcrumb.length = level + 1;
99
+ return;
100
+ }
101
101
 
102
- function processLevel() {
103
- const level = listState.length;
104
- const structure = {
105
- prefixWidth: 0,
102
+ // Need to start a new block
103
+ const block = {
104
+ kind,
105
+ indentWidth: (breadcrumb[breadcrumb.length - 1]?.indentWidth ?? 0) + kind === BlockKind.Quote ? 0 : 2,
106
106
  entries: [],
107
- } as TextStructure;
107
+ };
108
108
 
109
- while (index < paragraphs.length) {
110
- detectList(paragraphs[index], listState);
109
+ breadcrumb[breadcrumb.length - 1].entries.push(block);
110
+ breadcrumb.push(block);
111
+ }
111
112
 
112
- // If we've moved to a higher list, we're done with this level
113
- if (listState.length < level) {
114
- break;
115
- }
113
+ function detectEnumeration(test: RegExp, startsWith: string, kind: BlockKind) {
114
+ if (!marker.match(test)) {
115
+ return false;
116
+ }
116
117
 
117
- // If we've moved to a deeper list, process the new level before continuing
118
- if (listState.length > level) {
119
- structure.entries.push(processLevel());
120
- if (listState.length < level || index >= paragraphs.length) {
121
- break;
122
- }
118
+ // Only consider enumeration if a.) we are already in same type of enumeration, or b.) the marker is the first
119
+ // element of the enumeration (e.g. "1." or "i.")
120
+ if (!breadcrumb.find(block => block.kind === kind)) {
121
+ if (marker !== `${startsWith}.`) {
122
+ return false;
123
123
  }
124
+ }
124
125
 
125
- // This paragraph is in this level
126
- structure.entries.push(paragraphs[index]);
126
+ enterBlock(kind);
127
+ return true;
128
+ }
129
+ }
127
130
 
128
- // In lists, update the prefix width so we know how far out to pad when formatting
129
- if (level) {
130
- const { prefix } = extractPrefix(paragraphs[index]);
131
- if (prefix.length > structure.prefixWidth) {
132
- structure.prefixWidth = prefix.length;
133
- }
134
- }
131
+ /**
132
+ * Builds a block structure by detecting lists and/or quoted sections.
133
+ */
134
+ function detectStructure(text: string): Block {
135
+ const lines = text.split(/\n+/).map(line => line.trimEnd());
136
+ if (!lines.some(p => p)) {
137
+ return Empty;
138
+ }
135
139
 
136
- // Move to next line
137
- index++;
138
- }
140
+ const breadcrumb: Block[] = [{ ...Empty, entries: [] }];
139
141
 
140
- return structure;
142
+ for (const line of lines) {
143
+ detectBlock(line, breadcrumb);
144
+ breadcrumb[breadcrumb.length - 1].entries.push(line.trim().replace(/\s+/g, " "));
141
145
  }
142
146
 
143
- return processLevel();
147
+ return breadcrumb[0];
144
148
  }
145
149
 
146
- function wrapParagraph(input: string, into: string[], wrapWidth: number, padding: number, prefixWidth: number) {
150
+ function wrapParagraph(input: string, into: string[], wrapWidth: number, initialPrefix: string, wrapPrefix: string) {
151
+ const prefixWidth = visibleWidthOf(initialPrefix);
147
152
  const segments = input.split(/\s+/);
148
153
  if (!segments) {
149
154
  return;
@@ -163,50 +168,32 @@ function wrapParagraph(input: string, into: string[], wrapWidth: number, padding
163
168
  }
164
169
  }
165
170
 
166
- // Configure for list prefix formatting
167
- let wrapPrefix: string;
168
- if (prefixWidth) {
169
- // After wrapping this prefix will pad out subsequent entries
170
- wrapPrefix = "".padStart(prefixWidth + 1, " ");
171
- } else {
172
- // No prefix
173
- wrapPrefix = "";
174
- }
175
-
176
171
  // Wrapping setup. Track the portions of the line and current length
177
- const line = Array<string>();
178
- let length = 0;
172
+ const line = [initialPrefix];
173
+ let width = prefixWidth;
179
174
 
180
175
  // Perform actual wrapping
181
176
  let pushedOne = false;
182
- let needWrapPrefix = false;
183
177
  for (const s of segments) {
184
- const segmentLength = visibleLengthOf(s);
178
+ const segmentWidth = visibleWidthOf(s);
185
179
 
186
180
  // If we'll extend too far, start on a new line
187
- if (length && length + segmentLength > wrapWidth) {
181
+ if (width && width + segmentWidth > wrapWidth) {
188
182
  addLine();
189
- line.length = length = 0;
190
- needWrapPrefix = true;
183
+ line.length = 0;
184
+ width = prefixWidth;
191
185
  }
192
186
 
193
- // Add padding if this is a new line
194
- if (!line.length && padding) {
195
- line.push("".padStart(padding, " "));
196
- length += padding;
197
- }
198
-
199
- // Add wrap prefix if this is a new line in a list
200
- if (needWrapPrefix) {
201
- needWrapPrefix = false;
187
+ // Add wrap prefix if this is a new line
188
+ if (!line.length) {
202
189
  line.push(wrapPrefix);
203
- length += wrapPrefix.length;
190
+ width = prefixWidth;
204
191
  }
205
192
 
206
193
  // Add to the line
207
194
  line.push(s);
208
195
  line.push(" ");
209
- length += segmentLength + 1;
196
+ width += segmentWidth + 1;
210
197
  }
211
198
 
212
199
  // If there is a remaining line, add it
@@ -227,25 +214,51 @@ function wrapParagraph(input: string, into: string[], wrapWidth: number, padding
227
214
  }
228
215
  }
229
216
 
230
- function formatStructure(structure: TextStructure, width: number) {
217
+ function separatePrefixFromContent(text: string) {
218
+ const match = text.match(/^(\S+\s)\s*(\S.*$)/);
219
+ if (match) {
220
+ return { prefix: match[1], text: match[2] };
221
+ }
222
+ return { prefix: "", text };
223
+ }
224
+
225
+ function formatBlock(block: Block, width: number) {
231
226
  const lines = Array<string>();
232
227
 
233
- function formatLevel(structure: TextStructure, padding: number) {
234
- for (const entry of structure.entries) {
228
+ function formatLevel(block: Block, parentPrefix: string) {
229
+ for (const entry of block.entries) {
235
230
  if (typeof entry == "string") {
236
- wrapParagraph(entry, lines, width, padding, structure.prefixWidth);
231
+ let prefix, text;
232
+ if (block.kind === BlockKind.Simple) {
233
+ prefix = "";
234
+ text = entry;
235
+ } else {
236
+ ({ prefix, text } = separatePrefixFromContent(entry));
237
+ }
238
+
239
+ wrapParagraph(
240
+ text,
241
+ lines,
242
+ width,
243
+ parentPrefix + prefix,
244
+ parentPrefix + " ".repeat(visibleWidthOf(prefix)),
245
+ );
237
246
  } else {
238
- formatLevel(entry, padding + LIST_INDENT);
247
+ let childPrefix = parentPrefix;
248
+ if (entry.kind !== BlockKind.Quote || parentPrefix !== "") {
249
+ childPrefix += INDENT;
250
+ }
251
+ formatLevel(entry, childPrefix);
239
252
  }
240
253
  }
241
254
  }
242
255
 
243
- formatLevel(structure, 0);
256
+ formatLevel(block, "");
244
257
 
245
258
  return lines;
246
259
  }
247
260
 
248
- function visibleLengthOf(text: string) {
261
+ function visibleWidthOf(text: string) {
249
262
  let length = 0;
250
263
  for (let i = 0; i < text.length; ) {
251
264
  switch (text[i]) {