lesetid
Version:
A dead simple read time estimation
96 lines (94 loc) • 2.66 kB
JavaScript
const require_utils = require('./utils-TNF-mJTC.cjs');
//#region src/index.ts
const DEFAULT_OPTIONS = {
wordsPerMinute: 200,
charsPerMinute: 500,
isWord: require_utils.isAnsi
};
/**
* Counts the number of words and characters in the given text.
*
* @param {string?} text - the text to count words and characters in.
* @param {Options} [options] - the options to use.
* @returns {CountResult} the result of words and characters.
*/
function count(text, options = DEFAULT_OPTIONS) {
if (!text) return {
words: 0,
chars: 0
};
let words = 0;
let chars = 0;
let start = 0;
let end = text.length - 1;
while (!isPunctuationOrWord(text[start], options.isWord || require_utils.isAnsi)) start++;
while (!isPunctuationOrWord(text[end], options.isWord || require_utils.isAnsi)) end--;
const normalizedText = `${text}\n`;
for (let i = start; i <= end; i++) {
const char = normalizedText[i];
let nextChar = normalizedText[i + 1];
if (require_utils.isCJK(char)) {
chars++;
while (i <= end && !isPunctuationOrWord(nextChar, options.isWord || require_utils.isAnsi)) {
i++;
nextChar = normalizedText[i + 1];
}
} else if (isPunctuationOrWord(char, options.isWord || require_utils.isAnsi) && (!isPunctuationOrWord(nextChar, options.isWord || require_utils.isAnsi) || require_utils.isCJK(nextChar))) words++;
}
return {
words,
chars
};
}
function isPunctuationOrWord(char = "", isWordFn) {
return !char || !(require_utils.isPunctuation(char) || isWordFn(char));
}
/**
* Estimate a text's reading time.
*
* @param {string} text - the text to estimate.
* @param {Options} [options] - the options to use.
* @returns {Estimation} the estimation result.
*/
function estimate(text, options = DEFAULT_OPTIONS) {
if (!text) return {
minutes: 0,
time: 0,
words: 0,
chars: 0,
text: "0 min read"
};
const { words, chars } = count(text);
const { wordsPerMinute = 200, charsPerMinute = 500 } = options;
const charMinutes = chars / charsPerMinute;
const wordMinutes = words / wordsPerMinute;
const totalMinutes = charMinutes + wordMinutes;
const time = Math.round(totalMinutes * 60 * 1e3);
const displayed = Math.ceil(Number.parseFloat(totalMinutes.toFixed(2)));
return {
minutes: displayed,
time,
words,
chars,
text: `${displayed} min read`
};
}
//#endregion
Object.defineProperty(exports, 'DEFAULT_OPTIONS', {
enumerable: true,
get: function () {
return DEFAULT_OPTIONS;
}
});
Object.defineProperty(exports, 'count', {
enumerable: true,
get: function () {
return count;
}
});
Object.defineProperty(exports, 'estimate', {
enumerable: true,
get: function () {
return estimate;
}
});