UNPKG

lesetid

Version:

A dead simple read time estimation

96 lines (94 loc) 2.66 kB
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; } });