@naersen/tts-rich-text 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -119,7 +119,7 @@ const getPreviewParams = () => ({
119
119
 
120
120
  ### 功能配置
121
121
 
122
- `features` 可以覆盖工具列表、语言列表、拼音最大选区长度、数字最大长度和试听开关。包内提供 V1/V2 默认能力配置,项目配置拥有最高优先级。V2 默认提供全部工具,V1 默认不包含 `ignore`。
122
+ `features` 可以覆盖工具列表、语言列表、拼音最大选区长度、数字最大长度和试听开关。包内提供 V1/V2 默认能力配置,项目配置拥有最高优先级。V2 默认提供全部工具;V1 也支持 `ignore`,但默认不提供 `stop` 和 `continue`。
123
123
 
124
124
  `ignore` 对应“忽略读音”工具,只能标记纯文本选区。`convertToTtsFormat()` 会保留句子原文,并为忽略区域输出替换指令:
125
125
 
@@ -136,6 +136,24 @@ const getPreviewParams = () => ({
136
136
 
137
137
  合成端应按 `position` 和 `text` 将该区域替换为空格,从而保留编辑器可见文本但不合成读音。
138
138
 
139
+ ### 分句策略
140
+
141
+ `convertToTtsFormat()` 使用 `splitTextToSentences()` 生成 `sentences`。默认按视觉长度计算,中文、全角字符计 2,其他字符计 1;每段最小目标长度为 32,最大目标长度为 64。
142
+
143
+ 超长内容优先在分号处分割,其次是逗号或冒号、空格,顿号仅在没有其他自然切点时使用。数字中的小数点和千分位逗号不会被当作分句点,过短尾段会自动重平衡。
144
+
145
+ 需要自定义长度时,可以从核心入口调用:
146
+
147
+ ```ts
148
+ import { splitTextToSentences } from '@naersen/tts-rich-text/core'
149
+
150
+ const sentences = splitTextToSentences(text, {
151
+ minSegmentLength: 32,
152
+ maxSegmentLength: 64,
153
+ rebalanceRatio: 0.4
154
+ })
155
+ ```
156
+
139
157
  ### 服务适配
140
158
 
141
159
  以下能力只有传入对应 service 时才可用;未提供时保留原工具位置并显示为禁用态:
@@ -66,7 +66,7 @@ export declare const ToolConfig: {
66
66
  readonly label: "忽略读音";
67
67
  readonly icon: "editor-ingore";
68
68
  readonly type: "ignore";
69
- readonly deleteMode: "deleteNode";
69
+ readonly deleteMode: "convertToText";
70
70
  };
71
71
  };
72
72
  export type CustomTagType = 'stop' | 'customStop' | 'continue' | 'pinyin' | 'replace' | 'language' | 'ignore';
package/dist/core.js CHANGED
@@ -62,7 +62,7 @@ const f = {
62
62
  label: "忽略读音",
63
63
  icon: "editor-ingore",
64
64
  type: "ignore",
65
- deleteMode: f.DELETE_NODE
65
+ deleteMode: f.CONVERT_TO_TEXT
66
66
  }
67
67
  }, _ = [
68
68
  { value: "zh", label: "中文" },
@@ -75,16 +75,16 @@ const f = {
75
75
  { value: "it", label: "意大利语" },
76
76
  { value: "pt", label: "葡萄牙语" },
77
77
  { value: "ru", label: "俄语" }
78
- ], ie = [
78
+ ], le = [
79
79
  { label: "停顿 0.5 秒", value: 0.5 },
80
80
  { label: "停顿 1 秒", value: 1 }
81
- ], S = Object.keys(h), d = {
82
- tools: S,
81
+ ], v = Object.keys(h), d = {
82
+ tools: v,
83
83
  languages: _,
84
84
  maxPinyinLength: 4,
85
85
  maxNumberLength: 16,
86
86
  enablePreview: !0
87
- }, C = {
87
+ }, D = {
88
88
  1: {
89
89
  tools: [
90
90
  "customStop",
@@ -94,23 +94,24 @@ const f = {
94
94
  "number",
95
95
  "formula",
96
96
  "aiRewrite",
97
- "upload"
97
+ "upload",
98
+ "ignore"
98
99
  ],
99
100
  languages: _.filter(
100
101
  (e) => ["zh", "en"].includes(e.value)
101
102
  )
102
103
  },
103
104
  2: d
104
- }, le = (e, o = {}) => {
105
- const t = C[e] ?? d;
105
+ }, ae = (e, n = {}) => {
106
+ const t = D[e] ?? d;
106
107
  return {
107
108
  ...d,
108
109
  ...t,
109
- ...o,
110
- tools: o.tools ?? t.tools ?? d.tools,
111
- languages: o.languages ?? t.languages ?? d.languages
110
+ ...n,
111
+ tools: n.tools ?? t.tools ?? d.tools,
112
+ languages: n.languages ?? t.languages ?? d.languages
112
113
  };
113
- }, ae = () => ({
114
+ }, ce = () => ({
114
115
  type: "doc",
115
116
  content: [
116
117
  {
@@ -129,7 +130,7 @@ const f = {
129
130
  7: "七",
130
131
  8: "八",
131
132
  9: "九"
132
- }, v = {
133
+ }, w = {
133
134
  0: "洞",
134
135
  1: "幺",
135
136
  2: "二",
@@ -140,49 +141,49 @@ const f = {
140
141
  7: "七",
141
142
  8: "八",
142
143
  9: "九"
143
- }, A = ["", "十", "百", "千"], D = ["", "万", "亿", "万亿"];
144
- function w(e) {
145
- return e ? e.split("").map((o) => y[o] || o).join("") : "";
144
+ }, V = ["", "十", "百", "千"], $ = ["", "万", "亿", "万亿"];
145
+ function B(e) {
146
+ return e ? e.split("").map((n) => y[n] || n).join("") : "";
146
147
  }
147
- function ce(e) {
148
- return e ? e.split("").map((o) => v[o] || o).join("") : "";
148
+ function ue(e) {
149
+ return e ? e.split("").map((n) => w[n] || n).join("") : "";
149
150
  }
150
- function V(e) {
151
- const o = e.length;
152
- let t = "", n = !1;
153
- for (let s = 0; s < o; s++) {
154
- const a = e[s], r = o - 1 - s;
155
- a === "0" ? !n && t !== "" && (n = !0) : (n && (t += "零", n = !1), t += y[a] + A[r]);
151
+ function U(e) {
152
+ const n = e.length;
153
+ let t = "", o = !1;
154
+ for (let s = 0; s < n; s++) {
155
+ const l = e[s], r = n - 1 - s;
156
+ l === "0" ? !o && t !== "" && (o = !0) : (o && (t += "零", o = !1), t += y[l] + V[r]);
156
157
  }
157
158
  return t.startsWith("一十") && t.length === 2 && (t = t.substring(1)), t;
158
159
  }
159
- function I(e) {
160
+ function F(e) {
160
161
  if (!e) return "";
161
162
  if (e === "0" || (e = e.replace(/^0+/, "") || "0", e === "0")) return "零";
162
- let o = "";
163
- const t = e.length, n = [];
163
+ let n = "";
164
+ const t = e.length, o = [];
164
165
  for (let s = t; s > 0; s -= 4) {
165
- const a = Math.max(0, s - 4);
166
- n.unshift(e.substring(a, s));
166
+ const l = Math.max(0, s - 4);
167
+ o.unshift(e.substring(l, s));
167
168
  }
168
- for (let s = 0; s < n.length; s++) {
169
- const a = n[s], r = V(a);
169
+ for (let s = 0; s < o.length; s++) {
170
+ const l = o[s], r = U(l);
170
171
  if (r !== "") {
171
- const i = n.length - 1 - s;
172
- o += r + D[i];
172
+ const i = o.length - 1 - s;
173
+ n += r + $[i];
173
174
  }
174
175
  }
175
- return o;
176
+ return n;
176
177
  }
177
- function $(e) {
178
- return I(e);
178
+ function j(e) {
179
+ return F(e);
179
180
  }
180
- const ue = [
181
- { label: "基数读法", func: w },
181
+ const pe = [
182
+ { label: "基数读法", func: B },
182
183
  // { label: '位数读法', func: toPhoneReading },
183
- { label: "位数读法", func: I },
184
- { label: "口语读法", func: $ }
185
- ], B = /[\u0000-\u0008\u000B-\u001F\u007F-\u009F\u00AD\u200B-\u200F\u202A-\u202E\u2060-\u206F\uFE00-\uFE0F\uFEFF\uFFFD\uE000-\uF8FF]/g, j = /[\t\f\v\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g, L = {
184
+ { label: "位数读法", func: F },
185
+ { label: "口语读法", func: j }
186
+ ], k = /[\u0000-\u0008\u000B-\u001F\u007F-\u009F\u00AD\u200B-\u200F\u202A-\u202E\u2060-\u206F\uFE00-\uFE0F\uFEFF\uFFFD\uE000-\uF8FF]/g, z = /[\t\f\v\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g, O = {
186
187
  "‘": "'",
187
188
  "’": "'",
188
189
  "‚": "'",
@@ -214,153 +215,162 @@ const ue = [
214
215
  "︔": ";",
215
216
  "︕": "!",
216
217
  "︖": "?"
217
- }, U = new RegExp(
218
- `[${Object.keys(L).join("")}]`,
218
+ }, H = new RegExp(
219
+ `[${Object.keys(O).join("")}]`,
219
220
  "g"
220
- ), z = (e) => e.replace(/[\uFF21-\uFF3A\uFF41-\uFF5A\uFF10-\uFF19]/g, (o) => String.fromCharCode(o.charCodeAt(0) - 65248)), H = (e) => z(e).replace(/\r\n?/g, `
221
+ ), X = (e) => e.replace(/[\uFF21-\uFF3A\uFF41-\uFF5A\uFF10-\uFF19]/g, (n) => String.fromCharCode(n.charCodeAt(0) - 65248)), G = (e) => X(e).replace(/\r\n?/g, `
221
222
  `).replace(/[\u2028\u2029]/g, `
222
- `).replace(B, "").replace(j, " ").replace(U, (o) => L[o] || "").replace(/ *\n */g, `
223
+ `).replace(k, "").replace(z, " ").replace(H, (n) => O[n] || "").replace(/ *\n */g, `
223
224
  `).replace(/\n{3,}/g, `
224
225
 
225
- `), pe = (e) => {
226
+ `), ge = (e) => {
226
227
  if (typeof window > "u" || !e)
227
228
  return e;
228
- const t = new DOMParser().parseFromString(e, "text/html"), n = t.createTreeWalker(t.body, NodeFilter.SHOW_TEXT);
229
- let s = n.nextNode();
229
+ const t = new DOMParser().parseFromString(e, "text/html"), o = t.createTreeWalker(t.body, NodeFilter.SHOW_TEXT);
230
+ let s = o.nextNode();
230
231
  for (; s; )
231
- s.textContent = H(s.textContent || ""), s = n.nextNode();
232
+ s.textContent = G(s.textContent || ""), s = o.nextNode();
232
233
  return t.body.innerHTML;
233
- }, k = {
234
+ }, W = {
234
235
  minSegmentLength: 32,
235
- maxSegmentLength: 128,
236
+ maxSegmentLength: 64,
236
237
  rebalanceRatio: 0.4
237
- }, F = /[一-鿿㐀-䶿豈-﫿 -〿＀-￯]/, X = /[。!?!?\.]/, G = /[;;]/, W = /[,,、::]/, K = /[。!?!?,,、;;::\.]/, O = "", R = "", p = (e) => {
238
- let o = 0;
238
+ }, L = /[一-鿿㐀-䶿豈-﫿 -〿＀-￯]/, I = /[。!?!?\.]/, P = /[;;]/, M = /[,,::]/, Y = /[、]/, R = "", S = "", p = (e) => {
239
+ let n = 0;
239
240
  for (const t of e)
240
- o += F.test(t) ? 2 : 1;
241
- return o;
242
- }, Y = (e) => e.replace(/\r/g, "").split(`
243
- `).map((o) => o.trim()).filter(Boolean).join(" ").replace(/\s+/g, " ").trim(), q = (e) => {
244
- let o = e, t = "";
245
- for (; t !== o; )
246
- t = o, o = o.replace(/(\d),(\d)/g, `$1${O}$2`);
247
- for (t = ""; t !== o; )
248
- t = o, o = o.replace(/(\d)\.(\d)/g, `$1${R}$2`);
249
- return o;
250
- }, b = (e) => e.split(O).join(",").split(R).join("."), E = (e, o) => {
241
+ n += L.test(t) ? 2 : 1;
242
+ return n;
243
+ }, K = (e) => e.replace(/\r/g, "").split(`
244
+ `).map((n) => n.trim()).filter(Boolean).join(" ").replace(/\s+/g, " ").trim(), q = (e) => {
245
+ let n = e, t = "";
246
+ for (; t !== n; )
247
+ t = n, n = n.replace(/(\d),(\d)/g, `$1${R}$2`);
248
+ for (t = ""; t !== n; )
249
+ t = n, n = n.replace(/(\d)\.(\d)/g, `$1${S}$2`);
250
+ return n;
251
+ }, b = (e) => e.split(R).join(",").split(S).join("."), E = (e, n) => {
251
252
  let t = 0;
252
- for (let n = 0; n < e.length; n += 1)
253
- if (t += F.test(e[n]) ? 2 : 1, t >= o)
254
- return n + 1;
253
+ for (let o = 0; o < e.length; o += 1)
254
+ if (t += L.test(e[o]) ? 2 : 1, t >= n)
255
+ return o + 1;
255
256
  return e.length;
256
- }, x = (e, o, t, n, s) => {
257
- let a = -1, r = Number.POSITIVE_INFINITY;
258
- const i = Math.max(1, t), c = Math.min(e.length, n);
259
- for (let l = i; l <= c; l += 1) {
260
- if (!s.test(e[l - 1]))
257
+ }, x = (e, n, t, o, s) => {
258
+ let l = -1, r = Number.POSITIVE_INFINITY;
259
+ const i = Math.max(1, t), c = Math.min(e.length - 1, o);
260
+ for (let a = i; a <= c; a += 1) {
261
+ if (!s.test(e[a - 1]))
261
262
  continue;
262
- const u = Math.abs(l - o);
263
- if (u < r && (r = u, a = l), l > o && a >= 0)
263
+ const u = Math.abs(a - n);
264
+ if (u < r && (r = u, l = a), a > n && l >= 0)
264
265
  break;
265
266
  }
266
- return a;
267
- }, P = (e, o, t, n) => {
268
- let s = -1, a = Number.POSITIVE_INFINITY;
269
- const r = Math.max(1, t), i = Math.min(e.length, n);
267
+ return l;
268
+ }, J = (e, n, t, o) => {
269
+ let s = -1, l = Number.POSITIVE_INFINITY;
270
+ const r = Math.max(1, t), i = Math.min(e.length - 1, o);
270
271
  for (let c = r; c <= i; c += 1) {
271
272
  if (e[c - 1] !== " ")
272
273
  continue;
273
- const l = Math.abs(c - o);
274
- if (l < a && (a = l, s = c), c > o && s >= 0)
274
+ const a = Math.abs(c - n);
275
+ if (a < l && (l = a, s = c), c > n && s >= 0)
275
276
  break;
276
277
  }
277
278
  return s;
278
- }, J = (e, o) => {
279
+ }, C = (e, n, t, o, s) => {
280
+ for (const r of s) {
281
+ const i = x(
282
+ e,
283
+ n,
284
+ t,
285
+ o,
286
+ r
287
+ );
288
+ if (i >= 0)
289
+ return i;
290
+ }
291
+ const l = J(
292
+ e,
293
+ n,
294
+ t,
295
+ o
296
+ );
297
+ return l >= 0 ? l : x(
298
+ e,
299
+ n,
300
+ t,
301
+ o,
302
+ Y
303
+ );
304
+ }, Z = (e, n) => {
279
305
  const t = [];
280
- let n = e.trim();
281
- for (; n && p(n) > o; ) {
282
- const s = p(n), a = Math.min(
306
+ let o = e.trim();
307
+ for (; o && p(o) > n; ) {
308
+ const s = p(o), l = Math.min(
283
309
  Math.floor(s / 2),
284
- o
285
- ), r = E(n, a), i = Math.max(1, Math.floor(r / 3)), c = Math.max(
310
+ n
311
+ ), r = E(o, l), i = Math.max(1, Math.floor(r / 3)), c = Math.max(
286
312
  r + 1,
287
- E(n, o)
313
+ E(o, n)
288
314
  );
289
- let l = x(
290
- n,
315
+ let a = C(
316
+ o,
291
317
  r,
292
318
  i,
293
319
  c,
294
- G
320
+ [P, M]
295
321
  );
296
- l < 0 && (l = x(
297
- n,
298
- r,
299
- i,
300
- c,
301
- W
302
- )), l < 0 && (l = P(
303
- n,
304
- r,
305
- i,
306
- c
307
- )), (l < 0 || l >= n.length) && (l = r), t.push(n.slice(0, l).trim()), n = n.slice(l).trim();
322
+ (a < 0 || a >= o.length) && (a = r), t.push(o.slice(0, a).trim()), o = o.slice(a).trim();
308
323
  }
309
- return n && t.push(n), t;
310
- }, Z = (e, o) => {
324
+ return o && t.push(o), t;
325
+ }, Q = (e, n) => {
311
326
  if (e.length <= 1)
312
327
  return e;
313
- const t = e[e.length - 1], n = e.reduce((m, T) => m + p(T), 0) / e.length, s = Math.floor(n * o);
328
+ const t = e[e.length - 1], o = e.reduce((T, m) => T + p(m), 0) / e.length, s = Math.floor(o * n);
314
329
  if (p(t) >= s)
315
330
  return e;
316
- const r = `${e[e.length - 2]}${t}`, i = Math.floor(p(r) / 2), c = E(r, i), l = Math.max(1, Math.floor(c / 3));
317
- let u = x(
331
+ const r = `${e[e.length - 2]}${t}`, i = Math.floor(p(r) / 2), c = E(r, i), a = Math.max(1, Math.floor(c / 3));
332
+ let u = C(
318
333
  r,
319
334
  c,
320
- l,
335
+ a,
321
336
  r.length,
322
- K
337
+ [I, P, M]
323
338
  );
324
- if (u < 0 && (u = P(
325
- r,
326
- c,
327
- l,
328
- r.length
329
- )), u <= 0 || u >= r.length)
339
+ if (u <= 0 || u >= r.length)
330
340
  return e;
331
341
  const g = [...e];
332
342
  return g[g.length - 2] = r.slice(0, u).trim(), g[g.length - 1] = r.slice(u).trim(), g.filter(Boolean);
333
- }, Q = (e, o = {}) => {
343
+ }, ee = (e, n = {}) => {
334
344
  const t = {
335
- ...k,
336
- ...o
337
- }, n = Y(e);
338
- if (!n)
345
+ ...W,
346
+ ...n
347
+ }, o = K(e);
348
+ if (!o)
339
349
  return [];
340
- const s = q(n);
350
+ const s = q(o);
341
351
  if (p(s) <= t.minSegmentLength)
342
352
  return [b(s)];
343
- const a = [], r = s.split(new RegExp("(?<=[。!?!?\\.])"));
353
+ const l = [], r = s.split(new RegExp("(?<=[。!?!?\\.])"));
344
354
  let i = "";
345
- for (const l of r) {
346
- if (!l)
355
+ for (const a of r) {
356
+ if (!a)
347
357
  continue;
348
- i += l;
358
+ i += a;
349
359
  const u = i[i.length - 1] ?? "";
350
- p(i) >= t.minSegmentLength && X.test(u) && (a.push(i.trim()), i = "");
360
+ p(i) >= t.minSegmentLength && I.test(u) && (l.push(i.trim()), i = "");
351
361
  }
352
- i && (a.length > 0 && p(i) < t.minSegmentLength ? a[a.length - 1] += i : a.push(i.trim()));
353
- const c = a.flatMap((l) => p(l) <= t.maxSegmentLength ? [l] : J(l, t.maxSegmentLength));
354
- return Z(
362
+ i && (l.length > 0 && p(i) < t.minSegmentLength ? l[l.length - 1] += i : l.push(i.trim()));
363
+ const c = l.flatMap((a) => p(a) <= t.maxSegmentLength ? [a] : Z(a, t.maxSegmentLength));
364
+ return Q(
355
365
  c,
356
366
  t.rebalanceRatio
357
367
  ).map(b);
358
- }, M = (e) => e.type === "text" ? e.text || "" : (e.content || []).map(M).join(""), ee = (e) => {
359
- const o = e.content || [];
368
+ }, A = (e) => e.type === "text" ? e.text || "" : (e.content || []).map(A).join(""), te = (e) => {
369
+ const n = e.content || [];
360
370
  let t = "";
361
- const n = [], s = [], a = {
371
+ const o = [], s = [], l = {
362
372
  [h.stop.type]: ({ position: r, actionCode: i }) => {
363
- n.push({
373
+ o.push({
364
374
  action: "insert",
365
375
  model: "control",
366
376
  payload: "。 ",
@@ -370,7 +380,7 @@ const ue = [
370
380
  });
371
381
  },
372
382
  [h.customStop.type]: ({ payload: r, position: i, actionCode: c }) => {
373
- n.push({
383
+ o.push({
374
384
  action: "insert",
375
385
  model: "control",
376
386
  payload: `[stop:${r == null ? void 0 : r.time}]`,
@@ -380,7 +390,7 @@ const ue = [
380
390
  });
381
391
  },
382
392
  [h.continue.type]: ({ position: r, text: i, actionCode: c }) => {
383
- n.push({
393
+ o.push({
384
394
  action: "replace",
385
395
  model: "replace",
386
396
  payload: `《${i}》`,
@@ -393,40 +403,40 @@ const ue = [
393
403
  payload: r,
394
404
  position: i,
395
405
  text: c,
396
- actionCode: l
406
+ actionCode: a
397
407
  }) => {
398
- n.push({
408
+ o.push({
399
409
  action: "replace",
400
410
  model: "replace",
401
411
  payload: `${r == null ? void 0 : r.text}`,
402
412
  position: i,
403
413
  text: c,
404
- actionCode: l
414
+ actionCode: a
405
415
  });
406
416
  },
407
- [h.pinyin.type]: ({ payload: r, position: i, text: c, actionCode: l }) => {
408
- n.push({
417
+ [h.pinyin.type]: ({ payload: r, position: i, text: c, actionCode: a }) => {
418
+ o.push({
409
419
  action: "replace",
410
420
  model: "pinyin",
411
421
  payload: `${r == null ? void 0 : r.text}`,
412
422
  position: i,
413
423
  text: c,
414
- actionCode: l
424
+ actionCode: a
415
425
  });
416
426
  },
417
427
  [h.language.type]: ({
418
428
  payload: r,
419
429
  position: i,
420
430
  text: c,
421
- actionCode: l
431
+ actionCode: a
422
432
  }) => {
423
- n.push({
433
+ o.push({
424
434
  action: "language",
425
435
  model: "language",
426
436
  payload: `${r == null ? void 0 : r.code}`,
427
437
  position: i,
428
438
  text: c,
429
- actionCode: l
439
+ actionCode: a
430
440
  });
431
441
  },
432
442
  [h.ignore.type]: ({
@@ -434,7 +444,7 @@ const ue = [
434
444
  text: i,
435
445
  actionCode: c
436
446
  }) => {
437
- n.push({
447
+ o.push({
438
448
  action: "replace",
439
449
  model: "replace",
440
450
  payload: " ",
@@ -444,113 +454,113 @@ const ue = [
444
454
  });
445
455
  }
446
456
  };
447
- return o.forEach((r) => {
448
- var m, T;
457
+ return n.forEach((r) => {
458
+ var T, m;
449
459
  if (r.type === "text") {
450
460
  t += r.text || "";
451
461
  return;
452
462
  }
453
463
  if (r.type !== "customTag") return;
454
- const i = (m = r.attrs) == null ? void 0 : m.categ, c = (T = r.attrs) == null ? void 0 : T.payload, l = t.length, u = M(r), g = a[i];
464
+ const i = (T = r.attrs) == null ? void 0 : T.categ, c = (m = r.attrs) == null ? void 0 : m.payload, a = t.length, u = A(r), g = l[i];
455
465
  u && s.push({
456
- start: l,
457
- end: l + u.length
466
+ start: a,
467
+ end: a + u.length
458
468
  }), g && g({
459
469
  payload: c,
460
- position: l,
470
+ position: a,
461
471
  text: u,
462
472
  actionCode: i
463
473
  }), t += u;
464
474
  }), {
465
475
  text: t,
466
476
  protectedRanges: s,
467
- playments: n
477
+ playments: o
468
478
  };
469
- }, N = (e) => e.type === "text" || e.type === "customTag", te = (e) => {
470
- const o = e.content || [];
479
+ }, N = (e) => e.type === "text" || e.type === "customTag", ne = (e) => {
480
+ const n = e.content || [];
471
481
  if (e.type === "paragraph") return [e];
472
482
  if (e.type === "doc")
473
- return o.filter((n) => n.type === "paragraph");
474
- const t = o.filter(
475
- (n) => n.type === "paragraph"
483
+ return n.filter((o) => o.type === "paragraph");
484
+ const t = n.filter(
485
+ (o) => o.type === "paragraph"
476
486
  );
477
- return t.length ? t : o.some(N) ? [
487
+ return t.length ? t : n.some(N) ? [
478
488
  {
479
489
  type: "paragraph",
480
- content: o.filter(N)
490
+ content: n.filter(N)
481
491
  }
482
492
  ] : [];
483
- }, ne = (e, o) => {
493
+ }, oe = (e, n) => {
484
494
  let t = 0;
485
- return o.map((n) => {
486
- const s = e.indexOf(n, t), a = s >= 0 ? s : t, r = a + n.length;
495
+ return n.map((o) => {
496
+ const s = e.indexOf(o, t), l = s >= 0 ? s : t, r = l + o.length;
487
497
  return t = r, {
488
- text: n,
489
- start: a,
498
+ text: o,
499
+ start: l,
490
500
  end: r
491
501
  };
492
502
  });
493
- }, oe = (e, o) => e.reduce((t, n) => {
494
- if (o.some(
495
- (a) => n.start > a.start && n.start < a.end
503
+ }, re = (e, n) => e.reduce((t, o) => {
504
+ if (n.some(
505
+ (l) => o.start > l.start && o.start < l.end
496
506
  ) && t.length) {
497
- const a = t[t.length - 1];
498
- return a.text += n.text, a.end = n.end, t;
507
+ const l = t[t.length - 1];
508
+ return l.text += o.text, l.end = o.end, t;
499
509
  }
500
- return t.push({ ...n }), t;
501
- }, []), re = (e, o, t, n) => e.position >= o && e.position < t ? !0 : !e.text && n && e.position === t, se = (e) => {
502
- const o = Q(e.text);
503
- if (o.length <= 1) return [e];
504
- const t = oe(
505
- ne(e.text, o),
510
+ return t.push({ ...o }), t;
511
+ }, []), se = (e, n, t, o) => e.position >= n && e.position < t ? !0 : !e.text && o && e.position === t, ie = (e) => {
512
+ const n = ee(e.text);
513
+ if (n.length <= 1) return [e];
514
+ const t = re(
515
+ oe(e.text, n),
506
516
  e.protectedRanges || []
507
517
  );
508
- return t.map((n, s) => {
509
- const a = s === t.length - 1, r = e.playments.filter(
510
- (i) => re(
518
+ return t.map((o, s) => {
519
+ const l = s === t.length - 1, r = e.playments.filter(
520
+ (i) => se(
511
521
  i,
512
- n.start,
513
- n.end,
514
- a
522
+ o.start,
523
+ o.end,
524
+ l
515
525
  )
516
526
  ).map((i) => ({
517
527
  ...i,
518
- position: i.position - n.start
528
+ position: i.position - o.start
519
529
  }));
520
530
  return {
521
- text: n.text,
531
+ text: o.text,
522
532
  playments: r
523
533
  };
524
534
  });
525
- }, ge = (e) => {
526
- const o = {
535
+ }, he = (e) => {
536
+ const n = {
527
537
  playments: [],
528
538
  sentences: []
529
539
  };
530
- return te(e).forEach((n) => {
531
- const s = ee(n);
532
- !s.text && !s.playments.length || se(s).forEach(({ text: a, playments: r }) => {
533
- o.sentences.push(a), o.playments.push(r);
540
+ return ne(e).forEach((o) => {
541
+ const s = te(o);
542
+ !s.text && !s.playments.length || ie(s).forEach(({ text: l, playments: r }) => {
543
+ n.sentences.push(l), n.playments.push(r);
534
544
  });
535
- }), o;
545
+ }), n;
536
546
  };
537
547
  export {
538
548
  f as DeleteMode,
539
549
  _ as LanguageOptions,
540
- ue as NumberToTextTools,
541
- ie as StopOptions,
550
+ pe as NumberToTextTools,
551
+ le as StopOptions,
542
552
  h as ToolConfig,
543
- S as allToolTypes,
544
- ge as convertToTtsFormat,
545
- ae as getInitContent,
553
+ v as allToolTypes,
554
+ he as convertToTtsFormat,
555
+ ce as getInitContent,
546
556
  p as getVisualLength,
547
- le as resolveTtsEditorFeatures,
548
- pe as sanitizePastedHtml,
549
- H as sanitizePastedText,
550
- Q as splitTextToSentences,
551
- w as toCardinal,
552
- $ as toColloquial,
553
- ce as toPhoneReading,
554
- I as toPositional,
555
- ee as transformParagraph
557
+ ae as resolveTtsEditorFeatures,
558
+ ge as sanitizePastedHtml,
559
+ G as sanitizePastedText,
560
+ ee as splitTextToSentences,
561
+ B as toCardinal,
562
+ j as toColloquial,
563
+ ue as toPhoneReading,
564
+ F as toPositional,
565
+ te as transformParagraph
556
566
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naersen/tts-rich-text",
3
- "version": "0.6.0",
3
+ "version": "0.7.1",
4
4
  "description": "Reusable Vue 3 rich-text editor for TTS workflows",
5
5
  "type": "module",
6
6
  "files": [