mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-09-13 19:52:20 +02:00
56 lines
1.7 KiB
JavaScript
56 lines
1.7 KiB
JavaScript
// Unicode-aware text statistics shared by source and rich-text documents.
|
||
|
||
let _wordSegmenter;
|
||
let _graphemeSegmenter;
|
||
|
||
function _segmenter(granularity) {
|
||
if (typeof Intl === 'undefined' || typeof Intl.Segmenter !== 'function') return null;
|
||
try {
|
||
if (granularity === 'word') {
|
||
_wordSegmenter ||= new Intl.Segmenter(undefined, { granularity: 'word' });
|
||
return _wordSegmenter;
|
||
}
|
||
_graphemeSegmenter ||= new Intl.Segmenter(undefined, { granularity: 'grapheme' });
|
||
return _graphemeSegmenter;
|
||
} catch (_) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
export function countDocumentWords(value) {
|
||
const text = String(value ?? '');
|
||
if (!text.trim()) return 0;
|
||
const segmenter = _segmenter('word');
|
||
if (segmenter) {
|
||
let count = 0;
|
||
for (const segment of segmenter.segment(text)) {
|
||
if (segment.isWordLike) count += 1;
|
||
}
|
||
return count;
|
||
}
|
||
return (text.match(/[\p{L}\p{N}\p{M}]+(?:['’][\p{L}\p{N}\p{M}]+)*/gu) || []).length;
|
||
}
|
||
|
||
export function countDocumentCharacters(value) {
|
||
const text = String(value ?? '');
|
||
const segmenter = _segmenter('grapheme');
|
||
if (segmenter) return Array.from(segmenter.segment(text)).length;
|
||
return Array.from(text).length;
|
||
}
|
||
|
||
export function getDocumentStats(value) {
|
||
const text = String(value ?? '').replace(/\r\n?/g, '\n');
|
||
const words = countDocumentWords(text);
|
||
const characters = countDocumentCharacters(text);
|
||
const charactersNoSpaces = countDocumentCharacters(text.replace(/\s/gu, ''));
|
||
const lineText = text.replace(/\n+$/u, '');
|
||
const lines = lineText ? lineText.split('\n').length : 0;
|
||
return {
|
||
words,
|
||
characters,
|
||
charactersNoSpaces,
|
||
lines,
|
||
readingMinutes: words ? Math.max(1, Math.ceil(words / 225)) : 0,
|
||
};
|
||
}
|