From 1d4bd5223565ca1cf1eec801ea8457cfac1f03b2 Mon Sep 17 00:00:00 2001 From: Maxim Karpov Date: Mon, 2 Dec 2024 17:36:29 +0300 Subject: [PATCH] fix: add pairs group check --- src/constants/index.ts | 3 +++ src/constants/pairs.ts | 7 +++++++ src/index.ts | 4 ++-- src/parsers/index.spec.ts | 19 +++++++++++++++++++ src/parsers/index.ts | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 src/constants/pairs.ts diff --git a/src/constants/index.ts b/src/constants/index.ts index 0d9efd0..f1967fc 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -8,3 +8,6 @@ export { export {WINDOW_WIDTH} from './parameters'; export {INITIALS, HEAD, TAIL, OTHER, HEAD_PAIR, TAIL_PAIR, OTHER_PAIR} from './abbreviations'; + +export {REGEXP_PAIRS} from './pairs'; +export type {RegExpPair} from './pairs'; diff --git a/src/constants/pairs.ts b/src/constants/pairs.ts new file mode 100644 index 0000000..88ff90f --- /dev/null +++ b/src/constants/pairs.ts @@ -0,0 +1,7 @@ +export type RegExpPair = [() => RegExp, () => RegExp]; + +export const REGEXP_PAIRS: RegExpPair[] = [ + [() => /\*\*[\p{L}_~*]/giu, () => /[\p{L}_~*]\*\*/giu], + [() => /_[\p{L}_~*]/giu, () => /[\p{L}_~*]_/giu], + [() => /~~[\p{L}_~*]/giu, () => /[\p{L}_~*]~~/giu], +]; diff --git a/src/index.ts b/src/index.ts index d168467..1aa2d21 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ import {anyPass, call, compose, zipWith} from 'ramda'; -import {fstChars, lstChars, sentences} from './parsers'; +import {fstChars, groupPairs, lstChars, sentences} from './parsers'; import { leftAbbreviation, leftEndsWithHardbreak, @@ -80,5 +80,5 @@ export function sentenize(text: string): string[] { } } - return parsed; + return groupPairs(parsed); } diff --git a/src/parsers/index.spec.ts b/src/parsers/index.spec.ts index 18f7f6c..bf8bfba 100644 --- a/src/parsers/index.spec.ts +++ b/src/parsers/index.spec.ts @@ -16,6 +16,7 @@ import { fstChars, fstToken, fstWord, + groupPairs, lstChars, lstToken, lstWord, @@ -76,6 +77,24 @@ describe('sentences', () => { expect(actual).toStrictEqual(expected[i]); } }); + it('should split text on delimiter(s) with groupPairs special symbols **', () => { + const input = [ + 'Предложение **один.Предложение два.Предложение** три.Предложение четыре.', + 'Предложение **один?Предложение два?Предложение** три?Предложение четыре?', + 'Предложение **один!Предложение два!Предложение** три!Предложение четыре!', + 'Предложение **один…Предложение два…Предложение** три…Предложение четыре…', + ]; + const expected = [ + ['Предложение **один.Предложение два.Предложение** три.', 'Предложение четыре.'], + ['Предложение **один?Предложение два?Предложение** три?', 'Предложение четыре?'], + ['Предложение **один!Предложение два!Предложение** три!', 'Предложение четыре!'], + ['Предложение **один…Предложение два…Предложение** три…', 'Предложение четыре…'], + ]; + for (let i = 0; i < input.length; i++) { + const actual = groupPairs(sentences(input[i])); + expect(actual).toStrictEqual(expected[i]); + } + }); it('should default to array of single element of original text in case of one sentence', () => { const input = 'Одно длинное предложение без разделителя'; const expected = ['Одно длинное предложение без разделителя']; diff --git a/src/parsers/index.ts b/src/parsers/index.ts index 8ed678c..ddd06ed 100644 --- a/src/parsers/index.ts +++ b/src/parsers/index.ts @@ -4,6 +4,8 @@ import { BRACKETS_CLOSE_MARKERS, QUOTATION_CLOSE_MARKERS, QUOTATION_GENERIC_MARKERS, + REGEXP_PAIRS, + RegExpPair, SENTENCE_END_MARKERS, WINDOW_WIDTH, } from '../constants'; @@ -130,8 +132,41 @@ const dotSuffixRegExp = new RegExp(dotSuffixPattern, dotSuffixFlags); const dotSuffix = compose(defaultTo(''), snd, match(dotSuffixRegExp)); +function isUnpairedStr(str: string, regExp: RegExpPair) { + const first = str?.match(regExp[0]()) ?? []; + const second = str?.match(regExp[1]()) ?? []; + return first.length !== second.length; +} + +function isUnpaired(str: string) { + for (const pair of REGEXP_PAIRS) { + if (isUnpairedStr(str, pair)) { + return true; + } + } + return false; +} + +function groupPairs(parsed: string[]) { + let index = 0; + + while (index < parsed.length - 1) { + const current = parsed[index]; + const next = parsed[index + 1] || ''; + + if (isUnpaired(current)) { + parsed.splice(index, 2, current + next); + } else { + index++; + } + } + + return parsed; +} + export { sentences, + groupPairs, words, delimiters, fst,