@echogarden/text-segmentation 0.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.
- package/LICENSE.md +7 -0
- package/README.md +178 -0
- package/dist/EastAsianCharacterPatterns.d.ts +7 -0
- package/dist/EastAsianCharacterPatterns.js +24 -0
- package/dist/EastAsianCharacterPatterns.js.map +1 -0
- package/dist/Patterns.d.ts +34 -0
- package/dist/Patterns.js +126 -0
- package/dist/Patterns.js.map +1 -0
- package/dist/Suppressions.d.ts +4 -0
- package/dist/Suppressions.js +31 -0
- package/dist/Suppressions.js.map +1 -0
- package/dist/Test.d.ts +1 -0
- package/dist/Test.js +39 -0
- package/dist/Test.js.map +1 -0
- package/dist/TextSegmentation.d.ts +31 -0
- package/dist/TextSegmentation.js +208 -0
- package/dist/TextSegmentation.js.map +1 -0
- package/dist/WordSequence.d.ts +26 -0
- package/dist/WordSequence.js +67 -0
- package/dist/WordSequence.js.map +1 -0
- package/dist/utilities/Timer.d.ts +13 -0
- package/dist/utilities/Timer.js +70 -0
- package/dist/utilities/Timer.js.map +1 -0
- package/dist/utilities/Utilities.d.ts +6 -0
- package/dist/utilities/Utilities.js +24 -0
- package/dist/utilities/Utilities.js.map +1 -0
- package/package.json +55 -0
- package/src/EastAsianCharacterPatterns.ts +45 -0
- package/src/Patterns.ts +225 -0
- package/src/Suppressions.ts +35 -0
- package/src/Test.ts +55 -0
- package/src/TextSegmentation.ts +303 -0
- package/src/WordSequence.ts +94 -0
- package/src/utilities/Timer.ts +95 -0
- package/src/utilities/Utilities.ts +33 -0
- package/tsconfig.json +105 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { buildRegExp } from 'regexp-composer';
|
|
2
|
+
import { buildWordOrNumberPattern as buildWordSplitterPattern, phraseSeparatorRegExp, sentenceSeparatorTrailingPunctuationRegExp, sentenceSeparatorRegExp, whitespacePatternRegExp } from './Patterns.js';
|
|
3
|
+
import { cldrSuppressions, leadingApostropheContractionSuppressions, nounSuppressions, tldSuppressions } from './Suppressions.js';
|
|
4
|
+
import { eastAsianCharRangesRegExp } from './EastAsianCharacterPatterns.js';
|
|
5
|
+
import { WordSequence } from './WordSequence.js';
|
|
6
|
+
export { cldrSuppressions } from './Suppressions.js';
|
|
7
|
+
export async function segmentText(text, options) {
|
|
8
|
+
options = { ...defaultSegmentationOptions, ...(options ?? {}) };
|
|
9
|
+
const wordSequence = await splitToWords(text, options);
|
|
10
|
+
return segmentWordSequence(wordSequence);
|
|
11
|
+
}
|
|
12
|
+
export async function segmentWordSequence(wordSequence) {
|
|
13
|
+
const sentenceWordRanges = [];
|
|
14
|
+
let sentenceStartWordOffset = 0;
|
|
15
|
+
for (let wordIndex = 0; wordIndex < wordSequence.length; wordIndex++) {
|
|
16
|
+
const word = wordSequence.getWordAt(wordIndex);
|
|
17
|
+
if (sentenceSeparatorRegExp.test(word)) {
|
|
18
|
+
while (wordIndex < wordSequence.length - 1) {
|
|
19
|
+
const nextWord = wordSequence.getWordAt(wordIndex + 1);
|
|
20
|
+
if (!sentenceSeparatorTrailingPunctuationRegExp.test(nextWord)) {
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
wordIndex += 1;
|
|
24
|
+
}
|
|
25
|
+
sentenceWordRanges.push({
|
|
26
|
+
start: sentenceStartWordOffset,
|
|
27
|
+
end: wordIndex + 1
|
|
28
|
+
});
|
|
29
|
+
sentenceStartWordOffset = wordIndex + 1;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (sentenceStartWordOffset < wordSequence.length) {
|
|
33
|
+
sentenceWordRanges.push({ start: sentenceStartWordOffset, end: wordSequence.length });
|
|
34
|
+
}
|
|
35
|
+
const sentences = [];
|
|
36
|
+
for (const wordRange of sentenceWordRanges) {
|
|
37
|
+
const sentenceWordSequence = wordSequence.slice(wordRange.start, wordRange.end);
|
|
38
|
+
sentences.push(new Sentence(wordRange, sentenceWordSequence));
|
|
39
|
+
}
|
|
40
|
+
for (const sentence of sentences) {
|
|
41
|
+
const phraseWordRanges = [];
|
|
42
|
+
let sentenceEndWordOffset = sentence.wordRange.end;
|
|
43
|
+
let phraseStartWordOffset = sentence.wordRange.start;
|
|
44
|
+
for (let wordIndex = phraseStartWordOffset; wordIndex < sentenceEndWordOffset; wordIndex++) {
|
|
45
|
+
const currentWord = wordSequence.getWordAt(wordIndex);
|
|
46
|
+
if (phraseSeparatorRegExp.test(currentWord)) {
|
|
47
|
+
let whitespaceSeenOnce = false;
|
|
48
|
+
while (wordIndex < sentenceEndWordOffset - 1) {
|
|
49
|
+
const nextWord = wordSequence.getWordAt(wordIndex + 1);
|
|
50
|
+
if (!sentenceSeparatorTrailingPunctuationRegExp.test(nextWord)) {
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
if (whitespacePatternRegExp.test(nextWord)) {
|
|
54
|
+
whitespaceSeenOnce = true;
|
|
55
|
+
}
|
|
56
|
+
if (nextWord === '"' && whitespaceSeenOnce) {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
wordIndex += 1;
|
|
60
|
+
}
|
|
61
|
+
phraseWordRanges.push({
|
|
62
|
+
start: phraseStartWordOffset,
|
|
63
|
+
end: wordIndex + 1
|
|
64
|
+
});
|
|
65
|
+
phraseStartWordOffset = wordIndex + 1;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (phraseStartWordOffset < sentenceEndWordOffset) {
|
|
69
|
+
phraseWordRanges.push({ start: phraseStartWordOffset, end: sentenceEndWordOffset });
|
|
70
|
+
}
|
|
71
|
+
for (const wordRange of phraseWordRanges) {
|
|
72
|
+
const phraseWordSequence = wordSequence.slice(wordRange.start, wordRange.end);
|
|
73
|
+
sentence.phrases.push(new Phrase(wordRange, phraseWordSequence));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const result = {
|
|
77
|
+
wordSequence,
|
|
78
|
+
sentences,
|
|
79
|
+
};
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
export async function splitToWords(text, options) {
|
|
83
|
+
options = { ...defaultSegmentationOptions, ...(options ?? {}) };
|
|
84
|
+
const cldrSuppressionsForLang = cldrSuppressions[options.language ?? ''] ?? [];
|
|
85
|
+
const contractionSuppressionsForLang = leadingApostropheContractionSuppressions[options.language ?? ''] ?? [];
|
|
86
|
+
const contractionSuppressionsForLangWithSingleQuote = contractionSuppressionsForLang.map(str => str.replaceAll(`'`, `’`));
|
|
87
|
+
const customSuppressions = options.customSuppressions ?? [];
|
|
88
|
+
let suppressions = [
|
|
89
|
+
...customSuppressions,
|
|
90
|
+
...cldrSuppressionsForLang,
|
|
91
|
+
...contractionSuppressionsForLang,
|
|
92
|
+
...contractionSuppressionsForLangWithSingleQuote,
|
|
93
|
+
...nounSuppressions,
|
|
94
|
+
...tldSuppressions,
|
|
95
|
+
];
|
|
96
|
+
const wordPattern = buildWordSplitterPattern([
|
|
97
|
+
...suppressions,
|
|
98
|
+
...suppressions.map(word => word.toLocaleLowerCase()),
|
|
99
|
+
...suppressions.map(word => word.toLocaleUpperCase()),
|
|
100
|
+
]);
|
|
101
|
+
const wordSplitterRegExp = buildRegExp(wordPattern, { global: true });
|
|
102
|
+
//console.log(`Encoded pattern: ${wordSplitterRegExp.source}\n`)
|
|
103
|
+
let wordSequence = new WordSequence();
|
|
104
|
+
function addNonWordsBetween(startOffset, endOffset) {
|
|
105
|
+
const nonWordSubstring = text.substring(startOffset, endOffset);
|
|
106
|
+
let charOffset = startOffset;
|
|
107
|
+
let nonwordStartOffset = startOffset;
|
|
108
|
+
function addNonWordIfNeeded() {
|
|
109
|
+
if (charOffset > nonwordStartOffset) {
|
|
110
|
+
wordSequence.addWordEntry(text, nonwordStartOffset, charOffset, true);
|
|
111
|
+
nonwordStartOffset = charOffset;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
for (const char of nonWordSubstring) {
|
|
115
|
+
if (char === ' ') {
|
|
116
|
+
charOffset += 1;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
addNonWordIfNeeded();
|
|
120
|
+
charOffset += char.length;
|
|
121
|
+
addNonWordIfNeeded();
|
|
122
|
+
}
|
|
123
|
+
addNonWordIfNeeded();
|
|
124
|
+
}
|
|
125
|
+
const wordMatches = text.matchAll(wordSplitterRegExp);
|
|
126
|
+
let lastMatchEndOffset = 0;
|
|
127
|
+
if (wordMatches) {
|
|
128
|
+
for (const match of wordMatches) {
|
|
129
|
+
const offsets = match.indices[0];
|
|
130
|
+
const matchStartOffset = offsets[0];
|
|
131
|
+
const matchEndOffset = offsets[1];
|
|
132
|
+
if (matchStartOffset > lastMatchEndOffset) {
|
|
133
|
+
addNonWordsBetween(lastMatchEndOffset, matchStartOffset);
|
|
134
|
+
}
|
|
135
|
+
wordSequence.addWordEntry(text, matchStartOffset, matchEndOffset, false);
|
|
136
|
+
lastMatchEndOffset = matchEndOffset;
|
|
137
|
+
}
|
|
138
|
+
addNonWordsBetween(lastMatchEndOffset, text.length);
|
|
139
|
+
}
|
|
140
|
+
if (options.enableEastAsianPostprocessing) {
|
|
141
|
+
wordSequence = await postprocessEastAsianWords(text, wordSequence);
|
|
142
|
+
}
|
|
143
|
+
return wordSequence;
|
|
144
|
+
}
|
|
145
|
+
async function postprocessEastAsianWords(containingText, wordSequence) {
|
|
146
|
+
const icuSegmentation = await getIcuSegmentation();
|
|
147
|
+
if (icuSegmentation === undefined) {
|
|
148
|
+
return wordSequence;
|
|
149
|
+
}
|
|
150
|
+
let icuInitialized = false;
|
|
151
|
+
const newWordSequence = new WordSequence();
|
|
152
|
+
for (let wordIndex = 0; wordIndex < wordSequence.length; wordIndex++) {
|
|
153
|
+
const wordEntry = wordSequence.entries[wordIndex];
|
|
154
|
+
const wordStartOffset = wordEntry.startOffset;
|
|
155
|
+
const word = wordSequence.getWordAt(wordIndex);
|
|
156
|
+
if (eastAsianCharRangesRegExp.test(word)) {
|
|
157
|
+
if (!icuInitialized) {
|
|
158
|
+
await icuSegmentation.initialize();
|
|
159
|
+
icuInitialized = true;
|
|
160
|
+
}
|
|
161
|
+
const wordBreaks = [...icuSegmentation.createWordBreakIterator(word)];
|
|
162
|
+
for (let i = 0; i < wordBreaks.length - 1; i++) {
|
|
163
|
+
newWordSequence.addWordEntry(containingText, wordStartOffset + wordBreaks[i], wordStartOffset + wordBreaks[i + 1], false);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
newWordSequence.addWordEntry(containingText, wordEntry.startOffset, wordEntry.endOffset, wordEntry.isPunctuation);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return newWordSequence;
|
|
171
|
+
}
|
|
172
|
+
async function getIcuSegmentation() {
|
|
173
|
+
try {
|
|
174
|
+
const icuSegmentation = await import('@echogarden/icu-segmentation-wasm');
|
|
175
|
+
return icuSegmentation;
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
export class TextFragment {
|
|
182
|
+
wordRange;
|
|
183
|
+
wordSequence;
|
|
184
|
+
constructor(wordRange, wordSequence) {
|
|
185
|
+
this.wordRange = wordRange;
|
|
186
|
+
this.wordSequence = wordSequence;
|
|
187
|
+
}
|
|
188
|
+
get text() {
|
|
189
|
+
return this.wordSequence.text;
|
|
190
|
+
}
|
|
191
|
+
get charRange() {
|
|
192
|
+
return {
|
|
193
|
+
start: this.wordSequence.firstEntry.startOffset,
|
|
194
|
+
end: this.wordSequence.lastEntry.endOffset
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
export class Sentence extends TextFragment {
|
|
199
|
+
phrases = [];
|
|
200
|
+
}
|
|
201
|
+
export class Phrase extends TextFragment {
|
|
202
|
+
}
|
|
203
|
+
export const defaultSegmentationOptions = {
|
|
204
|
+
language: '',
|
|
205
|
+
customSuppressions: [],
|
|
206
|
+
enableEastAsianPostprocessing: true,
|
|
207
|
+
};
|
|
208
|
+
//# sourceMappingURL=TextSegmentation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextSegmentation.js","sourceRoot":"","sources":["../src/TextSegmentation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare class WordSequence {
|
|
2
|
+
entries: WordEntry[];
|
|
3
|
+
addWordEntry(containingText: string, startOffset: number, endOffset: number, isPunctuation: boolean): void;
|
|
4
|
+
getWordRange(startIndex: number, endIndex: number): string[];
|
|
5
|
+
iterateWordRange(startIndex: number, endIndex: number): Generator<string, void, unknown>;
|
|
6
|
+
getWordAt(index: number): string;
|
|
7
|
+
getEntryRange(startIndex: number, endIndex: number): WordEntry[];
|
|
8
|
+
iterateEntryRange(startIndex: number, endIndex: number): Generator<WordEntry, void, unknown>;
|
|
9
|
+
getEntryAt(index: number): WordEntry;
|
|
10
|
+
slice(startIndex: number, endIndex: number): WordSequence;
|
|
11
|
+
get words(): string[];
|
|
12
|
+
get firstWord(): string;
|
|
13
|
+
get lastWord(): string;
|
|
14
|
+
get firstEntry(): WordEntry;
|
|
15
|
+
get lastEntry(): WordEntry;
|
|
16
|
+
get nonPunctuationEntries(): WordEntry[];
|
|
17
|
+
get nonPunctuationWords(): string[];
|
|
18
|
+
get text(): string;
|
|
19
|
+
get length(): number;
|
|
20
|
+
}
|
|
21
|
+
export interface WordEntry {
|
|
22
|
+
text: string;
|
|
23
|
+
isPunctuation: boolean;
|
|
24
|
+
startOffset: number;
|
|
25
|
+
endOffset: number;
|
|
26
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export class WordSequence {
|
|
2
|
+
entries = [];
|
|
3
|
+
addWordEntry(containingText, startOffset, endOffset, isPunctuation) {
|
|
4
|
+
const wordText = containingText.substring(startOffset, endOffset);
|
|
5
|
+
this.entries.push({
|
|
6
|
+
text: wordText,
|
|
7
|
+
startOffset,
|
|
8
|
+
endOffset,
|
|
9
|
+
isPunctuation
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
getWordRange(startIndex, endIndex) {
|
|
13
|
+
return [...this.iterateWordRange(startIndex, endIndex)];
|
|
14
|
+
}
|
|
15
|
+
*iterateWordRange(startIndex, endIndex) {
|
|
16
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
17
|
+
yield this.getWordAt(i);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
getWordAt(index) {
|
|
21
|
+
return this.entries[index].text;
|
|
22
|
+
}
|
|
23
|
+
getEntryRange(startIndex, endIndex) {
|
|
24
|
+
return this.entries.slice(startIndex, endIndex);
|
|
25
|
+
}
|
|
26
|
+
*iterateEntryRange(startIndex, endIndex) {
|
|
27
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
28
|
+
yield this.getEntryAt(i);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
getEntryAt(index) {
|
|
32
|
+
return this.entries[index];
|
|
33
|
+
}
|
|
34
|
+
slice(startIndex, endIndex) {
|
|
35
|
+
const slicedSequence = new WordSequence();
|
|
36
|
+
slicedSequence.entries = this.entries.slice(startIndex, endIndex);
|
|
37
|
+
return slicedSequence;
|
|
38
|
+
}
|
|
39
|
+
get words() {
|
|
40
|
+
return this.entries.map(entry => entry.text);
|
|
41
|
+
}
|
|
42
|
+
get firstWord() {
|
|
43
|
+
return this.firstEntry?.text;
|
|
44
|
+
}
|
|
45
|
+
get lastWord() {
|
|
46
|
+
return this.lastEntry?.text;
|
|
47
|
+
}
|
|
48
|
+
get firstEntry() {
|
|
49
|
+
return this.entries[0];
|
|
50
|
+
}
|
|
51
|
+
get lastEntry() {
|
|
52
|
+
return this.entries[this.length - 1];
|
|
53
|
+
}
|
|
54
|
+
get nonPunctuationEntries() {
|
|
55
|
+
return this.entries.filter(entry => entry.isPunctuation === false);
|
|
56
|
+
}
|
|
57
|
+
get nonPunctuationWords() {
|
|
58
|
+
return this.entries.filter(entry => entry.isPunctuation === false).map(entry => entry.text);
|
|
59
|
+
}
|
|
60
|
+
get text() {
|
|
61
|
+
return this.words.join('');
|
|
62
|
+
}
|
|
63
|
+
get length() {
|
|
64
|
+
return this.entries.length;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=WordSequence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WordSequence.js","sourceRoot":"","sources":["../src/WordSequence.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,YAAY;IACxB,OAAO,GAAgB,EAAE,CAAA;IAEzB,YAAY,CAAC,cAAsB,EAAE,WAAmB,EAAE,SAAiB,EAAE,aAAsB;QAClG,MAAM,QAAQ,GAAG,cAAc,CAAC,SAAS,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;QAEjE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YACjB,IAAI,EAAE,QAAQ;YACd,WAAW;YACX,SAAS;YACT,aAAa;SACb,CAAC,CAAA;IACH,CAAC;IAED,YAAY,CAAC,UAAkB,EAAE,QAAgB;QAChD,OAAO,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAA;IACxD,CAAC;IAED,CAAC,gBAAgB,CAAC,UAAkB,EAAE,QAAgB;QACrD,KAAK,IAAI,CAAC,GAAG,UAAU,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;QACxB,CAAC;IACF,CAAC;IAED,SAAS,CAAC,KAAa;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAA;IAChC,CAAC;IAED,aAAa,CAAC,UAAkB,EAAE,QAAgB;QACjD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;IAChD,CAAC;IAED,CAAC,iBAAiB,CAAC,UAAkB,EAAE,QAAgB;QACtD,KAAK,IAAI,CAAC,GAAG,UAAU,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QACzB,CAAC;IACF,CAAC;IAED,UAAU,CAAC,KAAa;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;IAED,KAAK,CAAC,UAAkB,EAAE,QAAgB;QACzC,MAAM,cAAc,GAAG,IAAI,YAAY,EAAE,CAAA;QAEzC,cAAc,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;QAEjE,OAAO,cAAc,CAAA;IACtB,CAAC;IAED,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC7C,CAAC;IAED,IAAI,SAAS;QACZ,OAAO,IAAI,CAAC,UAAU,EAAE,IAAI,CAAA;IAC7B,CAAC;IAED,IAAI,QAAQ;QACX,OAAO,IAAI,CAAC,SAAS,EAAE,IAAI,CAAA;IAC5B,CAAC;IAED,IAAI,UAAU;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACvB,CAAC;IAED,IAAI,SAAS;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACrC,CAAC;IAED,IAAI,qBAAqB;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,KAAK,KAAK,CAAC,CAAA;IACnE,CAAC;IAED,IAAI,mBAAmB;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC5F,CAAC;IAED,IAAI,IAAI;QACP,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC3B,CAAC;IAED,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAA;IAC3B,CAAC;CACD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class Timer {
|
|
2
|
+
startTime: number;
|
|
3
|
+
constructor();
|
|
4
|
+
restart(): void;
|
|
5
|
+
get elapsedTime(): number;
|
|
6
|
+
get elapsedTimeSeconds(): number;
|
|
7
|
+
getElapsedTimeAndRestart(): number;
|
|
8
|
+
logAndRestart(title: string, timePrecision?: number): number;
|
|
9
|
+
static get currentTime(): number;
|
|
10
|
+
static get microsecondTimestamp(): number;
|
|
11
|
+
private static createGlobalTimestampFunction;
|
|
12
|
+
private static timestampFunc;
|
|
13
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { roundToDigits } from "./Utilities.js";
|
|
2
|
+
export class Timer {
|
|
3
|
+
startTime = 0;
|
|
4
|
+
constructor() {
|
|
5
|
+
this.restart();
|
|
6
|
+
}
|
|
7
|
+
restart() {
|
|
8
|
+
this.startTime = Timer.currentTime;
|
|
9
|
+
}
|
|
10
|
+
get elapsedTime() {
|
|
11
|
+
// Elapsed time (milliseconds)
|
|
12
|
+
return Timer.currentTime - this.startTime;
|
|
13
|
+
}
|
|
14
|
+
get elapsedTimeSeconds() {
|
|
15
|
+
// Elapsed time (seconds)
|
|
16
|
+
return this.elapsedTime / 1000;
|
|
17
|
+
}
|
|
18
|
+
getElapsedTimeAndRestart() {
|
|
19
|
+
const elapsedTime = this.elapsedTime;
|
|
20
|
+
this.restart();
|
|
21
|
+
return elapsedTime;
|
|
22
|
+
}
|
|
23
|
+
logAndRestart(title, timePrecision = 3) {
|
|
24
|
+
const elapsedTime = this.elapsedTime;
|
|
25
|
+
//
|
|
26
|
+
const message = `${title}: ${roundToDigits(elapsedTime, timePrecision)}ms`;
|
|
27
|
+
console.log(message);
|
|
28
|
+
//
|
|
29
|
+
this.restart();
|
|
30
|
+
return elapsedTime;
|
|
31
|
+
}
|
|
32
|
+
static get currentTime() {
|
|
33
|
+
if (!this.timestampFunc) {
|
|
34
|
+
this.createGlobalTimestampFunction();
|
|
35
|
+
}
|
|
36
|
+
return this.timestampFunc();
|
|
37
|
+
}
|
|
38
|
+
static get microsecondTimestamp() {
|
|
39
|
+
return Math.floor(Timer.currentTime * 1000);
|
|
40
|
+
}
|
|
41
|
+
static createGlobalTimestampFunction() {
|
|
42
|
+
if (typeof process === 'object' && typeof process.hrtime === 'function') {
|
|
43
|
+
let baseTimestamp = 0;
|
|
44
|
+
this.timestampFunc = () => {
|
|
45
|
+
const nodeTimeStamp = process.hrtime();
|
|
46
|
+
const millisecondTime = (nodeTimeStamp[0] * 1000) + (nodeTimeStamp[1] / 1000000);
|
|
47
|
+
return baseTimestamp + millisecondTime;
|
|
48
|
+
};
|
|
49
|
+
baseTimestamp = Date.now() - this.timestampFunc();
|
|
50
|
+
}
|
|
51
|
+
else if (typeof chrome === 'object' && chrome.Interval) {
|
|
52
|
+
const baseTimestamp = Date.now();
|
|
53
|
+
const chromeIntervalObject = new chrome.Interval();
|
|
54
|
+
chromeIntervalObject.start();
|
|
55
|
+
this.timestampFunc = () => baseTimestamp + chromeIntervalObject.microseconds() / 1000;
|
|
56
|
+
}
|
|
57
|
+
else if (typeof performance === 'object' && performance.now) {
|
|
58
|
+
const baseTimestamp = Date.now() - performance.now();
|
|
59
|
+
this.timestampFunc = () => baseTimestamp + performance.now();
|
|
60
|
+
}
|
|
61
|
+
else if (Date.now) {
|
|
62
|
+
this.timestampFunc = () => Date.now();
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
this.timestampFunc = () => (new Date()).getTime();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
static timestampFunc;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=Timer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Timer.js","sourceRoot":"","sources":["../../src/utilities/Timer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Pattern } from 'regexp-composer';
|
|
2
|
+
export declare function roundToDigits(val: number, digits?: number): number;
|
|
3
|
+
export declare function listAllCharsMatching(charPattern: Pattern): string[];
|
|
4
|
+
export declare function extractSuppressions(entries: {
|
|
5
|
+
suppression: string;
|
|
6
|
+
}[]): string[];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { buildRegExp } from 'regexp-composer';
|
|
2
|
+
export function roundToDigits(val, digits = 3) {
|
|
3
|
+
const multiplier = 10 ** digits;
|
|
4
|
+
return Math.round(val * multiplier) / multiplier;
|
|
5
|
+
}
|
|
6
|
+
export function listAllCharsMatching(charPattern) {
|
|
7
|
+
const regExp = buildRegExp(charPattern);
|
|
8
|
+
const matchingChars = [];
|
|
9
|
+
for (let codepoint = 0; codepoint < 1114111; codepoint++) {
|
|
10
|
+
const char = String.fromCodePoint(codepoint);
|
|
11
|
+
if (regExp.test(char)) {
|
|
12
|
+
matchingChars.push(char);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return matchingChars;
|
|
16
|
+
}
|
|
17
|
+
export function extractSuppressions(entries) {
|
|
18
|
+
const suppressions = [];
|
|
19
|
+
for (const entry of entries) {
|
|
20
|
+
suppressions.push(entry.suppression);
|
|
21
|
+
}
|
|
22
|
+
return suppressions;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=Utilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Utilities.js","sourceRoot":"","sources":["../../src/utilities/Utilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAW,MAAM,iBAAiB,CAAA;AAEtD,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,MAAM,GAAG,CAAC;IACpD,MAAM,UAAU,GAAG,EAAE,IAAI,MAAM,CAAA;IAE/B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,UAAU,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,WAAoB;IACxD,MAAM,MAAM,GAAG,WAAW,CAAC,WAAW,CAAC,CAAA;IAEvC,MAAM,aAAa,GAAa,EAAE,CAAA;IAElC,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC;QAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAA;QAE5C,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACzB,CAAC;IACF,CAAC;IAED,OAAO,aAAa,CAAA;AACrB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAiC;IACpE,MAAM,YAAY,GAAa,EAAE,CAAA;IAEjC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;IACrC,CAAC;IAED,OAAO,YAAY,CAAA;AACpB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@echogarden/text-segmentation",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A library for multilingual word, phrase and sentence segmentation.",
|
|
5
|
+
"author": "Rotem Dan",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"text segmentation",
|
|
9
|
+
"word segmentation",
|
|
10
|
+
"word boundary detection",
|
|
11
|
+
"phrase segmentation",
|
|
12
|
+
"phrase boundary detection",
|
|
13
|
+
"sentence segmentation",
|
|
14
|
+
"sentence boundary detection"
|
|
15
|
+
],
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/echogarden-project/text-segmentation"
|
|
22
|
+
},
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/echogarden-project/text-segmentation/issues"
|
|
25
|
+
},
|
|
26
|
+
"main": "./dist/TextSegmentation.js",
|
|
27
|
+
"type": "module",
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"src",
|
|
31
|
+
"tsconfig.json",
|
|
32
|
+
"LICENSE.md",
|
|
33
|
+
"README.md"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"test": "node dist/Test.js"
|
|
37
|
+
},
|
|
38
|
+
"//dependencies": {
|
|
39
|
+
"regexp-composer": "../../regexp-composer"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"regexp-composer": "^0.1.2"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@echogarden/icu-segmentation-wasm": "^0.1.0"
|
|
46
|
+
},
|
|
47
|
+
"peerDependenciesMeta": {
|
|
48
|
+
"@echogarden/icu-segmentation-wasm": {
|
|
49
|
+
"optional": true
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^22.10.1"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { anyOf, buildRegExp, codepointRange } from 'regexp-composer'
|
|
2
|
+
|
|
3
|
+
export const chineseCharacterRanges = anyOf(
|
|
4
|
+
codepointRange('4E00', '9FFF'), // Main
|
|
5
|
+
codepointRange('3400', '4DBF'), // CJK Unified Ideographs Extension A
|
|
6
|
+
codepointRange('20000', '2A6DF') // CJK Unified Ideographs Extension B
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
export const japaneseHiraganaCharacterRanges = anyOf(
|
|
10
|
+
codepointRange('3040', '309F'), // Hiragana
|
|
11
|
+
codepointRange('1AFF0', '1AFFF'), // Kana Extended-B
|
|
12
|
+
codepointRange('1B000', '1B0FF'), // Kana Supplement
|
|
13
|
+
codepointRange('1B100', '1B12F'), // Kana Extended-A
|
|
14
|
+
codepointRange('1B130', '1B16F'), // Small Kana Extension
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
export const japaneseKatakanaCharacterRanges = anyOf(
|
|
18
|
+
codepointRange('30A0', '30FF'), // Katakana
|
|
19
|
+
codepointRange('31F0', '31FF'), // Katakana Phonetic Extensions
|
|
20
|
+
codepointRange('3200', '32FF'), // Enclosed CJK Letters and Months
|
|
21
|
+
codepointRange('FF00', 'FFEF'), // Halfwidth and Fullwidth Forms
|
|
22
|
+
codepointRange('1AFF0', '1AFFF'), // Kana Extended-B
|
|
23
|
+
codepointRange('1B000', '1B0FF'), // Kana Supplement
|
|
24
|
+
codepointRange('1B100', '1B12F'), // Kana Extended-A
|
|
25
|
+
codepointRange('1B130', '1B16F'), // Small Kana Extension
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
export const thaiLetterRanges = anyOf(
|
|
29
|
+
codepointRange('0E00', '0E7F')
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
export const khmerLetterRanges = anyOf(
|
|
33
|
+
codepointRange('1780', '17FF'), // Letters
|
|
34
|
+
codepointRange('19E0', '19FF'), // Symbols
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
export const eastAsianCharRanges = anyOf(
|
|
38
|
+
chineseCharacterRanges,
|
|
39
|
+
japaneseHiraganaCharacterRanges,
|
|
40
|
+
japaneseKatakanaCharacterRanges,
|
|
41
|
+
thaiLetterRanges,
|
|
42
|
+
khmerLetterRanges,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
export const eastAsianCharRangesRegExp = buildRegExp(eastAsianCharRanges)
|