├── .npmignore ├── .gitignore ├── test ├── .eslintrc.json ├── pl.test.js ├── my.test.js ├── ur.test.js ├── ml.test.js ├── am.test.js ├── el.test.js ├── zh.test.js ├── hi.test.js ├── da.test.js ├── pa.test.js ├── nl.test.js ├── mr.test.js ├── ar.test.js ├── sk.test.js ├── pt.test.js ├── fi.test.js ├── bg.test.js ├── fr.test.js ├── ja.test.js ├── kk.test.js ├── ru.test.js ├── es.test.js ├── hy.test.js ├── en.test.js └── de.test.js ├── src ├── languages │ ├── ca.js │ ├── mr.js │ ├── ja.js │ ├── el.js │ ├── am.js │ ├── my.js │ ├── ar.js │ ├── hy.js │ ├── hi.js │ ├── or.js │ ├── pa.js │ ├── bn.js │ ├── gu.js │ ├── kn.js │ ├── te.js │ ├── ml.js │ ├── bg.js │ ├── ru.js │ ├── ta.js │ ├── index.js │ ├── fr.js │ ├── pt.js │ ├── pl.js │ ├── fi.js │ ├── en.js │ ├── de.js │ ├── es.js │ ├── sk.js │ ├── kk.js │ ├── da.js │ └── nl.js ├── index.js ├── fallbacks.json ├── base.js └── terminators.js ├── .eslintrc.json ├── bin └── segment.mjs ├── .github └── workflows │ ├── npm.yaml │ └── nodejs.yaml ├── rollup.config.js ├── LICENSE ├── package.json ├── README.md └── docs └── index.html /.npmignore: -------------------------------------------------------------------------------- 1 | .github 2 | test -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .vscode 4 | -------------------------------------------------------------------------------- /test/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/languages/ca.js: -------------------------------------------------------------------------------- 1 | import Spanish from './es.js' 2 | 3 | export default class Catalan extends Spanish { 4 | } 5 | -------------------------------------------------------------------------------- /src/languages/mr.js: -------------------------------------------------------------------------------- 1 | import Hindi from './hi.js' 2 | 3 | export default class Marathi extends Hindi { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/languages/ja.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | 3 | const abbreviations = new Set([ 4 | // TOOD: Add abbreviations 5 | ]) 6 | 7 | export default class Japanese extends BaseLanguage { 8 | static abbreviations = abbreviations 9 | } 10 | -------------------------------------------------------------------------------- /src/languages/el.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | import GLOBAL_SENTENCE_TERMINATORS from './../terminators.js' 3 | 4 | export default class Greek extends BaseLanguage { 5 | static abbreviations = new Set() 6 | static sentenceBreakRegex = new RegExp( 7 | `[${GLOBAL_SENTENCE_TERMINATORS.concat([';']).join('')}]+`, 8 | 'g' 9 | ) 10 | } 11 | -------------------------------------------------------------------------------- /src/languages/am.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | import English from './en.js' 3 | 4 | const abbreviations = new Set([ 5 | ...English.abbreviations, 6 | 'ዓ', 7 | 'ም' 8 | ]) 9 | 10 | export default class Amharic extends BaseLanguage { 11 | static abbreviations = abbreviations 12 | continueInNextWord (textAfterBoundary) { 13 | return textAfterBoundary.match(/^\W*[0-9a-z]/) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/languages/my.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | import English from './en.js' 3 | import GLOBAL_SENTENCE_TERMINATORS from './../terminators.js' 4 | 5 | export default class Burmese extends BaseLanguage { 6 | static abbreviations = English.abbreviations 7 | // See https://en.wiktionary.org/wiki/၏ 8 | static sentenceBreakRegex = new RegExp( 9 | `[${GLOBAL_SENTENCE_TERMINATORS.concat(['၏']).join('')}]+`, 10 | 'g' 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/languages/ar.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | 3 | const abbreviations = new Set([ 4 | 'إلخ', 5 | 'ا. د', 6 | 'ا.د', 7 | 'ا.ش.ا', 8 | 'ا', 9 | 'ت.ب', 10 | 'ج.ب', 11 | 'ج.م.ع', 12 | 'جم', 13 | 'س.ت', 14 | 'سم', 15 | 'ص.ب.', 16 | 'ص.ب', 17 | 'كج.', 18 | 'كلم.', 19 | 'م.ب', 20 | 'م', 21 | 'ه' 22 | 23 | ]) 24 | 25 | export default class Arabic extends BaseLanguage { 26 | static abbreviations = abbreviations 27 | } 28 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true, 5 | "node": true 6 | }, 7 | "extends": ["standard"], 8 | "parser": "@babel/eslint-parser", 9 | "parserOptions": { 10 | "requireConfigFile": false, 11 | "ecmaVersion": "latest", 12 | "sourceType": "module", 13 | "babelOptions": { 14 | "plugins": [ 15 | "@babel/plugin-syntax-import-assertions" 16 | ] 17 | } 18 | }, 19 | "rules": {} 20 | } 21 | 22 | -------------------------------------------------------------------------------- /bin/segment.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict' 4 | 5 | import segment from '../src/index.js' 6 | import fs from 'fs' 7 | 8 | const text = fs.readFileSync('/dev/stdin', 'utf8') 9 | if (text.trim() === '' || process.argv.length !== 3) { 10 | const script = process.argv[1] 11 | process.stderr.write( 12 | 'Usage: node ' + script + ' language < file\n' 13 | ) 14 | process.exit(1) 15 | } 16 | const language = process.argv[2] 17 | console.log(segment(language, text)) 18 | -------------------------------------------------------------------------------- /test/pl.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 'To słowo bałt. jestskrótem.': ['To słowo bałt. jestskrótem.'] 6 | } 7 | 8 | describe('Polish segment()', function () { 9 | for (const [text, expectedSentences] of Object.entries(tests)) { 10 | it(`correctly segments text: ${text}`, function () { 11 | const sentences = segment('pl', text) 12 | assert.deepEqual(sentences, expectedSentences) 13 | }) 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /test/my.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 'ခင္ဗ်ားနာမည္ဘယ္လိုေခၚလဲ။ င္ေနေကာင္းလား။': ['ခင္ဗ်ားနာမည္ဘယ္လိုေခၚလဲ။', 'င္ေနေကာင္းလား။'] 6 | } 7 | 8 | describe('Burmese segment()', function () { 9 | for (const [text, expectedSentences] of Object.entries(tests)) { 10 | it(`correctly segments text: ${text}`, function () { 11 | const sentences = segment('my', text) 12 | assert.deepEqual(sentences, expectedSentences) 13 | }) 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /src/languages/hy.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | import English from './en.js' 3 | import GLOBAL_SENTENCE_TERMINATORS from './../terminators.js' 4 | 5 | const hyTerminators = ['։', '՜', ':'].concat(GLOBAL_SENTENCE_TERMINATORS) 6 | hyTerminators.splice(hyTerminators.indexOf('.'), 1) 7 | const hyTerminatorsRegex = new RegExp(`[${hyTerminators.join('')}]+`, 'g') 8 | 9 | export default class Armenian extends BaseLanguage { 10 | static abbreviations = English.abbreviations 11 | static sentenceBreakRegex = hyTerminatorsRegex 12 | } 13 | -------------------------------------------------------------------------------- /test/ur.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 6 | 'کیا حال ہے؟ ميرا نام ___ ەے۔ میں حالا تاوان دےدوں؟': 7 | ['کیا حال ہے؟', 'ميرا نام ___ ەے۔', 'میں حالا تاوان دےدوں؟'] 8 | 9 | } 10 | 11 | describe('Urdu segment()', function () { 12 | for (const [text, expectedSentences] of Object.entries(tests)) { 13 | it(`correctly segments text: ${text}`, function () { 14 | const sentences = segment('ur', text) 15 | assert.deepEqual(sentences, expectedSentences) 16 | }) 17 | } 18 | }) 19 | -------------------------------------------------------------------------------- /.github/workflows/npm.yaml: -------------------------------------------------------------------------------- 1 | name: Publish Package to npmjs.org 2 | on: 3 | release: 4 | types: [published] 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | # Setup .npmrc file to publish to npm 11 | - uses: actions/setup-node@v3 12 | with: 13 | node-version: '20.x' 14 | registry-url: 'https://registry.npmjs.org' 15 | - run: npm ci 16 | - run: npm run build 17 | - run: npm publish 18 | env: 19 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 20 | -------------------------------------------------------------------------------- /src/languages/hi.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | import English from './en.js' 3 | 4 | const abbreviations = new Set([ 5 | ...English.abbreviations, 6 | 'ए', 7 | 'बी', 8 | 'सी', 9 | 'डी', 10 | 'ई', 11 | 'एफ', 12 | 'जी', 13 | 'एच', 14 | 'आई', 15 | 'जे', 16 | 'के', 17 | 'एल', 18 | 'एम', 19 | 'एन', 20 | 'ओ', 21 | 'पी', 22 | 'क्यू', 23 | 'आर', 24 | 'एस', 25 | 'टी', 26 | 'यू', 27 | 'भी', 28 | 'डब्लू', 29 | 'एक्स', 30 | 'वाई', 31 | 'जेड' 32 | ]) 33 | 34 | export default class Hindi extends BaseLanguage { 35 | static abbreviations = abbreviations 36 | } 37 | -------------------------------------------------------------------------------- /src/languages/or.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | import English from './en.js' 3 | 4 | const abbreviations = new Set([ 5 | ...English.abbreviations, 6 | 'ଏ', 7 | 'ବି', 8 | 'ସି', 9 | 'ଡି', 10 | 'ଈ', 11 | 'ଏଫ', 12 | 'ଜି', 13 | 'ହ୍', 14 | 'ଆଇ', 15 | 'ଜେ', 16 | 'କେ', 17 | 'ଏଲ', 18 | 'ଏମ', 19 | 'ଏନ', 20 | 'ଓ', 21 | 'ପି', 22 | 'କ୍ୟୁ', 23 | 'ଆର', 24 | 'ଏସ', 25 | 'ଟି', 26 | 'ୟୁ', 27 | 'ଭି', 28 | 'ଡବଲ୍ୱ୍', 29 | 'ଏକ୍ସ', 30 | 'ଏବଂ', 31 | 'ଜେଡ' 32 | ]) 33 | 34 | export default class Odia extends BaseLanguage { 35 | static abbreviations = abbreviations 36 | } 37 | -------------------------------------------------------------------------------- /src/languages/pa.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | import English from './en.js' 3 | 4 | const abbreviations = new Set([ 5 | ...English.abbreviations, 6 | 'ਏ', 7 | 'ਬੀ', 8 | 'ਸੀ', 9 | 'ਡੀ', 10 | 'ਈ', 11 | 'ਐਫ', 12 | 'ਜੀ', 13 | 'ਐਚ', 14 | 'ਆਈ', 15 | 'ਜੇ', 16 | 'ਕੇ', 17 | 'ਐਲ', 18 | 'ਐਮ', 19 | 'ਐਨ', 20 | 'ਓ', 21 | 'ਪੀ', 22 | 'ਕਿਊ', 23 | 'ਆਰ', 24 | 'ਐਸ', 25 | 'ਟੀ', 26 | 'ਯੂ', 27 | 'ਵੀ', 28 | 'ਡਬਲਯੂ', 29 | 'ਐਕਸ', 30 | 'ਵਾਈ', 31 | 'ਜੇਡ' 32 | ]) 33 | 34 | export default class Punjabi extends BaseLanguage { 35 | static abbreviations = abbreviations 36 | } 37 | -------------------------------------------------------------------------------- /src/languages/bn.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | import English from './en.js' 3 | 4 | const abbreviations = new Set([ 5 | ...English.abbreviations, 6 | 'এ', 7 | 'বি', 8 | 'সি', 9 | 'ডি', 10 | 'ঈ', 11 | 'এফ', 12 | 'জি', 13 | 'এইচ', 14 | 'আই', 15 | 'জে', 16 | 'কে', 17 | 'এল', 18 | 'এম', 19 | 'এন', 20 | 'ও', 21 | 'পি', 22 | 'কিউ', 23 | 'আর', 24 | 'এস', 25 | 'টি', 26 | 'ইউ', 27 | 'ভি', 28 | 'ডাবলিউ', 29 | 'এক্স', 30 | 'ওয়াই', 31 | 'জেড' 32 | ]) 33 | 34 | export default class Bengali extends BaseLanguage { 35 | static abbreviations = abbreviations 36 | } 37 | -------------------------------------------------------------------------------- /src/languages/gu.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | import English from './en.js' 3 | 4 | const abbreviations = new Set([ 5 | ...English.abbreviations, 6 | 'એ', 7 | 'બી', 8 | 'સી', 9 | 'ડી', 10 | 'ઈ', 11 | 'એફ', 12 | 'જી', 13 | 'એચ', 14 | 'આઈ', 15 | 'જે', 16 | 'કે', 17 | 'એલ', 18 | 'એમ', 19 | 'એન', 20 | 'ઓ', 21 | 'પી', 22 | 'ક્યૂ', 23 | 'આર', 24 | 'એસ', 25 | 'ટી', 26 | 'યૂ', 27 | 'વી', 28 | 'ડબલ્યૂ', 29 | 'એક્સ', 30 | 'વાય', 31 | 'જેડ' 32 | ]) 33 | 34 | export default class Gujarati extends BaseLanguage { 35 | static abbreviations = abbreviations 36 | } 37 | -------------------------------------------------------------------------------- /src/languages/kn.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | import English from './en.js' 3 | 4 | const abbreviations = new Set([ 5 | ...English.abbreviations, 6 | 'ಎ', 7 | 'ಬಿ', 8 | 'ಸಿ', 9 | 'ಡಿ', 10 | 'ಈ', 11 | 'ಎಫ್', 12 | 'ಜಿ', 13 | 'ಹೆಚ್', 14 | 'ಐ', 15 | 'ಜೆ', 16 | 'ಕೆ', 17 | 'ಎಲ್', 18 | 'ಎಂ', 19 | 'ಎನ್', 20 | 'ಓ', 21 | 'ಪಿ', 22 | 'ಕ್ಯೂ', 23 | 'ಆರ್', 24 | 'ಎಸ್', 25 | 'ಟಿ', 26 | 'ಯೂ', 27 | 'ವಿ', 28 | 'ಡಬಲ್ಯೂ', 29 | 'ಎಕ್ಸ್', 30 | 'ವೈ', 31 | 'ಜೆಡ್' 32 | ]) 33 | 34 | export default class Kannada extends BaseLanguage { 35 | static abbreviations = abbreviations 36 | } 37 | -------------------------------------------------------------------------------- /src/languages/te.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | import English from './en.js' 3 | 4 | const abbreviations = new Set([ 5 | ...English.abbreviations, 6 | 'ఎ', 7 | 'బి', 8 | 'సి', 9 | 'డి', 10 | 'ఈ', 11 | 'ఎఫ్', 12 | 'జి', 13 | 'హెచ్', 14 | 'ఐ', 15 | 'జె', 16 | 'కె', 17 | 'ఎల్', 18 | 'ఎం', 19 | 'ఎన్', 20 | 'ఓ', 21 | 'పి', 22 | 'క్యూ', 23 | 'ఆర్', 24 | 'ఎస్', 25 | 'టి', 26 | 'యూ', 27 | 'వి', 28 | 'డబ్ల్యూ', 29 | 'ఎక్స్', 30 | 'వై', 31 | 'జెడ్' 32 | ]) 33 | 34 | export default class Telugu extends BaseLanguage { 35 | static abbreviations = abbreviations 36 | } 37 | -------------------------------------------------------------------------------- /test/ml.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 'ഇത് ഡോ. ശിവൻ. ഇദ്ദേഹമാണ് ഞാൻ പറഞ്ഞയാൾ': ['ഇത് ഡോ. ശിവൻ.', 'ഇദ്ദേഹമാണ് ഞാൻ പറഞ്ഞയാൾ'], 6 | 'ഇത് മി. കെ. പി. മോഹനൻ': ['ഇത് മി. കെ. പി. മോഹനൻ'], 7 | 'ഇത് പ്രൊ. കെ.പി. മോഹനൻ': ['ഇത് പ്രൊ. കെ.പി. മോഹനൻ'], 8 | 'ഇത് Dr. മോഹനൻ': ['ഇത് Dr. മോഹനൻ'] 9 | 10 | } 11 | 12 | describe('Malayalam segment()', function () { 13 | for (const [text, expectedSentences] of Object.entries(tests)) { 14 | it(`correctly segments text: ${text}`, function () { 15 | const sentences = segment('ml', text) 16 | assert.deepEqual(sentences, expectedSentences) 17 | }) 18 | } 19 | }) 20 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import pkg from './package.json' assert { type: 'json' } 2 | import json from '@rollup/plugin-json' 3 | import esbuild from 'rollup-plugin-esbuild' 4 | 5 | export default [ 6 | { 7 | input: 'src/index.js', 8 | output: [ 9 | { 10 | name: pkg.name, 11 | file: pkg.module, 12 | format: 'esm', 13 | sourcemap: true 14 | }, 15 | { 16 | name: pkg.name, 17 | file: pkg.main, 18 | format: 'umd', 19 | sourcemap: true 20 | } 21 | ], 22 | plugins: [ 23 | json(), 24 | esbuild({ 25 | sourceMap: true, 26 | minify: true 27 | }) 28 | 29 | ] 30 | } 31 | ] 32 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import LANGUAGE_FALLBACKS from './fallbacks.json' assert { type: 'json' } 2 | 3 | import languages from './languages/index.js' 4 | 5 | function getLanguageClass (language) { 6 | if (language in languages) { 7 | return languages[language] 8 | } 9 | 10 | const fallbacks = LANGUAGE_FALLBACKS[language] || ['en'] 11 | for (const fallbackLanguage of fallbacks) { 12 | const cls = getLanguageClass(fallbackLanguage) 13 | if (cls) { 14 | return cls 15 | } 16 | } 17 | } 18 | 19 | export default function segment (language, text) { 20 | const className = getLanguageClass(language) 21 | // eslint-disable-next-line new-cap 22 | return new className().segment(text) 23 | } 24 | -------------------------------------------------------------------------------- /test/am.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 'እንደምን አለህ፧መልካም ቀን ይሁንልህ።እባክሽ ያልሽዉን ድገሚልኝ።': ['እንደምን አለህ፧', 'መልካም ቀን ይሁንልህ።', 'እባክሽ ያልሽዉን ድገሚልኝ።'], 6 | 'ቴዎድሮስ ጥር ፮ ቀን ፲፰፻፲፩ ዓ.ም. ሻርጌ በተባለ ቦታ ቋራ ውስጥ፣ ከጎንደር ከተማ በስተ ምዕራብ ተወለዱ።': [ 7 | 'ቴዎድሮስ ጥር ፮ ቀን ፲፰፻፲፩ ዓ.ም. ሻርጌ በተባለ ቦታ ቋራ ውስጥ፣ ከጎንደር ከተማ በስተ ምዕራብ ተወለዱ።' 8 | ] 9 | } 10 | 11 | describe('Amharic segment()', function () { 12 | for (const [text, expectedSentences] of Object.entries(tests)) { 13 | it(`correctly segments text: ${text}`, function () { 14 | const sentences = segment('am', text) 15 | assert.deepEqual(sentences, expectedSentences) 16 | }) 17 | } 18 | }) 19 | -------------------------------------------------------------------------------- /test/el.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 'Με συγχωρείτε· πού είναι οι τουαλέτες; Τις Κυριακές δε δούλευε κανένας. το κόστος του σπιτιού ήταν £260.950,00.': 6 | [ 7 | 'Με συγχωρείτε· πού είναι οι τουαλέτες;', 8 | 'Τις Κυριακές δε δούλευε κανένας.', 9 | 'το κόστος του σπιτιού ήταν £260.950,00.' 10 | ] 11 | } 12 | 13 | describe('Greek segment()', function () { 14 | for (const [text, expectedSentences] of Object.entries(tests)) { 15 | it(`correctly segments text: ${text}`, function () { 16 | const sentences = segment('el', text) 17 | assert.deepEqual(sentences, expectedSentences) 18 | }) 19 | } 20 | }) 21 | -------------------------------------------------------------------------------- /test/zh.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | '安永已聯繫周怡安親屬,協助辦理簽證相關事宜,周怡安家屬1月1日晚間搭乘東方航空班機抵達上海,他們步入入境大廳時神情落寞、不發一語。周怡安來自台中,去年剛從元智大學畢業,同年9月加入安永。': 6 | [ 7 | '安永已聯繫周怡安親屬,協助辦理簽證相關事宜,周怡安家屬1月1日晚間搭乘東方航空班機抵達上海,他們步入入境大廳時神情落寞、不發一語。', 8 | '周怡安來自台中,去年剛從元智大學畢業,同年9月加入安永。' 9 | ], 10 | 11 | '我们明天一起去看《摔跤吧!爸爸》好吗?好!': ['我们明天一起去看《摔跤吧!爸爸》好吗?', '好!'] 12 | } 13 | 14 | describe('Chinese segment()', function () { 15 | for (const [text, expectedSentences] of Object.entries(tests)) { 16 | it(`correctly segments text: ${text}`, function () { 17 | const sentences = segment('zh', text) 18 | assert.deepEqual(sentences, expectedSentences) 19 | }) 20 | } 21 | }) 22 | -------------------------------------------------------------------------------- /test/hi.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 'सच्चाई यह है कि इसे कोई नहीं जानता। हो सकता है यह फ़्रेन्को के खिलाफ़ कोई विद्रोह रहा हो, या फिर बेकाबू हो गया कोई आनंदोत्सव।': 6 | [ 7 | 'सच्चाई यह है कि इसे कोई नहीं जानता।', 8 | 'हो सकता है यह फ़्रेन्को के खिलाफ़ कोई विद्रोह रहा हो, या फिर बेकाबू हो गया कोई आनंदोत्सव।' 9 | ] 10 | } 11 | 12 | describe('Hindi segment()', function () { 13 | for (const [text, expectedSentences] of Object.entries(tests)) { 14 | it(`correctly segments text: ${text}`, function () { 15 | const sentences = segment('hi', text) 16 | assert.deepEqual(sentences, expectedSentences) 17 | }) 18 | } 19 | }) 20 | -------------------------------------------------------------------------------- /test/da.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 'Hej Verden. Mit navn er Jonas.': ['Hej Verden.', 'Mit navn er Jonas.'], 6 | 'Hvad er dit navn? Mit nav er Jonas.': ['Hvad er dit navn?', 'Mit nav er Jonas.'], 7 | 'De holdt Skt. Hans i byen.': ['De holdt Skt. Hans i byen.'], 8 | "St. Michael's Kirke er på 5. gade nær ved lyset.": 9 | ["St. Michael's Kirke er på 5. gade nær ved lyset."] 10 | } 11 | 12 | describe('Danish segment()', function () { 13 | for (const [text, expectedSentences] of Object.entries(tests)) { 14 | it(`correctly segments text: ${text}`, function () { 15 | const sentences = segment('da', text) 16 | assert.deepEqual(sentences, expectedSentences) 17 | }) 18 | } 19 | }) 20 | -------------------------------------------------------------------------------- /test/pa.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 'ਸਰੋਜਿਨੀ ਨਾਇਡੂ ਦਾ ਜਨਮ 13 ਫਰਵਰੀ 1879 ਨੂੰ ਭਾਰਤ ਦੇ ਸ਼ਹਿਰ ਹੈਦਰਾਬਾਦ ਵਿੱਚ ਹੋਇਆ ਸੀ। ਉਸ ਦੇ ਪਿਤਾ ਅਘੋਰਨਾਥ ਚੱਟੋਪਾਧਿਆਏ ਇੱਕ ਨਾਮੀ ਵਿਦਵਾਨ ਅਤੇ ਮਾਂ ਬਰਾਦਾ ਸੁੰਦਰੀ ਦੇਬੀ ਕਵਿਤਰੀ ਸੀ ਅਤੇ ਬੰਗਾਲੀ ਵਿੱਚ ਲਿਖਦੀ ਸੀ।': [ 6 | 'ਸਰੋਜਿਨੀ ਨਾਇਡੂ ਦਾ ਜਨਮ 13 ਫਰਵਰੀ 1879 ਨੂੰ ਭਾਰਤ ਦੇ ਸ਼ਹਿਰ ਹੈਦਰਾਬਾਦ ਵਿੱਚ ਹੋਇਆ ਸੀ।', 7 | 'ਉਸ ਦੇ ਪਿਤਾ ਅਘੋਰਨਾਥ ਚੱਟੋਪਾਧਿਆਏ ਇੱਕ ਨਾਮੀ ਵਿਦਵਾਨ ਅਤੇ ਮਾਂ ਬਰਾਦਾ ਸੁੰਦਰੀ ਦੇਬੀ ਕਵਿਤਰੀ ਸੀ ਅਤੇ ਬੰਗਾਲੀ ਵਿੱਚ ਲਿਖਦੀ ਸੀ।' 8 | ] 9 | } 10 | 11 | describe('Punjabi segment()', function () { 12 | for (const [text, expectedSentences] of Object.entries(tests)) { 13 | it(`correctly segments text: ${text}`, function () { 14 | const sentences = segment('pa', text) 15 | assert.deepEqual(sentences, expectedSentences) 16 | }) 17 | } 18 | }) 19 | -------------------------------------------------------------------------------- /test/nl.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 6 | 'Hij schoot op de JP8-brandstof toen de Surface-to-Air (sam)-missiles op hem af kwamen. 81 procent van de schoten was raak.': 7 | [ 8 | 'Hij schoot op de JP8-brandstof toen de Surface-to-Air (sam)-missiles op hem af kwamen.', 9 | '81 procent van de schoten was raak.' 10 | ], 11 | '81 procent van de schoten was raak. ...en toen barste de hel los.': ['81 procent van de schoten was raak.', '...', 'en toen barste de hel los.'], 12 | 13 | 'Afkorting aanw. vnw.': ['Afkorting aanw. vnw.'] 14 | 15 | } 16 | 17 | describe('Dutch segment()', function () { 18 | for (const [text, expectedSentences] of Object.entries(tests)) { 19 | it(`correctly segments text: ${text}`, function () { 20 | const sentences = segment('nl', text) 21 | assert.deepEqual(sentences, expectedSentences) 22 | }) 23 | } 24 | }) 25 | -------------------------------------------------------------------------------- /src/languages/ml.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | import English from './en.js' 3 | 4 | const abbreviations = new Set([ 5 | ...English.abbreviations, 6 | 'ഡോ', // Dr 7 | 'Dr', 8 | 'പ്രൊ', // Prof 9 | 'പ്രൊഫ', // Prof 10 | 'മി', // Mr, or Minister 11 | 'ശ്രീ', // Formal addressing - male 12 | 'ശ്രീമതി', // Formal addressing - female 13 | 'ബഹു', // Respected 14 | // Transliteration of English alphabets 15 | 'എ', 16 | 'ബി', 17 | 'സി', 18 | 'ഡി', 19 | 'എഫ്', 20 | 'ജി', 21 | 'എച്', 22 | 'എച്ച്', 23 | 'ഐ', 24 | 'ജെ', 25 | 'കെ', 26 | 'എൽ', 27 | 'എം', 28 | 'എൻ', 29 | 'ഒ', 30 | 'ഓ', 31 | 'പി', 32 | 'ക്യു', 33 | 'ക്യൂ', 34 | 'ആർ', 35 | 'എസ്', 36 | 'ടി', 37 | 'യു', 38 | 'യൂ', 39 | 'വി', 40 | 'ഡബ്ല്യു', 41 | 'ഡബ്ള്യു', 42 | 'എക്സ്', 43 | 'വൈ', 44 | 'ഇസഡ്' 45 | ]) 46 | 47 | export default class Malayalam extends BaseLanguage { 48 | static abbreviations = abbreviations 49 | } 50 | -------------------------------------------------------------------------------- /test/mr.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 'आज दसरा आहे. आज खूप शुभ दिवस आहे.': ['आज दसरा आहे.', 'आज खूप शुभ दिवस आहे.'], 6 | 'ढग खूप गर्जत होते; पण पाऊस पडत नव्हता.': ['ढग खूप गर्जत होते; पण पाऊस पडत नव्हता.'], 7 | 'रमाची परीक्षा कधी आहे? अवकाश आहे अजून.': ['रमाची परीक्षा कधी आहे?', 'अवकाश आहे अजून.'], 8 | 'शाब्बास, असाच अभ्यास कर! आणि मग तुला नक्की यश मिळणार.': ['शाब्बास, असाच अभ्यास कर!', 'आणि मग तुला नक्की यश मिळणार.'], 9 | '"आपली आपण करी स्तुती तो एक मूर्ख" असे समर्थ रामदासस्वामी म्हणतात.': ['"आपली आपण करी स्तुती तो एक मूर्ख" असे समर्थ रामदासस्वामी म्हणतात.'] 10 | } 11 | 12 | describe('Marathi segment()', function () { 13 | for (const [text, expectedSentences] of Object.entries(tests)) { 14 | it(`correctly segments text: ${text}`, function () { 15 | const sentences = segment('mr', text) 16 | assert.deepEqual(sentences, expectedSentences) 17 | }) 18 | } 19 | }) 20 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yaml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ main ] 9 | pull_request: 10 | branches: [ main ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [16.x, 18.x, 20.x] 20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 21 | 22 | steps: 23 | - uses: actions/checkout@v2 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v2 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | - run: npm install 29 | - run: npm run build --if-present 30 | - run: npm test 31 | -------------------------------------------------------------------------------- /test/ar.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 'ومن المنتظر أن يكتمل مشروع خط أنابيب نابوكو البالغ طوله 3300 كليومترا في 12/08/2014 بتكلفة تُقدر بـ 7.9 مليارات يورو أي نحو 10.9 مليارات دولار. ومن المقرر أن تصل طاقة ضخ الغاز في المشروع 31 مليار متر مكعب انطلاقا من بحر قزوين مرورا بالنمسا وتركيا ودول البلقان دون المرور على الأراضي الروسية.': [ 6 | 'ومن المنتظر أن يكتمل مشروع خط أنابيب نابوكو البالغ طوله 3300 كليومترا في 12/08/2014 بتكلفة تُقدر بـ 7.9 مليارات يورو أي نحو 10.9 مليارات دولار.', 7 | 'ومن المقرر أن تصل طاقة ضخ الغاز في المشروع 31 مليار متر مكعب انطلاقا من بحر قزوين مرورا بالنمسا وتركيا ودول البلقان دون المرور على الأراضي الروسية.' 8 | ] 9 | } 10 | 11 | describe('Arabic segment()', function () { 12 | for (const [text, expectedSentences] of Object.entries(tests)) { 13 | it(`correctly segments text: ${text}`, function () { 14 | const sentences = segment('ar', text) 15 | assert.deepEqual(sentences, expectedSentences) 16 | }) 17 | } 18 | }) 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Santhosh Thottingal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /src/languages/bg.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | 3 | const abbreviations = new Set([ 4 | 'p.s', 5 | 'акад', 6 | 'ал', 7 | 'б.р', 8 | 'б.ред', 9 | 'бел.а', 10 | 'бел.пр', 11 | 'бр', 12 | 'бул', 13 | 'в', 14 | 'вж', 15 | 'вкл', 16 | 'вм', 17 | 'вр', 18 | 'г', 19 | 'ген', 20 | 'гр', 21 | 'дж', 22 | 'дм', 23 | 'доц', 24 | 'др', 25 | 'ем', 26 | 'заб', 27 | 'зам', 28 | 'инж', 29 | 'к.с', 30 | 'кв.м', 31 | 'кв', 32 | 'кг', 33 | 'км', 34 | 'кор', 35 | 'куб.м', 36 | 'куб', 37 | 'л', 38 | 'лв', 39 | 'м.г', 40 | 'м', 41 | 'мин', 42 | 'млн', 43 | 'млрд', 44 | 'мм', 45 | 'н.с', 46 | 'напр', 47 | 'пл', 48 | 'полк', 49 | 'проф', 50 | 'р', 51 | 'рис', 52 | 'с', 53 | 'св', 54 | 'сек', 55 | 'см', 56 | 'сп', 57 | 'срв', 58 | 'ст', 59 | 'стр', 60 | 'т.г', 61 | 'т.е', 62 | 'т.н', 63 | 'т.нар', 64 | 'т', 65 | 'табл', 66 | 'тел', 67 | 'у', 68 | 'ул', 69 | 'фиг', 70 | 'ха', 71 | 'хил', 72 | 'ч', 73 | 'чл', 74 | 'щ.д' 75 | 76 | ]) 77 | 78 | export default class Bulgarian extends BaseLanguage { 79 | static abbreviations = abbreviations 80 | } 81 | -------------------------------------------------------------------------------- /src/languages/ru.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | 3 | const abbreviations = new Set([ 4 | 'y.e', 5 | 'y', 6 | 'а', 7 | 'авт', 8 | 'адм.-терр', 9 | 'акад', 10 | 'в', 11 | 'вв', 12 | 'вкз', 13 | 'вост.-европ', 14 | 'г', 15 | 'гг', 16 | 'гос', 17 | 'гр', 18 | 'д', 19 | 'деп', 20 | 'дисс', 21 | 'дол', 22 | 'долл', 23 | 'ежедн', 24 | 'ж', 25 | 'жен', 26 | 'з', 27 | 'зап.-европ', 28 | 'зап', 29 | 'заруб', 30 | 'и', 31 | 'ин', 32 | 'иностр', 33 | 'инст', 34 | 'к', 35 | 'канд', 36 | 'кв', 37 | 'кг', 38 | 'куб', 39 | 'л.h', 40 | 'л.н', 41 | 'л', 42 | 'м', 43 | 'мин', 44 | 'моск', 45 | 'муж', 46 | 'н', 47 | 'нед', 48 | 'о', 49 | 'п', 50 | 'пгт', 51 | 'пер', 52 | 'пп', 53 | 'пр', 54 | 'просп', 55 | 'проф', 56 | 'р', 57 | 'руб', 58 | 'с', 59 | 'сек', 60 | 'см', 61 | 'спб', 62 | 'стр', 63 | 'т', 64 | 'тел', 65 | 'тов', 66 | 'тт', 67 | 'тыс', 68 | 'у.е', 69 | 'у', 70 | 'ул', 71 | 'ф', 72 | 'ч' 73 | ]) 74 | 75 | export default class Russian extends BaseLanguage { 76 | static abbreviations = abbreviations 77 | 78 | continueInNextWord (textAfterBoundary) { 79 | return textAfterBoundary.match(/^[0-9a-zа-я]/) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/languages/ta.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | import English from './en.js' 3 | 4 | const vowelSigns = new Set(['ா', 'ி', 'ீ', 'ு', 'ூ', 'ெ', 'ே', 'ை', 'ொ', 'ோ', 'ௌ']) 5 | const vowels = new Set(['அ', 'ஆ', 'இ', 'ஈ', 'உ', 'ஊ', 'எ', 'ஏ', 'ஐ', 'ஒ', 'ஓ', 'ஔ']) 6 | const consonants = new Set([ 7 | 'க', 8 | 'ங', 9 | 'ச', 10 | 'ஞ', 11 | 'ட', 12 | 'ண', 13 | 'த', 14 | 'ந', 15 | 'ப', 16 | 'ம', 17 | 'ய', 18 | 'ர', 19 | 'ல', 20 | 'வ', 21 | 'ழ', 22 | 'ள', 23 | 'ற', 24 | 'ன' 25 | ]) 26 | 27 | const consonantVowels = new Set() 28 | 29 | for (const consonant of consonants) { 30 | for (const vowelSign of vowelSigns) { 31 | consonantVowels.add(consonant + vowelSign) 32 | } 33 | } 34 | 35 | const abbreviations = new Set([ 36 | ...English.abbreviations, 37 | ...vowels, 38 | ...consonants, 39 | ...consonantVowels, 40 | 'ஏ', 41 | 'பி', 42 | 'சி', 43 | 'டி', 44 | 'ஈ', 45 | 'எஃப்', 46 | 'ஜி', 47 | 'ஹேச்', 48 | 'ஐ', 49 | 'ஜே', 50 | 'கே', 51 | 'எல்', 52 | 'எம்', 53 | 'என்', 54 | 'ஓ', 55 | // "பி", 56 | 'க்யூ', 57 | 'ஆர்', 58 | 'எஸ்', 59 | // "டி", 60 | 'யூ', 61 | 'வி', 62 | 'டபிள்யூ', 63 | 'எக்ஸ்', 64 | 'வை', 65 | 'ஜெட்' 66 | ]) 67 | 68 | export default class Tamil extends BaseLanguage { 69 | static abbreviations = abbreviations 70 | } 71 | -------------------------------------------------------------------------------- /test/sk.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 6 | 'Ide o majiteľov firmy ABTrade s. r. o., ktorí stoja aj za ďalšími spoločnosťami, napr. XYZCorp a.s.': 7 | [ 8 | 'Ide o majiteľov firmy ABTrade s. r. o., ktorí stoja aj za ďalšími spoločnosťami, napr. XYZCorp a.s.' 9 | ], 10 | 11 | '„Prieskumy beriem na ľahkú váhu. V podstate ma to nezaujíma,“ reagoval Matovič na prieskum agentúry Focus.': 12 | [ 13 | '„Prieskumy beriem na ľahkú váhu. V podstate ma to nezaujíma,“ reagoval Matovič na prieskum agentúry Focus.' 14 | ], 15 | 16 | 'Toto sa mi podarilo až na 10. pokus, ale stálo to za to.': 17 | ['Toto sa mi podarilo až na 10. pokus, ale stálo to za to.'], 18 | 19 | 'Ide o príslušníkov XII. Pluku špeciálneho určenia.': 20 | ['Ide o príslušníkov XII. Pluku špeciálneho určenia.'], 21 | 'Spoločnosť bola založená 7. Apríla 2020, na zmluve však figuruje dátum 20. marec 2020.': 22 | ['Spoločnosť bola založená 7. Apríla 2020, na zmluve však figuruje dátum 20. marec 2020.'] 23 | } 24 | 25 | describe('Slovak segment()', function () { 26 | for (const [text, expectedSentences] of Object.entries(tests)) { 27 | it(`correctly segments text: ${text}`, function () { 28 | const sentences = segment('sk', text) 29 | assert.deepEqual(sentences, expectedSentences) 30 | }) 31 | } 32 | }) 33 | -------------------------------------------------------------------------------- /test/pt.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 6 | 'A Lei do Sorteio (n.º 1860, de 4 de janeiro de 1908) introduziu o serviço militar obrigatório para as Forças Armadas do Brasil, implantado de fato em 1916, substituindo o recrutamento forçado, o antigo “tributo de sangue”, e permitindo a constituição de uma reserva.': 7 | [ 8 | 'A Lei do Sorteio (n.º 1860, de 4 de janeiro de 1908) introduziu o serviço militar obrigatório para as Forças Armadas do Brasil, implantado de fato em 1916, substituindo o recrutamento forçado, o antigo “tributo de sangue”, e permitindo a constituição de uma reserva.' 9 | ], 10 | 11 | 'Os oficiais mantinham a disciplina pelo castigo corporal.[13] Na Marinha, isso resultou na Revolta da Chibata de 1910.[14]': 12 | [ 13 | 'Os oficiais mantinham a disciplina pelo castigo corporal.[13]', 14 | 'Na Marinha, isso resultou na Revolta da Chibata de 1910.[14]' 15 | ], 16 | 17 | 'A nova legislação era a lei 2.556, de 26 de setembro de 1874, e o decreto 5.881, de 17 de fevereiro de 1875.[35]': 18 | [ 19 | 'A nova legislação era a lei 2.556, de 26 de setembro de 1874, e o decreto 5.881, de 17 de fevereiro de 1875.[35]' 20 | ] 21 | } 22 | 23 | describe('Portuguese segment()', function () { 24 | for (const [text, expectedSentences] of Object.entries(tests)) { 25 | it(`correctly segments text: ${text}`, function () { 26 | const sentences = segment('pt', text) 27 | assert.deepEqual(sentences, expectedSentences) 28 | }) 29 | } 30 | }) 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sentencex", 3 | "version": "0.4.2", 4 | "description": "Sentence segmentation library", 5 | "main": "dist/cjs/index.cjs", 6 | "module": "dist/esm/index.js", 7 | "exports": { 8 | ".": { 9 | "require": "./dist/cjs/index.cjs", 10 | "import": "./dist/esm/index.js" 11 | } 12 | }, 13 | "type": "module", 14 | "scripts": { 15 | "build": "rollup -c", 16 | "lint": "eslint src test", 17 | "test:unit": "mocha", 18 | "test": "npm run lint && npm run test:unit" 19 | }, 20 | "bin": { 21 | "segment": "bin/segment.mjs" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "git+https://github.com/santhoshtr/sentencex-js.git" 26 | }, 27 | "keywords": [ 28 | "nlp", 29 | "sentence-segmentation" 30 | ], 31 | "author": "Santhosh Thottingal", 32 | "license": "MIT", 33 | "bugs": { 34 | "url": "https://github.com/santhoshtr/sentencex-js/issues" 35 | }, 36 | "homepage": "https://github.com/santhoshtr/sentencex-js#readme", 37 | "engines": { 38 | "node": ">=14" 39 | }, 40 | "devDependencies": { 41 | "@babel/eslint-parser": "^7.22.15", 42 | "@babel/plugin-syntax-import-assertions": "^7.22.5", 43 | "@rollup/plugin-json": "^6.0.0", 44 | "eslint-config-standard": "^17.1.0", 45 | "eslint-plugin-import": "^2.28.1", 46 | "eslint-plugin-n": "^16.1.0", 47 | "eslint-plugin-promise": "^6.1.1", 48 | "eslint": "^8.50.0", 49 | "mocha": "^10.2.0", 50 | "prettier": "^3.0.3", 51 | "rollup-plugin-esbuild": "^6.0.0", 52 | "rollup": "^3.29.3" 53 | }, 54 | "dependencies": {} 55 | } 56 | -------------------------------------------------------------------------------- /src/languages/index.js: -------------------------------------------------------------------------------- 1 | import Amharic from './am.js' 2 | import Arabic from './ar.js' 3 | import Armenian from './hy.js' 4 | import Bengali from './bn.js' 5 | import Bulgarian from './bg.js' 6 | import Burmese from './my.js' 7 | import Catalan from './ca.js' 8 | import Danish from './da.js' 9 | import Deutsch from './de.js' 10 | import Dutch from './nl.js' 11 | import English from './en.js' 12 | import Finnish from './fi.js' 13 | import French from './fr.js' 14 | import Greek from './el.js' 15 | import Gujarati from './gu.js' 16 | import Hindi from './hi.js' 17 | import Japanese from './ja.js' 18 | import Kannada from './kn.js' 19 | import Kazakh from './kk.js' 20 | import Malayalam from './ml.js' 21 | import Marathi from './mr.js' 22 | import Odia from './or.js' 23 | import Polish from './pl.js' 24 | import Portuguese from './pt.js' 25 | import Punjabi from './pa.js' 26 | import Russian from './ru.js' 27 | import Slovak from './sk.js' 28 | import Spanish from './es.js' 29 | import Tamil from './ta.js' 30 | import Telugu from './te.js' 31 | 32 | export default { 33 | am: Amharic, 34 | ar: Arabic, 35 | bg: Bulgarian, 36 | bn: Bengali, 37 | ca: Catalan, 38 | da: Danish, 39 | de: Deutsch, 40 | el: Greek, 41 | en: English, 42 | es: Spanish, 43 | fi: Finnish, 44 | fr: French, 45 | gu: Gujarati, 46 | hi: Hindi, 47 | hy: Armenian, 48 | ja: Japanese, 49 | kk: Kazakh, 50 | kn: Kannada, 51 | ml: Malayalam, 52 | mr: Marathi, 53 | my: Burmese, 54 | nl: Dutch, 55 | or: Odia, 56 | pa: Punjabi, 57 | pl: Polish, 58 | pt: Portuguese, 59 | ru: Russian, 60 | sk: Slovak, 61 | ta: Tamil, 62 | te: Telugu 63 | } 64 | -------------------------------------------------------------------------------- /src/languages/fr.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | 3 | const abbreviations = new Set([ 4 | 'a.c.n', 5 | 'a.m', 6 | 'al', 7 | 'ann', 8 | 'apr', 9 | 'art', 10 | 'auj', 11 | 'av', 12 | 'b.p', 13 | 'boul', 14 | 'c.-à-d', 15 | 'c.n.s', 16 | 'c.n', 17 | 'c.p.i', 18 | 'c.q.f.d', 19 | 'c.s', 20 | 'ca', 21 | 'cf', 22 | 'ch.-l', 23 | 'chap', 24 | 'co', 25 | 'contr', 26 | 'dir', 27 | 'e.g', 28 | 'e.v', 29 | 'éd', 30 | 'env', 31 | 'etc', 32 | 'ex', 33 | 'fasc', 34 | 'fém', 35 | 'fig', 36 | 'fr', 37 | 'hab', 38 | 'i.e', 39 | 'ibid', 40 | 'id', 41 | 'inf', 42 | 'l.d', 43 | 'lib', 44 | 'll.aa.ii', 45 | 'll.aa.rr', 46 | 'll.aa.ss', 47 | 'll.aa', 48 | 'll.ee', 49 | 'll.mm.ii.rr', 50 | 'll.mm', 51 | 'loc.cit', 52 | 'ltd', 53 | 'masc', 54 | 'mm', 55 | 'ms', 56 | 'n.b', 57 | 'n.d.a', 58 | 'n.d.l.r', 59 | 'n.d.t', 60 | 'n.d', 61 | 'n.p.a.i', 62 | 'n.s', 63 | 'n/réf', 64 | 'nn.ss', 65 | 'p.c.c', 66 | 'p.ex', 67 | 'p.j', 68 | 'p.s', 69 | 'pl', 70 | 'pp', 71 | 'r.-v', 72 | 'r.a.s', 73 | 'r.i.p', 74 | 'r.p', 75 | 's.a.i', 76 | 's.a.r', 77 | 's.a.s', 78 | 's.a', 79 | 's.e', 80 | 's.m.i.r', 81 | 's.m', 82 | 's.s', 83 | 'sec', 84 | 'sect', 85 | 'sing', 86 | 'sq', 87 | 'sqq', 88 | 'ss', 89 | 'suiv', 90 | 'sup', 91 | 'suppl', 92 | 't.s.v.p', 93 | 'tél', 94 | 'vb', 95 | 'vol', 96 | 'vs', 97 | 'x.o', 98 | 'z.i' 99 | 100 | ]) 101 | 102 | export default class French extends BaseLanguage { 103 | static abbreviations = abbreviations 104 | } 105 | -------------------------------------------------------------------------------- /src/languages/pt.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | 3 | const romanNumerals = 'i ii iii iv v vi vii viii ix x xi xii xiii xiv x xi xii xiii xv xvi xvii xviii xix xx' 4 | 5 | const romanNumeralsSet = new Set([...romanNumerals.split(' '), ...romanNumerals.toUpperCase().split(' ')]) 6 | 7 | const abbreviations = new Set([ 8 | ...romanNumeralsSet, 9 | 'Adj', 10 | 'Adm', 11 | 'Adv', 12 | 'Art', 13 | 'Ca', 14 | 'Capt', 15 | 'Cmdr', 16 | 'Col', 17 | 'Comdr', 18 | 'Con', 19 | 'Corp', 20 | 'Cpl', 21 | 'DR', 22 | 'DRA', 23 | 'Dr', 24 | 'Dra', 25 | 'Dras', 26 | 'Drs', 27 | 'Eng', 28 | 'Enga', 29 | 'Engas', 30 | 'Engos', 31 | 'Ex', 32 | 'Exo', 33 | 'Exmo', 34 | 'Fig', 35 | 'Gen', 36 | 'Hosp', 37 | 'Insp', 38 | 'Lda', 39 | 'MM', 40 | 'MR', 41 | 'MRS', 42 | 'MS', 43 | 'Maj', 44 | 'Mrs', 45 | 'Ms', 46 | 'Msgr', 47 | 'Op', 48 | 'Ord', 49 | 'Pfc', 50 | 'Ph', 51 | 'Prof', 52 | 'Pvt', 53 | 'Rep', 54 | 'Reps', 55 | 'Res', 56 | 'Rev', 57 | 'Rt', 58 | 'Sen', 59 | 'Sens', 60 | 'Sfc', 61 | 'Sgt', 62 | 'Sr', 63 | 'Sra', 64 | 'Sras', 65 | 'Srs', 66 | 'Sto', 67 | 'Supt', 68 | 'Surg', 69 | 'adj', 70 | 'adm', 71 | 'adv', 72 | 'art', 73 | 'cit', 74 | 'col', 75 | 'con', 76 | 'corp', 77 | 'cpl', 78 | 'dr', 79 | 'dra', 80 | 'dras', 81 | 'drs', 82 | 'eng', 83 | 'enga', 84 | 'engas', 85 | 'engos', 86 | 'ex', 87 | 'exo', 88 | 'exmo', 89 | 'fig', 90 | 'op', 91 | 'prof', 92 | 'sr', 93 | 'sra', 94 | 'sras', 95 | 'srs', 96 | 'sto', 97 | 'v', 98 | 'vs', 99 | 'i.e', 100 | 'rev', 101 | 'e.g' 102 | ]) 103 | 104 | export default class Portuguese extends BaseLanguage { 105 | static abbreviations = abbreviations 106 | } 107 | -------------------------------------------------------------------------------- /test/fi.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 6 | 'Se julkaistiin singlenä 7. heinäkuuta 1997, ja se nousi listaykköseksi yhtyeen kotimaassa Britanniassa sekä Irlannissa, Suomessa, Espanjassa ja Kanadassa': [ 7 | 'Se julkaistiin singlenä 7. heinäkuuta 1997, ja se nousi listaykköseksi yhtyeen kotimaassa Britanniassa sekä Irlannissa, Suomessa, Espanjassa ja Kanadassa' 8 | ], 9 | 10 | 'Brittiläinen musiikkilehti NME valitsi lokakuussa 2011 ”D’You Know What I Meanin?” sijalle 77 listallaan, joka sisälsi 150 parasta kappaletta vuosilta 1996–2011.': 11 | [ 12 | 'Brittiläinen musiikkilehti NME valitsi lokakuussa 2011 ”D’You Know What I Meanin?” sijalle 77 listallaan, joka sisälsi 150 parasta kappaletta vuosilta 1996–2011.' 13 | ], 14 | 'Netistä ladattu musiikki on otettu huomioon singlelistalla 3. lokakuuta 2007 lähtien.[13] Uudistus muutti listan luonnetta.': 15 | [ 16 | 'Netistä ladattu musiikki on otettu huomioon singlelistalla 3. lokakuuta 2007 lähtien.[13]', 17 | 'Uudistus muutti listan luonnetta.' 18 | ], 19 | 'Radiomafia oli Yleisradion pääasiassa nuorille ja nuorille aikuisille suunnattu radiokanava, joka aloitti toimintansa vuoden 1990 radiouudistuksessa 1. kesäkuuta 1990 ja lopetti Ylen radiouudistuksen myötä 12. tammikuuta 2003.': 20 | [ 21 | 'Radiomafia oli Yleisradion pääasiassa nuorille ja nuorille aikuisille suunnattu radiokanava, joka aloitti toimintansa vuoden 1990 radiouudistuksessa 1. kesäkuuta 1990 ja lopetti Ylen radiouudistuksen myötä 12. tammikuuta 2003.' 22 | ], 23 | 'Dr. Alban (oikealta nimeltä Alban Uzoma Nwapa, s. 26. elokuuta 1957 Oguta, Brittiläinen Nigeria) on nigerialaissyntyinen ruotsalainen eurodance/rap/reggae -artisti.': 24 | [ 25 | 'Dr. Alban (oikealta nimeltä Alban Uzoma Nwapa, s. 26. elokuuta 1957 Oguta, Brittiläinen Nigeria) on nigerialaissyntyinen ruotsalainen eurodance/rap/reggae -artisti.' 26 | ] 27 | 28 | } 29 | 30 | describe('Finnish segment()', function () { 31 | for (const [text, expectedSentences] of Object.entries(tests)) { 32 | it(`correctly segments text: ${text}`, function () { 33 | const sentences = segment('fi', text) 34 | assert.deepEqual(sentences, expectedSentences) 35 | }) 36 | } 37 | }) 38 | -------------------------------------------------------------------------------- /test/bg.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 6 | 'В първата половина на ноември т.г. ще бъде свикан Консултативният съвет за национална сигурност, обяви държавният глава.': 7 | [ 8 | 'В първата половина на ноември т.г. ще бъде свикан Консултативният съвет за национална сигурност, обяви държавният глава.' 9 | ], 10 | 11 | 'Компютърът е устройство с общо предназначение, което може да бъде програмирано да извършва набор от аритметични и/или логически операции. Възможността поредицата такива операции да бъде променяна позволява компютърът да се използва за решаването на теоретично всяка изчислителна/логическа задача. Обикновено целта на тези операции е обработката на въведена информация (данни), представена в цифров (дигитален) вид, резултатът от които може да се изведе в най-общо казано използваема форма.': 12 | [ 13 | 'Компютърът е устройство с общо предназначение, което може да бъде програмирано да извършва набор от аритметични и/или логически операции.', 14 | 'Възможността поредицата такива операции да бъде променяна позволява компютърът да се използва за решаването на теоретично всяка изчислителна/логическа задача.', 15 | 'Обикновено целта на тези операции е обработката на въведена информация (данни), представена в цифров (дигитален) вид, резултатът от които може да се изведе в най-общо казано използваема форма.' 16 | ], 17 | 'Пл. "20 Април"': ['Пл. "20 Април"'], 18 | 'Той поставя началото на могъща династия, която управлява в продължение на 150 г. Саргон надделява в двубой с владетеля на град Ур и разширява териториите на държавата си по долното течение на Тигър и Ефрат. Стойностни, вкл. български и руски': 19 | [ 20 | 'Той поставя началото на могъща династия, която управлява в продължение на 150 г. Саргон надделява в двубой с владетеля на град Ур и разширява териториите на държавата си по долното течение на Тигър и Ефрат.', 21 | 'Стойностни, вкл. български и руски' 22 | ] 23 | 24 | } 25 | 26 | describe('Bulgarian segment()', function () { 27 | for (const [text, expectedSentences] of Object.entries(tests)) { 28 | it(`correctly segments text: ${text}`, function () { 29 | const sentences = segment('bg', text) 30 | assert.deepEqual(sentences, expectedSentences) 31 | }) 32 | } 33 | }) 34 | -------------------------------------------------------------------------------- /src/languages/pl.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | 3 | const abbreviations = new Set([ 4 | 'ags', 5 | 'alb', 6 | 'ang', 7 | 'aor', 8 | 'awest', 9 | 'bałt', 10 | 'bojkow', 11 | 'bret', 12 | 'brus', 13 | 'bsł', 14 | 'bułg', 15 | 'c.b.d.o', 16 | 'c.b.d.u', 17 | 'celt', 18 | 'chorw', 19 | 'cs', 20 | 'czakaw', 21 | 'czerw', 22 | 'czes', 23 | 'dłuż', 24 | 'dniem', 25 | 'dor', 26 | 'dubrow', 27 | 'duń', 28 | 'ekaw', 29 | 'fiń', 30 | 'franc', 31 | 'gal', 32 | 'germ', 33 | 'głuż', 34 | 'gniem', 35 | 'goc', 36 | 'gr', 37 | 'grudz', 38 | 'hebr', 39 | 'het', 40 | 'hol', 41 | 'I cont', 42 | 'ie', 43 | 'ikaw', 44 | 'irań', 45 | 'irl', 46 | 'islandz', 47 | 'itd', 48 | 'itd.', 49 | 'itp', 50 | 'jekaw', 51 | 'kajkaw', 52 | 'kasz', 53 | 'kirg', 54 | 'kwiec', 55 | 'łac', 56 | 'lip', 57 | 'listop', 58 | 'lit', 59 | 'łot', 60 | 'lp', 61 | 'maced', 62 | 'mar', 63 | 'młpol', 64 | 'moraw', 65 | 'n.e', 66 | 'nb.', 67 | 'ngr', 68 | 'niem', 69 | 'nord', 70 | 'norw', 71 | 'np', 72 | 'np.', 73 | 'ok.', 74 | 'orm', 75 | 'oset', 76 | 'osk', 77 | 'p.n', 78 | 'p.n.e', 79 | 'p.o', 80 | 'pazdz', 81 | 'pers', 82 | 'pie', 83 | 'pod red.', 84 | 'podhal', 85 | 'pol', 86 | 'połab', 87 | 'port', 88 | 'prekm', 89 | 'pskow', 90 | 'psł', 91 | 'R cont', 92 | 'rez', 93 | 'rom', 94 | 'rozdz.', 95 | 'rum', 96 | 'rus', 97 | 'rys.', 98 | 'sas', 99 | 'sch', 100 | 'scs', 101 | 'serb', 102 | 'sierp', 103 | 'śl', 104 | 'sła', 105 | 'słe', 106 | 'słi', 107 | 'słow', 108 | 'sp. z o.o', 109 | 'śrdniem', 110 | 'śrgniem', 111 | 'śrirl', 112 | 'stbułg', 113 | 'stind', 114 | 'stpol', 115 | 'stpr', 116 | 'str.', 117 | 'strus', 118 | 'stwniem', 119 | 'stycz', 120 | 'sztokaw', 121 | 'szwedz', 122 | 't.', 123 | 'tj.', 124 | 'tłum.', 125 | 'toch', 126 | 'tur', 127 | 'tzn', 128 | 'ukr', 129 | 'ul', 130 | 'umbr', 131 | 'wed', 132 | 'węg', 133 | 'wlkpol', 134 | 'włos', 135 | 'wrzes', 136 | 'wyd.', 137 | 'zakarp' 138 | ]) 139 | 140 | export default class Polish extends BaseLanguage { 141 | static abbreviations = abbreviations 142 | constructor () { 143 | super() 144 | this.language = 'pl' 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /test/fr.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 6 | "Après avoir été l'un des acteurs du projet génome humain, le Genoscope met aujourd'hui le cap vers la génomique environnementale. L'exploitation des données de séquences, prolongée par l'identification expérimentale des fonctions biologiques, notamment dans le domaine de la biocatalyse, ouvrent des perspectives de développements en biotechnologie industrielle.": 7 | [ 8 | "Après avoir été l'un des acteurs du projet génome humain, le Genoscope met aujourd'hui le cap vers la génomique environnementale.", 9 | "L'exploitation des données de séquences, prolongée par l'identification expérimentale des fonctions biologiques, notamment dans le domaine de la biocatalyse, ouvrent des perspectives de développements en biotechnologie industrielle." 10 | ], 11 | 12 | "\"Airbus livrera comme prévu 30 appareils 380 cette année avec en ligne de mire l'objectif d'équilibre financier du programme en 2015\", a-t-il ajouté.": 13 | [ 14 | "\"Airbus livrera comme prévu 30 appareils 380 cette année avec en ligne de mire l'objectif d'équilibre financier du programme en 2015\", a-t-il ajouté." 15 | ], 16 | 17 | 'À 11 heures ce matin, la direction ne décomptait que douze grévistes en tout sur la France : ce sont ceux du site de Saran (Loiret), dont l’effectif est de 809 salariés, dont la moitié d’intérimaires. Elle assure que ce mouvement « n’aura aucun impact sur les livraisons ».': 18 | [ 19 | 'À 11 heures ce matin, la direction ne décomptait que douze grévistes en tout sur la France : ce sont ceux du site de Saran (Loiret), dont l’effectif est de 809 salariés, dont la moitié d’intérimaires.', 20 | 'Elle assure que ce mouvement « n’aura aucun impact sur les livraisons ».' 21 | ], 22 | 23 | 'Ce modèle permet d’afficher le texte « LL.AA.II.RR. » pour l’abréviation de « Leurs Altesses impériales et royales » avec son infobulle.': 24 | [ 25 | 'Ce modèle permet d’afficher le texte « LL.AA.II.RR. » pour l’abréviation de « Leurs Altesses impériales et royales » avec son infobulle.' 26 | ], 27 | 28 | 'Les derniers ouvrages de Intercept Ltd. sont ici.': 29 | ['Les derniers ouvrages de Intercept Ltd. sont ici.'] 30 | 31 | } 32 | 33 | describe('French segment()', function () { 34 | for (const [text, expectedSentences] of Object.entries(tests)) { 35 | it(`correctly segments text: ${text}`, function () { 36 | const sentences = segment('fr', text) 37 | assert.deepEqual(sentences, expectedSentences) 38 | }) 39 | } 40 | }) 41 | -------------------------------------------------------------------------------- /test/ja.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 'これはペンです。それはマーカーです。': ['これはペンです。', 'それはマーカーです。'], 6 | 'それは何ですか?ペンですか?': ['それは何ですか?', 'ペンですか?'], 7 | '良かったね!すごい!': ['良かったね!', 'すごい!'], 8 | '自民党税制調査会の幹部は、「引き下げ幅は3.29%以上を目指すことになる」と指摘していて、今後、公明党と合意したうえで、30日に決定する与党税制改正大綱に盛り込むことにしています。2%台後半を目指すとする方向で最終調整に入りました。': 9 | [ 10 | '自民党税制調査会の幹部は、「引き下げ幅は3.29%以上を目指すことになる」と指摘していて、今後、公明党と合意したうえで、30日に決定する与党税制改正大綱に盛り込むことにしています。', 11 | '2%台後半を目指すとする方向で最終調整に入りました。' 12 | ], 13 | 'アンディ・ガトマンズ(英: Andi Gutmans、ヘブライ語: אנדי גוטמנס)はスイスにルーツを持つイスラエル人プログラマで、PHPの開発とゼンド・テクノロジーズの創業者の1人として知られている[1]。ハイファにあるイスラエル工科大学出身で、1997年に友人のゼーブ・スラスキーと共にPHP 3を開発した。1999年、PHP 4の中核である Zend Engine を開発し、ゼンド・テクノロジーズを創業。その後PHPの発展に関与し続け、PHP 5開発にも参加している[2]。なおZendという名称は、ガトマンズとスラスキーの名前(ZeevとAndi)を組み合わせたかばん語である[3]。 ハイファにあるイスラエル工科大学出身で、1997年に友人のゼーブ・スラスキーと共にPHP 3を開発した。1999年、PHP 4の中核である Zend Engine を開発し、ゼンド・テクノロジーズを創業。その後PHPの発展に関与し続け、PHP 5開発にも参加している[2]。なおZendという名称は、ガトマンズとスラスキーの名前(ZeevとAndi)を組み合わせたかばん語である[3]。': 14 | [ 15 | 'アンディ・ガトマンズ(英: Andi Gutmans、ヘブライ語: אנדי גוטמנס)はスイスにルーツを持つイスラエル人プログラマで、PHPの開発とゼンド・テクノロジーズの創業者の1人として知られている[1]。', 16 | 'ハイファにあるイスラエル工科大学出身で、1997年に友人のゼーブ・スラスキーと共にPHP 3を開発した。1999年、PHP 4の中核である Zend Engine を開発し、ゼンド・テクノロジーズを創業。', 17 | 'その後PHPの発展に関与し続け、PHP 5開発にも参加している[2]。', 18 | 'なおZendという名称は、ガトマンズとスラスキーの名前(ZeevとAndi)を組み合わせたかばん語である[3]。', 19 | 'ハイファにあるイスラエル工科大学出身で、1997年に友人のゼーブ・スラスキーと共にPHP 3を開発した。1999年、PHP 4の中核である Zend Engine を開発し、ゼンド・テクノロジーズを創業。', 20 | 'その後PHPの発展に関与し続け、PHP 5開発にも参加している[2]。', 21 | 'なおZendという名称は、ガトマンズとスラスキーの名前(ZeevとAndi)を組み合わせたかばん語である[3]。' 22 | ], 23 | 'ハイファにあるイスラエル工科大学出身で、1997年に友人のゼーブ・スラスキーと共にPHP 3を開発した。1999年、PHP 4の中核である Zend Engine を開発し、ゼンド・テクノロジーズを創業。その後PHPの発展に関与し続け、PHP 5開発にも参加している。なおZendという名称は、ガトマンズとスラスキーの名前(ZeevとAndi)を組み合わせたかばん語である。ハイファにあるイスラエル工科大学出身で、1997年に友人のゼーブ・スラスキーと共にPHP 3を開発した。1999年、PHP 4の中核である Zend Engine を開発し、ゼンド・テクノロジーズを創業。その後PHPの発展に関与し続け、PHP 5 開発にも参加している。なおZendという名称は、ガトマンズとスラスキーの名前(ZeevとAndi)を組み合わせたかばん語である。': 24 | [ 25 | 'ハイファにあるイスラエル工科大学出身で、1997年に友人のゼーブ・スラスキーと共にPHP 3を開発した。1999年、PHP 4の中核である Zend Engine を開発し、ゼンド・テクノロジーズを創業。', 26 | 'その後PHPの発展に関与し続け、PHP 5開発にも参加している。', 27 | 'なおZendという名称は、ガトマンズとスラスキーの名前(ZeevとAndi)を組み合わせたかばん語である。', 28 | 'ハイファにあるイスラエル工科大学出身で、1997年に友人のゼーブ・スラスキーと共にPHP 3を開発した。1999年、PHP 4の中核である Zend Engine を開発し、ゼンド・テクノロジーズを創業。', 29 | 'その後PHPの発展に関与し続け、PHP 5 開発にも参加している。', 30 | 'なおZendという名称は、ガトマンズとスラスキーの名前(ZeevとAndi)を組み合わせたかばん語である。' 31 | ] 32 | } 33 | 34 | describe('Japanese segment()', function () { 35 | for (const [text, expectedSentences] of Object.entries(tests)) { 36 | it(`correctly segments text: ${text}`, function () { 37 | const sentences = segment('ja', text) 38 | assert.deepEqual(sentences, expectedSentences) 39 | }) 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /src/languages/fi.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | 3 | const abbreviations = new Set([ 4 | 'A', 5 | 'B', 6 | 'C', 7 | 'D', 8 | 'E', 9 | 'F', 10 | 'G', 11 | 'H', 12 | 'I', 13 | 'J', 'K', 14 | 'L', 15 | 'M', 16 | 'N', 17 | 'O', 18 | 'P', 19 | 'Q', 20 | 'R', 21 | 'S', 22 | 'T', 23 | 'U', 24 | 'V', 25 | 'W', 26 | 'X', 27 | 'Y', 28 | 'Z', 29 | 'Å', 30 | 'Ä', 31 | 'Ö', 32 | // List of titles. 33 | // These are often followed by upper-case names, but do not indicate sentence breaks 34 | 'alik', 35 | 'alil', 36 | 'amir', 37 | 'apul', 38 | 'apul.prof', 39 | 'arkkit', 40 | 'ass', 41 | 'assist', 42 | 'dipl', 43 | 'dipl.arkkit', 44 | 'dipl.ekon', 45 | 'dipl.ins', 46 | 'dipl.kielenk', 47 | 'dipl.kirjeenv', 48 | 'dipl.kosm', 49 | 'dipl.urk', 50 | 'dos', 51 | 'Dr', 52 | 'erikoiseläinl', 53 | 'erikoishammasl', 54 | 'erikoisl', 55 | 'erikoist', 56 | 'ev.luutn', 57 | 'evp', 58 | 'fil', 59 | 'ft', 60 | 'hallinton', 61 | 'hallintot', 62 | 'hammaslääket', 63 | 'jatk', 64 | 'jääk', 65 | 'kansaned', 66 | 'kapt', 67 | 'kapt.luutn', 68 | 'kenr', 69 | 'kenr.luutn', 70 | 'kenr.maj', 71 | 'kers', 72 | 'kirjeenv', 73 | 'kom', 74 | 'kom.kapt', 75 | 'komm', 76 | 'konst', 77 | 'korpr', 78 | 'luutn', 79 | 'maist', 80 | 'maj', 81 | 'Mr', 82 | 'Mrs', 83 | 'Ms', 84 | 'M.Sc', 85 | 'neuv', 86 | 'nimim', 87 | 'Ph.D', 88 | 'prof', 89 | 'puh.joht', 90 | 'pääll', 91 | 'res', 92 | 'san', 93 | 'siht', 94 | 'suom', 95 | 'sähköp', 96 | 'säv', 97 | 'toht', 98 | 'toim', 99 | 'toim.apul', 100 | 'toim.joht', 101 | 'toim.siht', 102 | 'tuom', 103 | 'ups', 104 | 'vänr', 105 | 'vääp', 106 | 'ye.ups', 107 | 'ylik', 108 | 'ylil', 109 | 'ylim', 110 | 'ylimatr', 111 | 'yliop', 112 | 'yliopp', 113 | 'ylip', 114 | 'yliv', 115 | // misc - odd period-ending items that NEVER indicate breaks (p.m. does NOT fall 116 | // into this category - it sometimes ends a sentence) 117 | 'e.g', 118 | 'ent', 119 | 'esim', 120 | 'huom', 121 | 'i.e', 122 | 'ilm', 123 | 'l', 124 | 'mm', 125 | 'myöh', 126 | 'nk', 127 | 'nyk', 128 | 'par', 129 | 'po', 130 | 't', 131 | 'v' 132 | ]) 133 | 134 | export default class Finnish extends BaseLanguage { 135 | static abbreviations = abbreviations 136 | static MONTHS = new Set([ 137 | 'tammikuu', 138 | 'helmikuu', 139 | 'maaliskuu', 140 | 'huhtikuu', 141 | 'toukokuu', 142 | 'kesäkuu', 143 | 'heinäkuu', 144 | 'elokuu', 145 | 'syyskuu', 146 | 'lokakuu', 147 | 'marraskuu', 148 | 'joulukuu' 149 | ]) 150 | 151 | continueInNextWord (textAfterBoundary) { 152 | if (textAfterBoundary.match(/^\W*[0-9a-z]/)) { 153 | return true 154 | } 155 | 156 | const nextWord = textAfterBoundary.trim().split(' ')[0] 157 | 158 | if (!nextWord.length) { 159 | return false 160 | } 161 | if (Finnish.MONTHS.has(nextWord) || Finnish.MONTHS.has(nextWord[0].toUpperCase() + nextWord.slice(1))) { 162 | return true 163 | } 164 | 165 | return false 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > NOTE: 2 | > This repository is deprecated, The original [sentencex](https://github.com/santhoshtr/sentencex) library is written in Rust and has node bindings. The node library name and APIs are same. 3 | 4 | # Sentence segmenter 5 | 6 | [](https://github.com/santhoshtr/sentencex/actions/workflows/nodejs.yaml) 7 | [](https://www.npmjs.com/package/sentencex) 8 | 9 | A sentence segmentation library with wide language support optimized for speed and utility. 10 | 11 | This is a javascript port of [sentencex python library](https://github.com/santhoshtr/sentencex) 12 | 13 | ## Approach 14 | 15 | - If it's a period, it ends a sentence. 16 | - If the preceding token is in the hand-compiled list of abbreviations, then it doesn't end a sentence. 17 | 18 | However, it is not 'period' for many languages. So we will use a list of known punctuations that can cause a sentence break in as many languages as possible. 19 | 20 | We also collect a list of known, popular abbreviations in as many languages as possible. 21 | 22 | Sometimes, it is very hard to get the segmentation correct. In such cases this library is opinionated and prefer not segmenting than wrong segmentation. If two sentences are accidentally together, that is ok. It is better than sentence being split in middle. 23 | Avoid over engineering to get everything linguistically 100% accurate. 24 | 25 | This approach would be suitable for applications like text to speech, machine translation. 26 | 27 | Consider this example: `We make a good team, you and I. Did you see Albert I. Jones yesterday?` 28 | 29 | The accurate splitting of this sentence is 30 | `["We make a good team, you and I." ,"Did you see Albert I. Jones yesterday?"]` 31 | 32 | However, to achieve this level precision, complex rules need to be added and it could create side effects. Instead, if we just don't segment between `I. Did`, it is ok for most of downstream applications. 33 | 34 | The sentence segmentation in this library is **non-distructive**. This means, if the sentences are combined together, you can reconstruct the original text. Line breaks, punctuations and whitespaces are preserved in the output. 35 | 36 | ## Usage 37 | 38 | Install the library using 39 | 40 | ```bash 41 | npm install --save sentencex 42 | ``` 43 | 44 | Then, any text can be segmented as follows. 45 | 46 | ```javascript 47 | import segment from 'sentencex' 48 | 49 | text = ` 50 | The James Webb Space Telescope (JWST) is a space telescope specifically designed to conduct infrared astronomy. The U.S. National Aeronautics and Space Administration (NASA) led Webb's design and development") 51 | ` 52 | console.log(segment("en", text)) 53 | 54 | ``` 55 | 56 | The first argument is language code, second argument is text to segment. The `segment` method returns an array of identified sentences. 57 | 58 | ## Language support 59 | 60 | The aim is to support all languages where there is a wikipedia. Instead of falling back on English for languages not defined in the library, a fallback chain is used. The closest language which is defined in the library will be used. Fallbacks for ~244 languages are defined. 61 | 62 | ## License 63 | 64 | MIT license. See [License](./LICENSE) 65 | -------------------------------------------------------------------------------- /src/languages/en.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | 3 | const abbreviations = new Set([ 4 | 'A', 5 | 'adj', 6 | 'adm', 7 | 'adv', 8 | 'al', 9 | 'ala', 10 | 'alta', 11 | 'apr', 12 | 'arc', 13 | 'ariz', 14 | 'ark', 15 | 'art', 16 | 'assn', 17 | 'asst', 18 | 'attys', 19 | 'aug', 20 | 'ave', 21 | 'B', 22 | 'bart', 23 | 'bld', 24 | 'bldg', 25 | 'blvd', 26 | 'brig', 27 | 'bros', 28 | 'btw', 29 | 'C', 30 | 'cal', 31 | 'calif', 32 | 'capt', 33 | 'cl', 34 | 'cmdr', 35 | 'co', 36 | 'col', 37 | 'colo', 38 | 'comdr', 39 | 'con', 40 | 'conn', 41 | 'corp', 42 | 'cpl', 43 | 'cres', 44 | 'ct', 45 | 'd.phil', 46 | 'D', 47 | 'dak', 48 | 'dec', 49 | 'del', 50 | 'dept', 51 | 'det', 52 | 'dist', 53 | 'dr.phil', 54 | 'dr.philos', 55 | 'dr', 56 | 'drs', 57 | 'e.g', 58 | 'E', 59 | 'ens', 60 | 'esp', 61 | 'esq', 62 | 'etc', 63 | 'exp', 64 | 'expy', 65 | 'ext', 66 | 'F', 67 | 'feb', 68 | 'fed', 69 | 'fig', 70 | 'fla', 71 | 'ft', 72 | 'fwy', 73 | 'fy', 74 | 'G', 75 | 'ga', 76 | 'gen', 77 | 'gov', 78 | 'H', 79 | 'hon', 80 | 'hosp', 81 | 'hr', 82 | 'hway', 83 | 'hwy', 84 | 'i.e', 85 | 'I', 86 | 'ia', 87 | 'id', 88 | 'ida', 89 | 'ill', 90 | 'inc', 91 | 'ind', 92 | 'ing', 93 | 'insp', 94 | 'J', 95 | 'jan', 96 | 'jr', 97 | 'jul', 98 | 'jun', 99 | 'K', 100 | 'kan', 101 | 'kans', 102 | 'ken', 103 | 'ky', 104 | 'L', 105 | 'la', 106 | 'lt', 107 | 'ltd', 108 | 'M', 109 | 'maj', 110 | 'man', 111 | 'mar', 112 | 'mass', 113 | 'may', 114 | 'md', 115 | 'me', 116 | 'med', 117 | 'messrs', 118 | 'mex', 119 | 'mfg', 120 | 'mich', 121 | 'min', 122 | 'minn', 123 | 'miss', 124 | 'mlle', 125 | 'mm', 126 | 'mme', 127 | 'mo', 128 | 'mont', 129 | 'mr', 130 | 'mrs', 131 | 'ms', 132 | 'msgr', 133 | 'mssrs', 134 | 'mt', 135 | 'mtn', 136 | 'Nº', 137 | 'N°', 138 | 'No̱', 139 | 'No', 140 | 'N', 141 | 'neb', 142 | 'nebr', 143 | 'nev', 144 | 'no', 145 | 'nos', 146 | 'nov', 147 | 'nr', 148 | 'O', 149 | 'oct', 150 | 'ok', 151 | 'okla', 152 | 'ont', 153 | 'op', 154 | 'ord', 155 | 'ore', 156 | 'p', 157 | 'P', 158 | 'pa', 159 | 'pd', 160 | 'pde', 161 | 'penn', 162 | 'penna', 163 | 'pfc', 164 | 'ph.d', 165 | 'ph', 166 | 'pl', 167 | 'plz', 168 | 'pp', 169 | 'prof', 170 | 'pvt', 171 | 'Q', 172 | 'que', 173 | 'R', 174 | 'rd', 175 | 'ref', 176 | 'rep', 177 | 'reps', 178 | 'res', 179 | 'rev', 180 | 'rs', 181 | 'rt', 182 | 'S', 183 | 'sask', 184 | 'sec', 185 | 'sen', 186 | 'sens', 187 | 'sep', 188 | 'sept', 189 | 'sfc', 190 | 'sgt', 191 | 'sr', 192 | 'st', 193 | 'supt', 194 | 'surg', 195 | 'T', 196 | 'tce', 197 | 'tenn', 198 | 'tex', 199 | 'u.s', 200 | 'U', 201 | 'univ', 202 | 'usafa', 203 | 'ut', 204 | 'v', 205 | 'V', 206 | 'va', 207 | 'ver', 208 | 'viz', 209 | 'vs', 210 | 'vt', 211 | 'W', 212 | 'wash', 213 | 'wis', 214 | 'wisc', 215 | 'wy', 216 | 'wyo', 217 | 'X', 218 | 'Y', 219 | 'yuk', 220 | 'Z' 221 | ]) 222 | 223 | export default class English extends BaseLanguage { 224 | static abbreviations = abbreviations 225 | } 226 | -------------------------------------------------------------------------------- /test/kk.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 'Мұхитқа тікелей шыға алмайтын мемлекеттердің ішінде Қазақстан - ең үлкені.': 6 | ['Мұхитқа тікелей шыға алмайтын мемлекеттердің ішінде Қазақстан - ең үлкені.'], 7 | 8 | 'Әр түрлі өлшемнің атауы болып табылатын м (метр), см (сантиметр), кг (киллограмм), т (тонна), га (гектар), ц (центнер), т. б. (тағы басқа), тәрізді белгілер де қысқарған сөздер болып табылады.': 9 | [ 10 | 'Әр түрлі өлшемнің атауы болып табылатын м (метр), см (сантиметр), кг (киллограмм), т (тонна), га (гектар), ц (центнер), т. б. (тағы басқа), тәрізді белгілер де қысқарған сөздер болып табылады.' 11 | ], 12 | 13 | 'Мысалы: обкомға (облыстық комитетке) барды, ауаткомда (аудандық атқару комитетінде) болды, педучилищеге (педагогтік училищеге) түсті, медпункттің (медициналық пункттің) алдында т. б.': 14 | [ 15 | 'Мысалы: обкомға (облыстық комитетке) барды, ауаткомда (аудандық атқару комитетінде) болды, педучилищеге (педагогтік училищеге) түсті, медпункттің (медициналық пункттің) алдында т. б.' 16 | ], 17 | 'Елдің жалпы ішкі өнімі ЖІӨ (номинал) = $225.619 млрд (2014)': 18 | ['Елдің жалпы ішкі өнімі ЖІӨ (номинал) = $225.619 млрд (2014)'], 19 | 'Ресейдiң әлеуметтiк-экономикалық жағдайы.XVIII ғасырдың бiрiншi ширегiнде Ресейге тән нәрсе.': 20 | [ 21 | 'Ресейдiң әлеуметтiк-экономикалық жағдайы.', 22 | 'XVIII ғасырдың бiрiншi ширегiнде Ресейге тән нәрсе.' 23 | ], 24 | // '(«Егемен Қазақстан», 7 қыркүйек 2012 жыл. №590-591); Бұл туралы кеше санпедқадағалау комитетінің облыыстық департаменті хабарлады. («Айқын», 23 сəуір 2010 жыл. № 70).': 25 | // [ 26 | // '(«Егемен Қазақстан», 7 қыркүйек 2012 жыл. №590-591); Бұл туралы кеше санпедқадағалау комитетінің облыыстық департаменті хабарлады.', 27 | // '(«Айқын», 23 сəуір 2010 жыл. № 70).' 28 | // ], 29 | 'Иран революциясы (1905 — 11) және азаматтық қозғалыс (1918 — 21) кезінде А. Фарахани, М. Кермани, М. Т. Бехар, т.б. ақындар демократиялық идеяның жыршысы болды.': 30 | [ 31 | 'Иран революциясы (1905 — 11) және азаматтық қозғалыс (1918 — 21) кезінде А. Фарахани, М. Кермани, М. Т. Бехар, т.б. ақындар демократиялық идеяның жыршысы болды.' 32 | ], 33 | 'Владимир Федосеев: Аттар магиясы енді жоқ http://www.vremya.ru/2003/179/10/80980.html': 34 | ['Владимир Федосеев: Аттар магиясы енді жоқ http://www.vremya.ru/2003/179/10/80980.html'], 35 | 36 | 'Бірақ оның енді не керегі бар? — деді.': ['Бірақ оның енді не керегі бар? — деді.'], 37 | 38 | 'Сондықтан шапаныма жегізіп отырғаным! - деп, жауап береді.': 39 | ['Сондықтан шапаныма жегізіп отырғаным! - деп, жауап береді.'], 40 | 41 | 'Б.з.б. 6 – 3 ғасырларда конфуцийшілдік, моизм, легизм мектептерінің қалыптасуы нәтижесінде Қытай философиясы пайда болды.': 42 | [ 43 | 'Б.з.б. 6 – 3 ғасырларда конфуцийшілдік, моизм, легизм мектептерінің қалыптасуы нәтижесінде Қытай философиясы пайда болды.' 44 | ], 45 | 46 | "'Та марбута' тек сөз соңында екі түрде жазылады:": ["'Та марбута' тек сөз соңында екі түрде жазылады:"] 47 | 48 | } 49 | 50 | describe('Kazakh segment()', function () { 51 | for (const [text, expectedSentences] of Object.entries(tests)) { 52 | it(`correctly segments text: ${text}`, function () { 53 | const sentences = segment('kk', text) 54 | assert.deepEqual(sentences, expectedSentences) 55 | }) 56 | } 57 | }) 58 | -------------------------------------------------------------------------------- /src/languages/de.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | import English from './en.js' 3 | 4 | const abbreviations = new Set([ 5 | ...English.abbreviations, 6 | 'ä', 7 | 'Ä', 8 | 'adj', 9 | 'adm', 10 | 'adv', 11 | 'ao.univ.prof', 12 | 'art', 13 | 'ass.prof', 14 | 'ass', 15 | 'asst', 16 | 'b.a', 17 | 'b.s', 18 | 'bart', 19 | 'bldg', 20 | 'brig', 21 | 'bros', 22 | 'bse', 23 | 'buchst', 24 | 'bzgl', 25 | 'bzw', 26 | 'c.-à-d', 27 | 'ca', 28 | 'capt', 29 | 'chr', 30 | 'cmdr', 31 | 'co', 32 | 'col', 33 | 'comdr', 34 | 'con', 35 | 'corp', 36 | 'cpl', 37 | 'd.h', 38 | 'd.j', 39 | 'dergl', 40 | 'dgl', 41 | 'di', 42 | 'dipl.-ing', 43 | 'dkr', 44 | 'dr ', 45 | 'ens', 46 | 'etc', 47 | 'ev ', 48 | 'evtl', 49 | 'ff', 50 | 'g.g.a', 51 | 'g.u', 52 | 'gen', 53 | 'ggf', 54 | 'gov', 55 | 'hon.prof', 56 | 'hon', 57 | 'hosp', 58 | 'i.f', 59 | 'i.h.v', 60 | 'ii', 61 | 'iii', 62 | 'insp', 63 | 'iv', 64 | 'ix', 65 | 'jun', 66 | 'k.o', 67 | 'kath', 68 | 'lfd', 69 | 'lt', 70 | 'ltd', 71 | 'm.e', 72 | 'mag', 73 | 'maj', 74 | 'med', 75 | 'messrs', 76 | 'mio', 77 | 'mlle', 78 | 'mm', 79 | 'mme', 80 | 'mr', 81 | 'mrd', 82 | 'mrs', 83 | 'ms', 84 | 'msgr', 85 | 'mwst', 86 | 'no', 87 | 'nos', 88 | 'nr', 89 | 'o.ä', 90 | 'o.univ.-prof', 91 | 'op', 92 | 'ord', 93 | 'pfc', 94 | 'ph', 95 | 'pp', 96 | 'prof', 97 | 'projektass', 98 | 'pvt', 99 | 'rep', 100 | 'reps', 101 | 'res', 102 | 'rev', 103 | 'rt', 104 | 's', 105 | 's.p.a', 106 | 'sa', 107 | 'sen', 108 | 'sens', 109 | 'sfc', 110 | 'sgt', 111 | 'sog', 112 | 'sogen', 113 | 'spp', 114 | 'sr', 115 | 'st', 116 | 'std', 117 | 'str ', 118 | 'stud.ass', 119 | 'supt', 120 | 'surg', 121 | 'T', 122 | 'u.a ', 123 | 'u.ä', 124 | 'u.e', 125 | 'u.s.w', 126 | 'u.u', 127 | 'univ.-doz', 128 | 'univ.-prof', 129 | 'univ.ass', 130 | 'usf', 131 | 'usw', 132 | 'v', 133 | 'vgl', 134 | 'vi', 135 | 'vii', 136 | 'viii', 137 | 'vs', 138 | 'x', 139 | 'xi', 140 | 'xii', 141 | 'xiii', 142 | 'xiv', 143 | 'xix', 144 | 'xv', 145 | 'xvi', 146 | 'xvii', 147 | 'xviii', 148 | 'xx', 149 | 'z.b', 150 | 'z.t', 151 | 'z.z', 152 | 'z.zt', 153 | 'zt', 154 | 'zzt' 155 | 156 | ]) 157 | 158 | export default class Deutsch extends BaseLanguage { 159 | static abbreviations = abbreviations 160 | static MONTHS = new Set([ 161 | 'Januar', 162 | 'Februar', 163 | 'März', 164 | 'April', 165 | 'Mai', 166 | 'Juni', 167 | 'Juli', 168 | 'August', 169 | 'September', 170 | 'Oktober', 171 | 'November', 172 | 'Dezember' 173 | ]) 174 | 175 | continueInNextWord (textAfterBoundary) { 176 | if (textAfterBoundary.match(/^\W*[0-9a-z]/)) { 177 | return true 178 | } 179 | 180 | let nextWord = textAfterBoundary.trim().split(' ')[0] 181 | nextWord = nextWord.replace(/[?!.]/g, '') 182 | if (!nextWord.length) { 183 | return false 184 | } 185 | if (Deutsch.MONTHS.has(nextWord) || Deutsch.MONTHS.has(nextWord[0].toUpperCase() + nextWord.slice(1))) { 186 | return true 187 | } 188 | 189 | return false 190 | } 191 | 192 | isPunctuationBetweenQuotes () { 193 | return true 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /src/languages/es.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | 3 | const abbreviations = new Set([ 4 | 'a.c', 5 | 'a', 6 | 'a/c', 7 | 'abr', 8 | 'adj', 9 | 'admón', 10 | 'aero', 11 | 'afmo', 12 | 'ago', 13 | 'almte', 14 | 'ambi', 15 | 'an', 16 | 'anfi', 17 | 'ante', 18 | 'anti', 19 | 'ap', 20 | 'apdo', 21 | 'archi', 22 | 'arci', 23 | 'arq', 24 | 'art', 25 | 'atte', 26 | 'auto', 27 | 'av', 28 | 'avda', 29 | 'bco', 30 | 'bi', 31 | 'bibl', 32 | 'bien', 33 | 'bis', 34 | 'bs. as', 35 | 'c.f', 36 | 'c.g', 37 | 'c', 38 | 'c/c', 39 | 'c/u', 40 | 'cap', 41 | 'cc.aa', 42 | 'cdad', 43 | 'cm', 44 | 'co', 45 | 'com', 46 | 'con', 47 | 'contra', 48 | 'cra', 49 | 'crio', 50 | 'cta', 51 | 'cuadri', 52 | 'cuasi', 53 | 'cuatri', 54 | 'cv', 55 | 'd.e.p', 56 | 'da', 57 | 'dcha', 58 | 'dcho', 59 | 'de', 60 | 'deci', 61 | 'dep', 62 | 'des', 63 | 'di', 64 | 'dic', 65 | 'dicc', 66 | 'dir', 67 | 'dis', 68 | 'dn', 69 | 'doc', 70 | 'dom', 71 | 'dpto', 72 | 'dr', 73 | 'dra', 74 | 'dto', 75 | 'ecto', 76 | 'ee', 77 | 'ej', 78 | 'en', 79 | 'endo', 80 | 'entlo', 81 | 'entre', 82 | 'epi', 83 | 'equi', 84 | 'esq', 85 | 'etc', 86 | 'ex', 87 | 'excmo', 88 | 'ext', 89 | 'extra', 90 | 'f.c', 91 | 'fca', 92 | 'fdo', 93 | 'febr', 94 | 'ff. aa', 95 | 'ff.cc', 96 | 'fig', 97 | 'fil', 98 | 'fra', 99 | 'g.p', 100 | 'g/p', 101 | 'geo', 102 | 'gob', 103 | 'gr', 104 | 'gral', 105 | 'grs', 106 | 'hemi', 107 | 'hetero', 108 | 'hiper', 109 | 'hipo', 110 | 'hnos', 111 | 'homo', 112 | 'hs', 113 | 'i', 114 | 'igl', 115 | 'iltre', 116 | 'im', 117 | 'imp', 118 | 'impr', 119 | 'impto', 120 | 'in', 121 | 'incl', 122 | 'infra', 123 | 'ing', 124 | 'inst', 125 | 'inter', 126 | 'intra', 127 | 'iso', 128 | 'izdo', 129 | 'izq', 130 | 'izqdo', 131 | 'j.c', 132 | 'jue', 133 | 'jul', 134 | 'jun', 135 | 'kg', 136 | 'km', 137 | 'lcdo', 138 | 'ldo', 139 | 'let', 140 | 'lic', 141 | 'ltd', 142 | 'lun', 143 | 'macro', 144 | 'mar', 145 | 'máx', 146 | 'may', 147 | 'mega', 148 | 'mg', 149 | 'micro', 150 | 'mié', 151 | 'min', 152 | 'mín', 153 | 'mini', 154 | 'mm', 155 | 'mono', 156 | 'mt', 157 | 'multi', 158 | 'n. del t', 159 | 'n.b', 160 | 'neo', 161 | 'no', 162 | 'nos', 163 | 'nov', 164 | 'ntra. sra', 165 | 'núm', 166 | 'oct', 167 | 'omni', 168 | 'p.a', 169 | 'p.d', 170 | 'p.ej', 171 | 'p.v.p', 172 | 'p', 173 | 'pág', 174 | 'págs', 175 | 'para', 176 | 'párr', 177 | 'párrf', 178 | 'pen', 179 | 'ph.d', 180 | 'ph', 181 | 'pluri', 182 | 'poli', 183 | 'pos', 184 | 'post', 185 | 'pp', 186 | 'ppal', 187 | 'pre', 188 | 'prev', 189 | 'pro', 190 | 'prof', 191 | 'prov', 192 | 'pseudo', 193 | 'ptas', 194 | 'pts', 195 | 'pza', 196 | 'q.e.g.e', 197 | 'q.e.p.d', 198 | 'q.e.s.m', 199 | 're', 200 | 'reg', 201 | 'rep', 202 | 'retro', 203 | 'rr. hh', 204 | 'rte', 205 | 's. a', 206 | 's.a.r', 207 | 's.e', 208 | 's.l', 209 | 's.r.c', 210 | 's.r.l', 211 | 's.s.s', 212 | 's', 213 | 's/n', 214 | 'sáb', 215 | 'sdad', 216 | 'seg', 217 | 'semi', 218 | 'sept', 219 | 'seudo', 220 | 'sig', 221 | 'sobre', 222 | 'sr', 223 | 'sra', 224 | 'sres', 225 | 'srta', 226 | 'sta', 227 | 'sto', 228 | 'sub', 229 | 'super', 230 | 'supra', 231 | 't.v.e', 232 | 'tamb', 233 | 'tel', 234 | 'tfno', 235 | 'trans', 236 | 'tras', 237 | 'tri', 238 | 'ud', 239 | 'uds', 240 | 'ulter', 241 | 'ultra', 242 | 'un', 243 | 'uni', 244 | 'univ', 245 | 'uu', 246 | 'v.b', 247 | 'v.e', 248 | 'vd', 249 | 'vds', 250 | 'vice', 251 | 'vid', 252 | 'vie', 253 | 'vol', 254 | 'vs', 255 | 'vto', 256 | 'yuxta' 257 | ]) 258 | 259 | export default class Spanish extends BaseLanguage { 260 | static abbreviations = abbreviations 261 | } 262 | -------------------------------------------------------------------------------- /src/languages/sk.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | 3 | const MONTHS = new Set([ 4 | 'Január', 5 | 'Február', 6 | 'Marec', 7 | 'Apríl', 8 | 'Máj', 9 | 'Jún', 10 | 'Júl', 11 | 'August', 12 | 'September', 13 | 'Október', 14 | 'November', 15 | 'December', 16 | 'Januára', 17 | 'Februára', 18 | 'Marca', 19 | 'Apríla', 20 | 'Mája', 21 | 'Júna', 22 | 'Júla', 23 | 'Augusta', 24 | 'Septembra', 25 | 'Októbra', 26 | 'Novembra', 27 | 'Decembra' 28 | ]) 29 | 30 | const romanNumerals = 'i ii iii iv v vi vii viii ix x xi xii xiii xiv x xi xii xiii xv xvi xvii xviii xix xx' 31 | 32 | const romanNumeralsSet = new Set([...romanNumerals.split(' '), ...romanNumerals.toUpperCase().split(' ')]) 33 | 34 | const abbreviations = new Set([ 35 | ...romanNumeralsSet, 36 | 'a. d', 37 | 'a. g. p', 38 | 'a. i. i', 39 | 'a. k. a', 40 | 'a. m', 41 | 'a. r. k', 42 | 'a. s. a. p', 43 | 'a. s', 44 | 'a. v', 45 | 'a.d', 46 | 'a.g.p', 47 | 'a.i.i', 48 | 'a.k.a', 49 | 'a.m', 50 | 'a.s.a.p', 51 | 'a.s', 52 | 'a.v', 53 | 'akad', 54 | 'al', 55 | 'apod', 56 | 'arm', 57 | 'atď.', 58 | 'atd', 59 | 'atď', 60 | 'bc', 61 | 'bros', 62 | 'c. k', 63 | 'c.k', 64 | 'č', 65 | 'cca', 66 | 'co', 67 | 'corp', 68 | 'čs', 69 | 'csc', 70 | 'čsl', 71 | 'd. c', 72 | 'd.c', 73 | 'doc', 74 | 'dr', 75 | 'drsc', 76 | 'e. t', 77 | 'e.t', 78 | 'el', 79 | 'etc', 80 | 'ev', 81 | 'gen', 82 | 'hl', 83 | 'hod', 84 | 'i. b', 85 | 'i.b', 86 | 'ii', 87 | 'iii', 88 | 'inc', 89 | 'ind', 90 | 'ing', 91 | 'iv', 92 | 'jr', 93 | 'judr', 94 | 'k. o', 95 | 'k.o', 96 | 'kol', 97 | 'konkr', 98 | 'kt', 99 | 'll. m', 100 | 'll.m', 101 | 'ltd', 102 | 'm. n. m', 103 | 'm.n.m', 104 | 'm.o', 105 | 'max', 106 | 'mgr', 107 | 'mil', 108 | 'min', 109 | 'ml', 110 | 'mld', 111 | 'mr', 112 | 'mudr', 113 | 'mvdr', 114 | 'n. a', 115 | 'n. o', 116 | 'n. w. a', 117 | 'n.a', 118 | 'n.o', 119 | 'n.w.a', 120 | 'nám', 121 | 'napr', 122 | 'např', 123 | 'naprk', 124 | 'nár', 125 | 'nešp', 126 | 'no', 127 | 'nr', 128 | 'o. c. p', 129 | 'o. f. i', 130 | 'o. k', 131 | 'o. z', 132 | 'o.c.p', 133 | 'o.f.i', 134 | 'o.i', 135 | 'o.k', 136 | 'o.z', 137 | 'obr', 138 | 'obv', 139 | 'odd', 140 | 'ods', 141 | 'os', 142 | 'p. a', 143 | 'p. n. l', 144 | 'p. s', 145 | 'p.a', 146 | 'p.n.l', 147 | 'p.s', 148 | 'p', 149 | 'paeddr', 150 | 'pedg', 151 | 'ph. d', 152 | 'ph.d', 153 | 'phd', 154 | 'phdr', 155 | 'písm', 156 | 'plgr', 157 | 'pod', 158 | 'pok', 159 | 'pol. pr', 160 | 'pol.pr', 161 | 'por', 162 | 'pozn', 163 | 'pp', 164 | 'pr', 165 | 'prek', 166 | 'príp', 167 | 'prof', 168 | 'r. o', 169 | 'r.o', 170 | 'red', 171 | 'resp', 172 | 'rndr', 173 | 'roz', 174 | 'rozh', 175 | 'rsdr', 176 | 'rtg', 177 | 's. a', 178 | 's. e. g', 179 | 'š. p', 180 | 's. r. o', 181 | 's.a', 182 | 's.e.g', 183 | 'š.p', 184 | 's.r.o', 185 | 'skr', 186 | 'sl', 187 | 'slov', 188 | 'soc', 189 | 'sp', 190 | 'spol', 191 | 'sr', 192 | 'st', 193 | 'št', 194 | 'stor', 195 | 'str', 196 | 'stred', 197 | 'súkr', 198 | 'sv', 199 | 'sz', 200 | 't. č', 201 | 't. j', 202 | 't. z', 203 | 't.č', 204 | 't.j', 205 | 't.z', 206 | 'tel', 207 | 'tis', 208 | 'tj', 209 | 'tr', 210 | 'tu', 211 | 'tvz', 212 | 'tz', 213 | 'tzn', 214 | 'tzv', 215 | 'ú. p. v. o', 216 | 'u. s', 217 | 'ú.p.v.o', 218 | 'u.s', 219 | 'ul', 220 | 'v. sp', 221 | 'v.sp', 222 | 'var', 223 | 'vi', 224 | 'viď', 225 | 'vs', 226 | 'vyd', 227 | 'vz', 228 | 'xx', 229 | 'z. z', 230 | 'z.z', 231 | 'zák', 232 | 'zb', 233 | 'zdravot', 234 | 'zs', 235 | 'zz' 236 | ]) 237 | 238 | export default class Slovak extends BaseLanguage { 239 | static abbreviations = abbreviations 240 | 241 | continueInNextWord (textAfterBoundary) { 242 | if (textAfterBoundary.match(/^\W*[0-9a-z]/)) { 243 | return true 244 | } 245 | 246 | const nextWord = textAfterBoundary.trim().split(' ')[0] 247 | 248 | if (!nextWord.length) { 249 | return false 250 | } 251 | if (MONTHS.has(nextWord) || MONTHS.has(nextWord[0].toUpperCase() + nextWord.slice(1))) { 252 | return true 253 | } 254 | 255 | return false 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /src/languages/kk.js: -------------------------------------------------------------------------------- 1 | import BaseLanguage from '../base.js' 2 | 3 | const abbreviations = new Set([ 4 | 'afp', 5 | 'anp', 6 | 'atp', 7 | 'aбб', 8 | 'bae', 9 | 'bg', 10 | 'bp', 11 | 'cam', 12 | 'cctv', 13 | 'cd', 14 | 'cez', 15 | 'cgi', 16 | 'cnpc', 17 | 'dvd', 18 | 'eiti', 19 | 'epo', 20 | 'er', 21 | 'farc', 22 | 'fbi', 23 | 'gp', 24 | 'gps', 25 | 'has', 26 | 'hiv', 27 | 'hrh', 28 | 'http', 29 | 'icu', 30 | 'idf', 31 | 'imd', 32 | 'ime', 33 | 'ip', 34 | 'iso', 35 | 'kaz', 36 | 'kpa', 37 | 'kpo', 38 | 'kz', 39 | 'mgm', 40 | 'mri', 41 | 'nasa', 42 | 'nba', 43 | 'nbc', 44 | 'nds', 45 | 'ohl', 46 | 'omlt', 47 | 'pda', 48 | 'pkk', 49 | 'ppm', 50 | 'psm', 51 | 'psp', 52 | 'raf', 53 | 'rss', 54 | 'rtl', 55 | 'sas', 56 | 'sme', 57 | 'sms', 58 | 'tnt', 59 | 'udf', 60 | 'uefa', 61 | 'usb', 62 | 'utc', 63 | 'x', 64 | 'zdf', 65 | 'а.', 66 | 'аақ', 67 | 'авг.', 68 | 'аек', 69 | 'ак', 70 | 'акад.', 71 | 'акср', 72 | 'акцион.', 73 | 'ақ', 74 | 'ақш', 75 | 'амт', 76 | 'англ', 77 | 'аөсшк', 78 | 'апр.', 79 | 'апр', 80 | 'аум.', 81 | 'аф', 82 | 'ацат', 83 | 'әқбк', 84 | 'әөк', 85 | 'әч', 86 | 'б. з. б.', 87 | 'б. з. д.', 88 | 'б. т.', 89 | 'б. э. д.', 90 | 'б.б.', 91 | 'ббс', 92 | 'биікт.', 93 | 'биол.', 94 | 'биохим', 95 | 'бмтрк', 96 | 'боак', 97 | 'бө', 98 | 'бсн', 99 | 'бта', 100 | 'бұұ', 101 | 'бхооо', 102 | 'вич', 103 | 'всоонл', 104 | 'г', 105 | 'геогр.', 106 | 'геол.', 107 | 'гленкор', 108 | 'гсбп', 109 | 'гсдп', 110 | 'гулаг', 111 | 'гэс', 112 | 'ғ. с.', 113 | 'ғ.', 114 | 'дек.', 115 | 'дк', 116 | 'днқ', 117 | 'дсұ', 118 | 'еақк', 119 | 'еаэы', 120 | 'еқыұ', 121 | 'ембімұнайгаз', 122 | 'ео', 123 | 'еуразэқ', 124 | 'еуроодақ', 125 | 'еұу', 126 | 'еэы', 127 | 'ж.', 128 | 'жж.', 129 | 'жіө', 130 | 'жко', 131 | 'жкт', 132 | 'жққ', 133 | 'жоо', 134 | 'жсдп', 135 | 'жск', 136 | 'жтсх', 137 | 'жхл', 138 | 'жшс', 139 | 'жэк', 140 | 'зоо', 141 | 'и.', 142 | 'инта', 143 | 'исаф', 144 | 'іім', 145 | 'камаз', 146 | 'кг', 147 | 'кгб', 148 | 'кеу', 149 | 'кимеп', 150 | 'км', 151 | 'км²', 152 | 'км³', 153 | 'кмс', 154 | 'кокп', 155 | 'кота', 156 | 'кср', 157 | 'ксро', 158 | 'кту', 159 | 'кхдр', 160 | 'қ.', 161 | 'қазатомпром', 162 | 'қазкср', 163 | 'қазмұнайгаз', 164 | 'қазпошта', 165 | 'қазтаг', 166 | 'қазұу', 167 | 'қк', 168 | 'қкп', 169 | 'ққс', 170 | 'қмдб', 171 | 'қр', 172 | 'қхр', 173 | 'лат.', 174 | 'м.', 175 | 'м', 176 | 'м²', 177 | 'м³', 178 | 'магатэ', 179 | 'маж', 180 | 'май.', 181 | 'максам', 182 | 'мб', 183 | 'мбф', 184 | 'мвт', 185 | 'мемдум', 186 | 'мемл', 187 | 'мин', 188 | 'мқо', 189 | 'млн', 190 | 'млрд', 191 | 'мм.', 192 | 'мм', 193 | 'мр', 194 | 'мсоп', 195 | 'мт', 196 | 'мтк', 197 | 'мыс.', 198 | 'наса', 199 | 'нато', 200 | 'нквд', 201 | 'нояб.', 202 | 'нұсжп', 203 | 'оар', 204 | 'обб', 205 | 'обл.', 206 | 'огпу', 207 | 'оеб', 208 | 'окт.', 209 | 'оңт.', 210 | 'опек', 211 | 'өгк', 212 | 'өзенмұнайгаз', 213 | 'өұқ', 214 | 'өф', 215 | 'пәк', 216 | 'пед.', 217 | 'пиқ', 218 | 'р.', 219 | 'ржмб', 220 | 'ркфср', 221 | 'рлдп', 222 | 'рнқ', 223 | 'рсфср', 224 | 'ртж', 225 | 'руб', 226 | 'рф', 227 | 'рфкп', 228 | 'с.', 229 | 'с.ш.', 230 | 'сбд', 231 | 'сбл', 232 | 'свс', 233 | 'сву', 234 | 'сду', 235 | 'сент.', 236 | 'сес', 237 | 'см', 238 | 'снпс', 239 | 'солт.', 240 | 'сооно', 241 | 'спбму', 242 | 'сср', 243 | 'ссро', 244 | 'ссс', 245 | 'ссср', 246 | 'сэс', 247 | 'т. б.', 248 | 'т. с. с.', 249 | 'т.', 250 | 'т.с.с', 251 | 'т', 252 | 'тв', 253 | 'тереңд.', 254 | 'тех.', 255 | 'тж', 256 | 'тжқ', 257 | 'тим', 258 | 'тмд', 259 | 'төм.', 260 | 'тр', 261 | 'трлн', 262 | 'тэц', 263 | 'уаз', 264 | 'уефа', 265 | 'ук', 266 | 'ұқк', 267 | 'ұқшұ', 268 | 'февр.', 269 | 'фкққ', 270 | 'фққ', 271 | 'фсб', 272 | 'хвқ', 273 | 'хдо', 274 | 'хдп', 275 | 'хим.', 276 | 'хқко', 277 | 'хтқо', 278 | 'цас', 279 | 'цтп', 280 | 'ш.', 281 | 'ш.б.', 282 | 'шұар', 283 | 'шыұ', 284 | 'экон.', 285 | 'экспо', 286 | 'эқк', 287 | 'эөкк', 288 | 'эыдұ', 289 | 'юнеско', 290 | 'янв.', 291 | 'А', 292 | 'М', 293 | 'Т' 294 | ]) 295 | 296 | export default class Kazakh extends BaseLanguage { 297 | static abbreviations = abbreviations 298 | 299 | continueInNextWord (textAfterBoundary) { 300 | return textAfterBoundary.match(/^\W*[0-9a-zа-я]/) 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /test/ru.test.js: -------------------------------------------------------------------------------- 1 | import segment from '../src/index.js' 2 | import assert from 'assert' 3 | 4 | const tests = { 5 | 'Объем составляет 5 куб.м.': ['Объем составляет 5 куб.м.'], 6 | 'Маленькая девочка бежала и кричала: «Не видали маму?».': ['Маленькая девочка бежала и кричала: «Не видали маму?».'], 7 | 'Сегодня 27.10.14': ['Сегодня 27.10.14'], 8 | 9 | '«Я приду поздно», — сказал Андрей.': ['«Я приду поздно», — сказал Андрей.'], 10 | 11 | '«К чему ты готовишься? – спросила мама. – Завтра ведь выходной».': 12 | ['«К чему ты готовишься? – спросила мама. – Завтра ведь выходной».'], 13 | 14 | 'По словам Пушкина, «Привычка свыше дана, замена счастью она».': 15 | ['По словам Пушкина, «Привычка свыше дана, замена счастью она».'], 16 | 17 | 'Он сказал: «Я очень устал», и сразу же замолчал.': 18 | ['Он сказал: «Я очень устал», и сразу же замолчал.'], 19 | 20 | 'Мне стало как-то ужасно грустно в это мгновение; однако что-то похожее на смех зашевелилось в душе моей.': 21 | [ 22 | 'Мне стало как-то ужасно грустно в это мгновение; однако что-то похожее на смех зашевелилось в душе моей.' 23 | ], 24 | 'Шухов как был в ватных брюках, не снятых на ночь повыше левого колена их тоже был пришит затасканный, погрязневший лоскут, и на нем выведен черной, уже поблекшей краской номер Щ-854, надел телогрейку…': 25 | [ 26 | 'Шухов как был в ватных брюках, не снятых на ночь повыше левого колена их тоже был пришит затасканный, погрязневший лоскут, и на нем выведен черной, уже поблекшей краской номер Щ-854, надел телогрейку…' 27 | ], 28 | 29 | 'Слово «дом» является синонимом жилища': ['Слово «дом» является синонимом жилища'], 30 | 'В Санкт-Петербург на гастроли приехал театр «Современник»': 31 | ['В Санкт-Петербург на гастроли приехал театр «Современник»'], 32 | 33 | 'Машина едет со скоростью 100 км/ч.': ['Машина едет со скоростью 100 км/ч.'], 34 | 'Я поем и/или лягу спать.': ['Я поем и/или лягу спать.'], 35 | 'Он не мог справиться с примером "3 + (14:7) = 5"': ['Он не мог справиться с примером "3 + (14:7) = 5"'], 36 | 'Вот список: 1.мороженое, 2.мясо, 3.рис.': ['Вот список: 1.мороженое, 2.мясо, 3.рис.'], 37 | 'Квартира 234 находится на 4-ом этаже.': ['Квартира 234 находится на 4-ом этаже.'], 38 | 'В это время года температура может подниматься до 40°C.': ['В это время года температура может подниматься до 40°C.'], 39 | 40 | 'Объем составляет 5м³.': ['Объем составляет 5м³.'], 41 | 42 | 'Площадь комнаты 14м².': ['Площадь комнаты 14м².'], 43 | 'Площадь комнаты 14 кв.м.': ['Площадь комнаты 14 кв.м.'], 44 | '1°C соответствует 33.8°F.': ['1°C соответствует 33.8°F.'], 45 | 46 | 'Сегодня 27 октября 2014 года.': ['Сегодня 27 октября 2014 года.'], 47 | 'Эта машина стоит 150 000 дол.!': ['Эта машина стоит 150 000 дол.!'], 48 | 'Эта машина стоит $150 000!': ['Эта машина стоит $150 000!'], 49 | 'Вот номер моего телефона: +39045969798. Передавайте привет г-ну Шапочкину. До свидания.': [ 50 | 'Вот номер моего телефона: +39045969798.', 51 | 'Передавайте привет г-ну Шапочкину.', 52 | 'До свидания.' 53 | ], 54 | 55 | 'Постойте, разве можно указывать цены в у.е.!': ['Постойте, разве можно указывать цены в у.е.!'], 56 | 57 | 'Едем на скорости 90 км/ч в сторону пгт. Брагиновка, о котором мы так много слышали по ТВ!': [ 58 | 'Едем на скорости 90 км/ч в сторону пгт. Брагиновка, о котором мы так много слышали по ТВ!' 59 | ], 60 | 61 | 'Д-р ветеринарных наук А. И. Семенов и пр. выступали на этом семинаре.': 62 | ['Д-р ветеринарных наук А. И. Семенов и пр. выступали на этом семинаре.'], 63 | 64 | 'Уважаемый проф. Семенов! Просьба до 20.10 сдать отчет на кафедру.': 65 | ['Уважаемый проф. Семенов!', 'Просьба до 20.10 сдать отчет на кафедру.'], 66 | 67 | 'Первоначальная стоимость этого комплекта 30 долл., но сейчас действует скидка. Предъявите дисконтную карту, пожалуйста!': 68 | [ 69 | 'Первоначальная стоимость этого комплекта 30 долл., но сейчас действует скидка.', 70 | 'Предъявите дисконтную карту, пожалуйста!' 71 | ], 72 | 'Виктор съел пол-лимона и ушел по-английски из дома на ул. 1 Мая.': ['Виктор съел пол-лимона и ушел по-английски из дома на ул. 1 Мая.'], 73 | 'Напоминаю Вам, что 25.10 день рождения у Маши К., нужно будет купить ей подарок.': ['Напоминаю Вам, что 25.10 день рождения у Маши К., нужно будет купить ей подарок.'], 74 | 75 | 'В 2010-2012 гг. Виктор посещал г. Волгоград неоднократно.': ['В 2010-2012 гг. Виктор посещал г. Волгоград неоднократно.'], 76 | 77 | 'Маленькая девочка бежала и кричала: «Не видали маму?»': ['Маленькая девочка бежала и кричала: «Не видали маму?»'], 78 | 79 | 'Кв. 234 находится на 4 этаже.': ['Кв. 234 находится на 4 этаже.'], 80 | 81 | 'Нужно купить 1)рыбу 2)соль.': ['Нужно купить 1)рыбу 2)соль.'], 82 | 83 | 'Л.Н. Толстой написал "Войну и мир". Кроме Волконских, Л. Н. Толстой состоял в близком родстве с некоторыми другими аристократическими родами. Дом, где родился Л.Н.Толстой, 1898 г. В 1854 году дом продан по распоряжению писателя на вывоз в село Долгое.': [ 84 | 'Л.Н. Толстой написал "Войну и мир".', 85 | 'Кроме Волконских, Л. Н. Толстой состоял в близком родстве с некоторыми другими аристократическими родами.', 86 | 'Дом, где родился Л.Н.Толстой, 1898 г. В 1854 году дом продан по распоряжению писателя на вывоз в село Долгое.' 87 | ] 88 | 89 | } 90 | 91 | describe('Russian segment()', function () { 92 | for (const [text, expectedSentences] of Object.entries(tests)) { 93 | it(`correctly segments text: ${text}`, function () { 94 | const sentences = segment('ru', text) 95 | assert.deepEqual(sentences, expectedSentences) 96 | }) 97 | } 98 | }) 99 | -------------------------------------------------------------------------------- /src/fallbacks.json: -------------------------------------------------------------------------------- 1 | { 2 | "ab": ["ru"], 3 | "abs": ["id"], 4 | "ace": ["id"], 5 | "ady": ["ady-cyrl"], 6 | "aeb": ["aeb-arab"], 7 | "aeb-arab": ["ar"], 8 | "aln": ["sq"], 9 | "alt": ["ru"], 10 | "ami": ["zh-hant"], 11 | "an": ["es"], 12 | "anp": ["hi"], 13 | "arn": ["es"], 14 | "arq": ["ar"], 15 | "ary": ["ar"], 16 | "arz": ["ar"], 17 | "ast": ["es"], 18 | "atj": ["fr"], 19 | "av": ["ru"], 20 | "avk": ["fr", "es", "ru"], 21 | "awa": ["hi"], 22 | "ay": ["es"], 23 | "azb": ["fa"], 24 | "ba": ["ru"], 25 | "ban": ["id"], 26 | "ban-bali": ["ban"], 27 | "bar": ["de"], 28 | "bbc": ["bbc-latn"], 29 | "bbc-latn": ["id"], 30 | "bcc": ["fa"], 31 | "be-tarask": ["be"], 32 | "bgn": ["fa"], 33 | "bh": ["bho"], 34 | "bi": ["en"], 35 | "bjn": ["id"], 36 | "bm": ["fr"], 37 | "bpy": ["bn"], 38 | "bqi": ["fa"], 39 | "br": ["fr"], 40 | "btm": ["id"], 41 | "bug": ["id"], 42 | "bxr": ["ru"], 43 | "ca": ["oc"], 44 | "cbk-zam": ["es"], 45 | "cdo": ["nan", "zh-hant"], 46 | "ce": ["ru"], 47 | "co": ["it"], 48 | "crh": ["crh-latn"], 49 | "crh-cyrl": ["ru"], 50 | "cs": ["sk"], 51 | "csb": ["pl"], 52 | "cv": ["ru"], 53 | "de-at": ["de"], 54 | "de-ch": ["de"], 55 | "de-formal": ["de"], 56 | "dsb": ["de"], 57 | "dtp": ["ms"], 58 | "dty": ["ne"], 59 | "egl": ["it"], 60 | "eml": ["it"], 61 | "en-ca": ["en"], 62 | "en-gb": ["en"], 63 | "es-419": ["es"], 64 | "es-formal": ["es"], 65 | "ext": ["es"], 66 | "ff": ["fr"], 67 | "fit": ["fi"], 68 | "frc": ["fr"], 69 | "frp": ["fr"], 70 | "frr": ["de"], 71 | "fur": ["it"], 72 | "gag": ["tr"], 73 | "gan": ["gan-hant", "zh-hant", "zh-hans"], 74 | "gan-hans": ["zh-hans"], 75 | "gan-hant": ["zh-hant", "zh-hans"], 76 | "gcr": ["fr"], 77 | "gl": ["pt"], 78 | "glk": ["fa"], 79 | "gn": ["es"], 80 | "gom": ["gom-deva"], 81 | "gom-deva": ["hi"], 82 | "gor": ["id"], 83 | "gsw": ["de"], 84 | "guc": ["es"], 85 | "hak": ["zh-hant"], 86 | "hif": ["hif-latn"], 87 | "hrx": ["de"], 88 | "hsb": ["dsb", "de"], 89 | "ht": ["fr"], 90 | "hu-formal": ["hu"], 91 | "hyw": ["hy"], 92 | "ii": ["zh-cn", "zh-hans"], 93 | "inh": ["ru"], 94 | "io": ["eo"], 95 | "iu": ["ike-cans"], 96 | "jam": ["en"], 97 | "jut": ["da"], 98 | "jv": ["id"], 99 | "kaa": ["kk-latn", "kk-cyrl"], 100 | "kab": ["fr"], 101 | "kbd": ["kbd-cyrl"], 102 | "kbp": ["fr"], 103 | "khw": ["ur"], 104 | "kiu": ["tr"], 105 | "kjp": ["my"], 106 | "kk": ["kk-cyrl"], 107 | "kk-arab": ["kk-cyrl"], 108 | "kk-cn": ["kk-arab", "kk-cyrl"], 109 | "kk-kz": ["kk-cyrl"], 110 | "kk-latn": ["kk-cyrl"], 111 | "kk-tr": ["kk-latn", "kk-cyrl"], 112 | "kl": ["da"], 113 | "ko-kp": ["ko"], 114 | "koi": ["ru"], 115 | "krc": ["ru"], 116 | "krl": ["fi"], 117 | "ks": ["ks-arab"], 118 | "ksh": ["de"], 119 | "ku": ["ku-latn"], 120 | "ku-arab": ["ckb"], 121 | "kum": ["ru"], 122 | "kv": ["ru"], 123 | "lad": ["es"], 124 | "lb": ["de"], 125 | "lbe": ["ru"], 126 | "lez": ["ru", "az"], 127 | "li": ["nl"], 128 | "lij": ["it"], 129 | "liv": ["et"], 130 | "lki": ["fa"], 131 | "lld": ["it", "rm", "fur"], 132 | "lmo": ["pms", "eml", "lij", "vec", "it"], 133 | "ln": ["fr"], 134 | "lrc": ["fa"], 135 | "ltg": ["lv"], 136 | "luz": ["fa"], 137 | "lzh": ["zh-hant"], 138 | "lzz": ["tr"], 139 | "mad": ["id"], 140 | "mai": ["hi"], 141 | "map-bms": ["jv", "id"], 142 | "mdf": ["ru"], 143 | "mg": ["fr"], 144 | "mhr": ["ru"], 145 | "min": ["id"], 146 | "mnw": ["my"], 147 | "mo": ["ro"], 148 | "mrj": ["ru"], 149 | "ms-arab": ["ms"], 150 | "mwl": ["pt"], 151 | "myv": ["ru"], 152 | "mzn": ["fa"], 153 | "nah": ["es"], 154 | "nan": ["cdo", "zh-hant"], 155 | "nap": ["it"], 156 | "nds": ["de"], 157 | "nds-nl": ["nl"], 158 | "nia": ["id"], 159 | "nl-informal": ["nl"], 160 | "nn": ["nb"], 161 | "nrm": ["fr"], 162 | "oc": ["ca", "fr"], 163 | "olo": ["fi"], 164 | "os": ["ru"], 165 | "pcd": ["fr"], 166 | "pdc": ["de"], 167 | "pdt": ["de"], 168 | "pfl": ["de"], 169 | "pih": ["en"], 170 | "pms": ["it"], 171 | "pnt": ["el"], 172 | "pt": ["pt-br"], 173 | "pt-br": ["pt"], 174 | "qu": ["es"], 175 | "qug": ["es"], 176 | "rgn": ["it"], 177 | "rmy": ["ro"], 178 | "roa-tara": ["it"], 179 | "rue": ["uk", "ru"], 180 | "rup": ["ro"], 181 | "ruq": ["ruq-latn", "ro"], 182 | "ruq-cyrl": ["mk"], 183 | "ruq-latn": ["ro"], 184 | "sa": ["hi"], 185 | "sah": ["ru"], 186 | "scn": ["it"], 187 | "sco": ["en"], 188 | "sdc": ["it"], 189 | "sdh": ["cbk", "fa"], 190 | "ses": ["fr"], 191 | "sg": ["fr"], 192 | "sgs": ["lt"], 193 | "sh": ["bs", "sr-el", "hr"], 194 | "shi": ["fr"], 195 | "shy": ["shy-latn"], 196 | "shy-latn": ["fr"], 197 | "sk": ["cs"], 198 | "skr": ["skr-arab"], 199 | "skr-arab": ["ur", "pnb"], 200 | "sli": ["de"], 201 | "smn": ["fi"], 202 | "sr": ["sr-ec"], 203 | "srn": ["nl"], 204 | "stq": ["de"], 205 | "sty": ["ru"], 206 | "su": ["id"], 207 | "szl": ["pl"], 208 | "szy": ["zh-tw", "zh-hant", "zh-hans"], 209 | "tay": ["zh-tw", "zh-hant", "zh-hans"], 210 | "tcy": ["kn"], 211 | "tet": ["pt"], 212 | "tg": ["tg-cyrl"], 213 | "trv": ["zh-tw", "zh-hant", "zh-hans"], 214 | "tt": ["tt-cyrl", "ru"], 215 | "tt-cyrl": ["ru"], 216 | "ty": ["fr"], 217 | "tyv": ["ru"], 218 | "udm": ["ru"], 219 | "ug": ["ug-arab"], 220 | "vec": ["it"], 221 | "vep": ["et"], 222 | "vls": ["nl"], 223 | "vmf": ["de"], 224 | "vot": ["fi"], 225 | "vro": ["et"], 226 | "wa": ["fr"], 227 | "wo": ["fr"], 228 | "wuu": ["zh-hans"], 229 | "xal": ["ru"], 230 | "xmf": ["ka"], 231 | "yi": ["he"], 232 | "za": ["zh-hans"], 233 | "zea": ["nl"], 234 | "zgh": ["kab"], 235 | "zh": ["zh-hans"], 236 | "zh-cn": ["zh-hans"], 237 | "zh-hant": ["zh-hans"], 238 | "zh-hk": ["zh-hant", "zh-hans"], 239 | "zh-mo": ["zh-hk", "zh-hant", "zh-hans"], 240 | "zh-my": ["zh-sg", "zh-hans"], 241 | "zh-sg": ["zh-hans"], 242 | "zh-tw": ["zh-hant", "zh-hans"] 243 | } 244 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |