echogarden 3.0.4 → 3.1.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.
Files changed (39) hide show
  1. package/data/lexicons/heteronyms.en.json +1 -1
  2. package/data/lexicons/words.en.json +88 -0
  3. package/dist/alignment/SemanticTextAlignment.js +2 -2
  4. package/dist/alignment/SemanticTextAlignment.js.map +1 -1
  5. package/dist/api/Alignment.js +2 -2
  6. package/dist/api/Alignment.js.map +1 -1
  7. package/dist/nlp/Segmentation.d.ts +2 -8
  8. package/dist/nlp/Segmentation.d.ts.map +1 -1
  9. package/dist/nlp/Segmentation.js +39 -19
  10. package/dist/nlp/Segmentation.js.map +1 -1
  11. package/dist/nlp/TextNormalizer.d.ts.map +1 -1
  12. package/dist/nlp/TextNormalizer.js +22 -14
  13. package/dist/nlp/TextNormalizer.js.map +1 -1
  14. package/dist/recognition/AmazonTranscribeSTT.js +3 -3
  15. package/dist/recognition/AmazonTranscribeSTT.js.map +1 -1
  16. package/dist/synthesis/EspeakTTS.d.ts.map +1 -1
  17. package/dist/synthesis/EspeakTTS.js +14 -7
  18. package/dist/synthesis/EspeakTTS.js.map +1 -1
  19. package/dist/synthesis/KokoroTTS.d.ts.map +1 -1
  20. package/dist/synthesis/KokoroTTS.js +0 -5
  21. package/dist/synthesis/KokoroTTS.js.map +1 -1
  22. package/dist/synthesis/VitsTTS.d.ts.map +1 -1
  23. package/dist/synthesis/VitsTTS.js +0 -5
  24. package/dist/synthesis/VitsTTS.js.map +1 -1
  25. package/dist/utilities/Timeline.js +2 -2
  26. package/dist/utilities/Timeline.js.map +1 -1
  27. package/dist/utilities/WikipediaReader.js +5 -5
  28. package/dist/utilities/WikipediaReader.js.map +1 -1
  29. package/package.json +12 -12
  30. package/src/alignment/SemanticTextAlignment.ts +2 -2
  31. package/src/api/Alignment.ts +2 -2
  32. package/src/nlp/Segmentation.ts +49 -19
  33. package/src/nlp/TextNormalizer.ts +29 -16
  34. package/src/recognition/AmazonTranscribeSTT.ts +3 -3
  35. package/src/synthesis/EspeakTTS.ts +16 -8
  36. package/src/synthesis/KokoroTTS.ts +0 -6
  37. package/src/synthesis/VitsTTS.ts +0 -6
  38. package/src/utilities/Timeline.ts +2 -2
  39. package/src/utilities/WikipediaReader.ts +5 -5
@@ -14,7 +14,7 @@ import { type WhisperAlignmentOptions } from '../recognition/WhisperSTT.js'
14
14
  import { DtwGranularity, createAlignmentReferenceUsingEspeak } from '../alignment/SpeechAlignment.js'
15
15
  import { type SubtitlesConfig } from '../subtitles/Subtitles.js'
16
16
  import { type EspeakOptions, defaultEspeakOptions } from '../synthesis/EspeakTTS.js'
17
- import { isWord } from '../nlp/Segmentation.js'
17
+ import { includesWordCharacter } from '../nlp/Segmentation.js'
18
18
 
19
19
  const log = logToStderr
20
20
 
@@ -264,7 +264,7 @@ export async function align(input: AudioSourceParam, transcript: string, options
264
264
  logger.log('')
265
265
 
266
266
  // Remove non-word entries from recognition timeline
267
- recognitionTimeline = recognitionTimeline.filter(entry => isWord(entry.text))
267
+ recognitionTimeline = recognitionTimeline.filter(entry => includesWordCharacter(entry.text))
268
268
 
269
269
  // Synthesize the ground-truth transcript and get its timeline
270
270
  logger.start('Synthesize ground-truth transcript with eSpeak')
@@ -1,7 +1,8 @@
1
1
  import { sumArray, logToStderr } from '../utilities/Utilities.js'
2
2
  import { getShortLanguageCode } from '../utilities/Locale.js'
3
3
  import { ParagraphBreakType, WhitespaceProcessing } from '../api/Common.js'
4
- import { includesAnyOf, splitAndPreserveSeparators } from '../utilities/StringUtilities.js'
4
+ import { splitAndPreserveSeparators } from '../utilities/StringUtilities.js'
5
+ import { anyOf, buildRegExp, unicodeProperty, oneOrMore, possibly, codepoint, inputStart, inputEnd, whitespace } from 'regexp-composer'
5
6
 
6
7
  import * as TextSegmentation from '@echogarden/text-segmentation'
7
8
  import { splitChineseTextToWords_Jieba } from './ChineseSegmentation.js'
@@ -9,50 +10,77 @@ import { splitJapaneseTextToWords_Kuromoji } from './JapaneseSegmentation.js'
9
10
 
10
11
  const log = logToStderr
11
12
 
12
- export const wordCharacterRegExp = /[\p{Letter}\p{Number}]/u
13
+ const includesWordCharacterPattern = anyOf(unicodeProperty('Letter'), unicodeProperty('Number'))
14
+ const includesWordCharacterRegExp = buildRegExp(includesWordCharacterPattern)
13
15
 
14
16
  // See: https://mathiasbynens.be/notes/es-unicode-property-escapes
15
- export const emojiSequenceRegExp = /\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/u
17
+ //export const emojiSequenceRegExp = /\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/u
18
+ const includesEmojiSequencePattern = anyOf(
19
+ [unicodeProperty('Emoji_Modifier_Base'), possibly(unicodeProperty('Emoji_Modifier'))],
20
+ unicodeProperty('Emoji_Presentation'),
21
+ [unicodeProperty('Emoji'), codepoint('FE0F')]
22
+ )
23
+ const includesEmojiSequenceRegExp = buildRegExp(includesEmojiSequencePattern)
16
24
 
17
- export const includesPunctuationRegExp = /[\p{Punctuation}]/u
18
- export const isAllPunctuationRegExp = /^[\p{Punctuation}]+$/u
25
+ const symbolWordsList = ['$', '€', '¢', '£', '¥', '©', '®', '™', '%', '&', '#', '~', '@', '+', '±', '÷', '/', '\\', '^', '*', '×', '=', '≈', '¼', '½', '¾', '→', '≤', '≥']
26
+ const includesSymbolWordPattern = anyOf(...symbolWordsList)
27
+ const includesSymbolWordRegExp = buildRegExp(includesSymbolWordPattern)
19
28
 
20
- export const phraseSeparators = [',', '、', ',', '،', ';', ';', ':', ':', '—']
21
- export const symbolWords = ['$', '€', '¢', '£', '¥', '©', '®', '™', '%', '&', '#', '~', '@', '+', '±', '÷', '/', '\\', '^', '*', '×', '=', '≈', '¼', '½', '¾', '→', '≤', '≥']
29
+ const isAllSymbolWordsPattern = [inputStart, oneOrMore(includesSymbolWordPattern), inputEnd]
30
+ const isAllSymbolWordsRegExp = buildRegExp(isAllSymbolWordsPattern)
31
+
32
+ const includesWordCharacterOrEmojiPattern = anyOf(includesWordCharacterPattern, includesEmojiSequencePattern)
33
+ const includesWordCharacterOrEmojiRegExp = buildRegExp(includesWordCharacterOrEmojiPattern)
34
+
35
+ const includesWordCharacterOrEmojiOrIsAllSymbolWordPattern = anyOf(includesWordCharacterPattern, includesEmojiSequencePattern, isAllSymbolWordsPattern)
36
+ const includesWordCharacterOrEmojiOrIsAllSymbolWordRegExp = buildRegExp(includesWordCharacterOrEmojiOrIsAllSymbolWordPattern)
37
+
38
+ const includesPunctuationPattern = unicodeProperty('Punctuation')
39
+ const includesPunctuationRegExp = buildRegExp(includesPunctuationPattern)
40
+
41
+ const isAllPunctuationPattern = [inputStart, oneOrMore(includesPunctuationPattern), inputEnd]
42
+ const isAllPunctuationRegExp = buildRegExp(isAllPunctuationPattern)
43
+
44
+ const phraseSeparatorsList = [',', '、', ',', '،', ';', ';', ':', ':', '—']
45
+ const includesPhraseSeparatorsPattern = anyOf(...phraseSeparatorsList)
46
+ const includesPhraseSeparatorsRegExp = buildRegExp(includesPhraseSeparatorsPattern)
47
+
48
+ const isAllWhitespacePattern = [inputStart, oneOrMore(whitespace), inputEnd]
49
+ const isAllWhitespaceRegExp = buildRegExp(isAllWhitespacePattern)
22
50
 
23
51
  ///////////////////////////////////////////////////////////////////////////////////////////////
24
52
  // Predicates
25
53
  ///////////////////////////////////////////////////////////////////////////////////////////////
26
54
  export function isWordOrEmojiOrSymbolWord(str: string) {
27
- return isWordOrEmoji(str) || symbolWords.includes(str)
55
+ return includesWordCharacterOrEmojiOrIsAllSymbolWordRegExp.test(str.trim())
28
56
  }
29
57
 
30
58
  export function isWordOrEmoji(str: string) {
31
- return isWord(str) || includesEmoji(str)
59
+ return includesWordCharacterOrEmojiRegExp.test(str.trim())
32
60
  }
33
61
 
34
62
  export function isSymbolWord(str: string) {
35
- return symbolWords.includes(str?.trim())
63
+ return isAllSymbolWordsRegExp.test(str.trim())
36
64
  }
37
65
 
38
- export function isWord(str: string) {
39
- return wordCharacterRegExp.test(str?.trim())
66
+ export function includesWordCharacter(str: string) {
67
+ return includesWordCharacterRegExp.test(str.trim())
40
68
  }
41
69
 
42
70
  export function includesPunctuation(str: string) {
43
- return includesPunctuationRegExp.test(str?.trim())
71
+ return includesPunctuationRegExp.test(str.trim())
44
72
  }
45
73
 
46
74
  export function isAllPunctuation(str: string) {
47
- return isAllPunctuationRegExp.test(str?.trim())
75
+ return isAllPunctuationRegExp.test(str.trim())
48
76
  }
49
77
 
50
78
  export function includesEmoji(str: string) {
51
- return emojiSequenceRegExp.test(str?.trim())
79
+ return includesEmojiSequenceRegExp.test(str.trim())
52
80
  }
53
81
 
54
82
  export function isAllWhitespace(str: string) {
55
- return str && /^\s+$/.test(str)
83
+ return isAllWhitespaceRegExp.test(str)
56
84
  }
57
85
 
58
86
  ///////////////////////////////////////////////////////////////////////////////////////////////
@@ -280,11 +308,13 @@ export class Word {
280
308
  this.isSentenceFinalizer = isSentenceFinalizer
281
309
  }
282
310
 
283
- get containsOnlyPunctuation() { return !wordCharacterRegExp.test(this.text) && !this.isSymbolWord }
311
+ get containsOnlyPunctuation() { return !isWordOrEmojiOrSymbolWord(this.text) }
284
312
 
285
- get isSymbolWord() { return symbolWords.includes(this.text) }
313
+ get isSymbolWord() { return isSymbolWord(this.text) }
286
314
 
287
- get isPhraseSeperator() { return this.containsOnlyPunctuation && includesAnyOf(this.text, phraseSeparators) }
315
+ get isPhraseSeperator() {
316
+ return this.containsOnlyPunctuation && includesPhraseSeparatorsRegExp.test(this.text)
317
+ }
288
318
 
289
319
  get length() { return this.text.length }
290
320
  }
@@ -1,6 +1,6 @@
1
1
  import { getShortLanguageCode } from '../utilities/Locale.js'
2
2
  import { substituteCharactersUsingLookup } from '../utilities/StringUtilities.js'
3
- import { anyOf, buildRegExp, charRange, inputEnd, inputStart, repeated, zeroOrMore } from 'regexp-composer'
3
+ import { anyOf, buildRegExp, charRange, inputEnd, inputStart, oneOrMore, repeated, unicodeProperty, zeroOrMore } from 'regexp-composer'
4
4
 
5
5
  export function getNormalizedFragmentsForSpeech(
6
6
  words: string[],
@@ -25,14 +25,24 @@ export function getNormalizedFragmentsForSpeech(
25
25
  const nextNonWhitespaceWord = nextNonWhitespaceWords[0]
26
26
 
27
27
  const originalWordIndex = nonWhitespaceWordOriginalIndex[wordIndex]
28
+
28
29
  const isFollowedByWhitespace = words[originalWordIndex + 1]?.trim().length === 0
30
+ const isSpecialCharacterBeforeYear = ['(', ',', '©'].includes(words[originalWordIndex])
29
31
 
30
- if (wordsPrecedingAYear.includes(lowerCaseWord) &&
31
- isFollowedByWhitespace &&
32
- fourDigitYearPatternRegExp.test(nextNonWhitespaceWord)) {
32
+ //const isWordPrecedingAYear = wordsPrecedingAYear.includes(lowerCaseWord)
33
+ const isWordPrecedingAYear =
34
+ isAllLettersRegExp.test(lowerCaseWord) || isSpecialCharacterBeforeYear
35
+
36
+ const followedByFourDigitYearPattern = fourDigitYearRegExp.test(nextNonWhitespaceWord)
33
37
 
34
- // Normalize a four digit year pattern, e.g. 'in 1995'.
38
+ const isWordPrecedingADecade = wordsPrecedingADecade.includes(lowerCaseWord)
39
+ const followedByFourDigitDecadePattern = fourDigitDecadeRegExp.test(nextNonWhitespaceWord)
35
40
 
41
+ if (isWordPrecedingAYear &&
42
+ (isFollowedByWhitespace || isSpecialCharacterBeforeYear) &&
43
+ followedByFourDigitYearPattern) {
44
+
45
+ // Normalize a four digit year pattern, e.g. 'in 1995'.
36
46
  const normalizedString = normalizeFourDigitYearString(nextNonWhitespaceWord)
37
47
 
38
48
  normalizedFragments.push(word)
@@ -43,11 +53,11 @@ export function getNormalizedFragmentsForSpeech(
43
53
 
44
54
  wordIndex += 1
45
55
  } else if (
46
- wordsPrecedingADecade.includes(lowerCaseWord) &&
56
+ isWordPrecedingADecade &&
47
57
  isFollowedByWhitespace &&
48
- fourDigitDecadePatternRegExp.test(nextNonWhitespaceWord)) {
58
+ followedByFourDigitDecadePattern) {
49
59
 
50
- // Normalize a four digit decade pattern, e.g. 'the 1980s'.
60
+ // Normalize a four digit decade pattern, e.g. 'the 1980s'.
51
61
 
52
62
  const normalizedString = normalizeFourDigitDecadeString(nextNonWhitespaceWord)
53
63
 
@@ -58,7 +68,7 @@ export function getNormalizedFragmentsForSpeech(
58
68
  referenceFragments.push(nextNonWhitespaceWord)
59
69
 
60
70
  wordIndex += 1
61
- } else if (fourDigitYearRangePatternRegExp.test(words.slice(originalWordIndex, originalWordIndex + 3).join(''))) {
71
+ } else if (fourDigitYearRangeRegExp.test(words.slice(originalWordIndex, originalWordIndex + 3).join(''))) {
62
72
  // Normalize a year range pattern, e.g. '1835-1896', ensure there are no spaces between words
63
73
  normalizedFragments.push(normalizeFourDigitYearString(nonWhitespaceWords[wordIndex]))
64
74
  referenceFragments.push(nonWhitespaceWords[wordIndex])
@@ -92,7 +102,7 @@ export function getNormalizedFragmentsForSpeech(
92
102
  const referenceString = word
93
103
  referenceFragments.push(referenceString)
94
104
  }
95
- } else if (followingCurrencyPatternRegExp.test(lowerCaseWord)) {
105
+ } else if (followingCurrencyRegExp.test(lowerCaseWord)) {
96
106
  const currencyWord = currencySymbolsAsWords[currencySymbols.indexOf(lowerCaseWord[lowerCaseWord.length - 1])]
97
107
 
98
108
  const normalizedString = `${word.substring(0, word.length - 1)} ${currencyWord}`
@@ -234,14 +244,14 @@ const wordsFollowingACurrency = [
234
244
 
235
245
  const arabicNumeralPattern = charRange('0', '9')
236
246
 
237
- const numberPattern = [
247
+ const isNumberPattern = [
238
248
  inputStart,
239
249
  arabicNumeralPattern,
240
250
  zeroOrMore(anyOf(arabicNumeralPattern, ',', '.')),
241
251
  inputEnd
242
252
  ]
243
253
 
244
- const numberPatternRegExp = buildRegExp(numberPattern)
254
+ const isNumberRegExp = buildRegExp(isNumberPattern)
245
255
 
246
256
  const precedingCurrencyPattern = [
247
257
  inputStart,
@@ -261,13 +271,16 @@ const followingCurrencyPattern = [
261
271
  inputEnd
262
272
  ]
263
273
 
264
- const followingCurrencyPatternRegExp = buildRegExp(followingCurrencyPattern)
274
+ const followingCurrencyRegExp = buildRegExp(followingCurrencyPattern)
265
275
 
266
276
  const fourDigitYearPattern = [inputStart, repeated(4, arabicNumeralPattern), inputEnd]
267
- const fourDigitYearPatternRegExp = buildRegExp(fourDigitYearPattern)
277
+ const fourDigitYearRegExp = buildRegExp(fourDigitYearPattern)
268
278
 
269
279
  const fourDigitDecadePattern = [inputStart, repeated(3, arabicNumeralPattern), '0s', inputEnd]
270
- const fourDigitDecadePatternRegExp = buildRegExp(fourDigitDecadePattern)
280
+ const fourDigitDecadeRegExp = buildRegExp(fourDigitDecadePattern)
271
281
 
272
282
  const fourDigitYearRangePattern = [inputStart, repeated(4, arabicNumeralPattern), anyOf('-', '–'), repeated(4, arabicNumeralPattern), inputEnd]
273
- const fourDigitYearRangePatternRegExp = buildRegExp(fourDigitYearRangePattern)
283
+ const fourDigitYearRangeRegExp = buildRegExp(fourDigitYearRangePattern)
284
+
285
+ const isAllLettersPattern = [inputStart, oneOrMore(unicodeProperty('Letter')), inputEnd]
286
+ const isAllLettersRegExp = buildRegExp(isAllLettersPattern)
@@ -1,6 +1,6 @@
1
- import { Item, LanguageCode, StartStreamTranscriptionCommandInput } from '@aws-sdk/client-transcribe-streaming'
2
- import { wordCharacterRegExp } from '../nlp/Segmentation.js'
3
1
  import * as FFMpegTranscoder from '../codecs/FFMpegTranscoder.js'
2
+ import { Item, LanguageCode, StartStreamTranscriptionCommandInput } from '@aws-sdk/client-transcribe-streaming'
3
+ import { isWordOrEmojiOrSymbolWord } from '../nlp/Segmentation.js'
4
4
  import { Logger } from '../utilities/Logger.js'
5
5
  import { Timeline } from '../utilities/Timeline.js'
6
6
  import { RawAudio } from '../audio/AudioUtilities.js'
@@ -103,7 +103,7 @@ export async function recgonize(rawAudio: RawAudio, languageCode: string, region
103
103
  for (const event of events) {
104
104
  const text = event.Content!
105
105
 
106
- if (!wordCharacterRegExp.test(text)) {
106
+ if (!isWordOrEmojiOrSymbolWord(text)) {
107
107
  continue
108
108
  }
109
109
 
@@ -4,7 +4,7 @@ import { Logger } from '../utilities/Logger.js'
4
4
  import { RawAudio, getEmptyRawAudio } from '../audio/AudioUtilities.js'
5
5
  import { getNormalizedFragmentsForSpeech, simplifyPunctuationCharacters } from '../nlp/TextNormalizer.js'
6
6
  import { ipaPhoneToKirshenbaum } from '../nlp/PhoneConversion.js'
7
- import { isAllPunctuation, isWord, isWordOrEmoji, splitToWords, wordCharacterRegExp } from '../nlp/Segmentation.js'
7
+ import { isAllPunctuation, isWordOrEmoji, splitToWords, isWordOrEmojiOrSymbolWord } from '../nlp/Segmentation.js'
8
8
  import { Lexicon, tryGetFirstLexiconSubstitution } from '../nlp/Lexicon.js'
9
9
  import { phonemizeSentence } from '../nlp/EspeakPhonemizer.js'
10
10
  import { Timeline, TimelineEntry } from '../utilities/Timeline.js'
@@ -12,7 +12,7 @@ import { extendDeep } from '../utilities/ObjectUtilities.js'
12
12
  import { escapeHtml } from '../encodings/HtmlEscape.js'
13
13
  import * as TextSegmentation from '@echogarden/text-segmentation'
14
14
 
15
- import { getGlobalOption, OperationCallbacks, SynthesisCallbacks } from '../api/API.js'
15
+ import { OperationCallbacks, SynthesisCallbacks } from '../api/API.js'
16
16
  import { loadPackage } from '../utilities/PackageManager.js'
17
17
 
18
18
  import { wrapEmscriptenModuleHeap } from 'wasm-heap-manager'
@@ -73,11 +73,14 @@ export async function preprocessAndSynthesize(text: string, language: string, es
73
73
  for (let i = 0; i < mergedWords.length; i++) {
74
74
  const mergedWord = mergedWords[i]
75
75
 
76
- // Convert isolated groups of vertical bars and em dashes to a comma
77
76
  if (/^[\|│—─–]+$/.test(mergedWord)) {
77
+ // Convert isolated groups of vertical bars or em dashes to a comma
78
78
  mergedWords[i] = ','
79
- } else if (isAllPunctuation(mergedWord)) { // Collapse repeated punctuation
80
- mergedWords[i] = mergedWord[0]
79
+ } else if (isAllPunctuation(mergedWord)) {
80
+ // Collapse repeated punctuation to up to 3 repetitions,
81
+ // Since otherwise eSpeak may go crazy.
82
+
83
+ mergedWords[i] = mergedWord.substring(0, Math.min(3, mergedWord.length))
81
84
  }
82
85
  }
83
86
 
@@ -102,7 +105,12 @@ export async function preprocessAndSynthesize(text: string, language: string, es
102
105
 
103
106
  const { normalizedFragments, referenceFragments } = getNormalizedFragmentsForSpeech(words, nonWhitespaceWords, nonWhitespaceWordsOriginalIndex, language)
104
107
 
105
- const simplifiedFragments = normalizedFragments.map(word => simplifyPunctuationCharacters(word).toLocaleLowerCase())
108
+ const simplifiedFragments = normalizedFragments.map(word => {
109
+ return simplifyPunctuationCharacters(word)
110
+ .toLocaleLowerCase()
111
+ .replaceAll('(', ',')
112
+ .replaceAll(')', ',')
113
+ })
106
114
 
107
115
  if ([`'`].includes(simplifiedFragments[0])) {
108
116
  normalizedFragments[0] = `()`
@@ -150,8 +158,8 @@ export async function preprocessAndSynthesize(text: string, language: string, es
150
158
  {
151
159
  const fragmentWordSequence = new TextSegmentation.WordSequence()
152
160
 
153
- for (let fragment of fragments) {
154
- fragmentWordSequence.addWord(fragment, 0, !wordCharacterRegExp.test(fragment))
161
+ for (let fragment of simplifiedFragments) {
162
+ fragmentWordSequence.addWord(fragment, 0, !isWordOrEmojiOrSymbolWord(fragment))
155
163
  }
156
164
 
157
165
  const wordEntries = referenceTimeline.flatMap(phraseEntry => phraseEntry.timeline!)
@@ -72,12 +72,6 @@ export class KokoroTTS {
72
72
  const voicePrimaryLanguage = voice.languages[0]
73
73
  const voicePrimaryLanguageShort = getShortLanguageCode(voicePrimaryLanguage)
74
74
 
75
- sentenceText = //simplifyPunctuationCharacters(sentence.trim())
76
- sentenceText
77
- .replaceAll('(', ', ')
78
- .replaceAll(')', ', ')
79
- .replaceAll('—', ', ')
80
-
81
75
  const simplifiedSentenceText = simplifyPunctuationCharacters(sentenceText.trim())
82
76
 
83
77
  const voiceLanguage = voiceEntry.languages[0]
@@ -72,12 +72,6 @@ export class VitsTTS {
72
72
 
73
73
  lengthScale *= baseLengthScale
74
74
 
75
- sentence = //simplifyPunctuationCharacters(sentence.trim())
76
- sentence
77
- .replaceAll('(', ', ')
78
- .replaceAll(')', ', ')
79
- .replaceAll('—', ', ')
80
-
81
75
  const Espeak = await import('../synthesis/EspeakTTS.js')
82
76
 
83
77
  logger.end()
@@ -1,6 +1,6 @@
1
1
  import { addMissingPunctuationWordsToWordSequence, segmentWordSequence, WordSequence } from '@echogarden/text-segmentation'
2
2
  import { ParagraphBreakType, WhitespaceProcessing } from '../api/Common.js'
3
- import { applyWhitespaceProcessing, isWord, isWordOrEmojiOrSymbolWord, splitToParagraphs } from '../nlp/Segmentation.js'
3
+ import { applyWhitespaceProcessing, includesWordCharacter, isWordOrEmojiOrSymbolWord, splitToParagraphs } from '../nlp/Segmentation.js'
4
4
  import { deepClone } from './ObjectUtilities.js'
5
5
  import { getUTF32Chars } from './StringUtilities.js'
6
6
  import { roundToDigits } from './Utilities.js'
@@ -213,7 +213,7 @@ function replaceSentenceEndersWithinWordsWithMaskingCharacter(transcript: string
213
213
  for (const wordEntry of wordTimeline) {
214
214
  const wordText = wordEntry.text
215
215
 
216
- if (!isWord(wordText)) {
216
+ if (!includesWordCharacter(wordText)) {
217
217
  continue
218
218
  }
219
219
 
@@ -1,10 +1,10 @@
1
1
  import { OperationCallbacks } from '../api/Common.js'
2
- import { splitToParagraphs, wordCharacterRegExp } from '../nlp/Segmentation.js'
2
+ import { isWordOrEmojiOrSymbolWord, splitToParagraphs } from '../nlp/Segmentation.js'
3
3
 
4
4
  export async function fetchAndParseWikipediaArticle(articleName: string, language: string, callbacks: OperationCallbacks) {
5
- const { default: wtf } = await import('wtf_wikipedia')
5
+ const { default: wtfWikipedia } = await import('wtf_wikipedia')
6
6
 
7
- const document = await wtf.fetch(articleName, language)
7
+ const document = await wtfWikipedia.fetch(articleName, language)
8
8
 
9
9
  if (!document) {
10
10
  throw new Error('Error fetching Wikipedia article')
@@ -16,7 +16,7 @@ export async function fetchAndParseWikipediaArticle(articleName: string, languag
16
16
  for (const section of sections) {
17
17
  const sectionTitle = section.title()
18
18
 
19
- if (wordCharacterRegExp.test(sectionTitle)) {
19
+ if (isWordOrEmojiOrSymbolWord(sectionTitle)) {
20
20
  sectionsText.push(sectionTitle)
21
21
  }
22
22
 
@@ -25,7 +25,7 @@ export async function fetchAndParseWikipediaArticle(articleName: string, languag
25
25
  for (const paragraph of sectionParagraphs) {
26
26
  const paragraphText = paragraph
27
27
 
28
- if (wordCharacterRegExp.test(paragraphText)) {
28
+ if (isWordOrEmojiOrSymbolWord(paragraphText)) {
29
29
  sectionsText.push(paragraphText)
30
30
  }
31
31
  }