From a4044dc16c1b0830e939c8b172d54dbb1f02430a Mon Sep 17 00:00:00 2001 From: gwn Date: Sun, 21 Apr 2019 23:35:31 +0300 Subject: [PATCH] Implement a text mode for non-wordlist text files Users can now supply any kind of plain text file to type its contents exactly; as opposed to the shuffled word approach of the wordlist mode. One gotcha is that since the typing stage is of width 80, the user-supplied text file should be word wrapped to 80 columns or it will break the layout. --- app.js | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) mode change 100644 => 100755 app.js diff --git a/app.js b/app.js old mode 100644 new mode 100755 index d5a7296..d57b1e8 --- a/app.js +++ b/app.js @@ -11,7 +11,8 @@ if (flagExists('h', 'help')) { console.log('\nOptions:'); console.log(' -t, --time\t\tGiven time in seconds to complete the test'); console.log(' -w, --words\t\tNumber of words to display per line'); - console.log(' -i, --input\t\tPath to a wordlist file with new line separated words'); + console.log(' -i, --input\t\tPath to a wordlist file with new line separated words, or a plain text file.'); + console.log(' -m, --input-mode\t\tEither "wordlist" (default) or "text".'); console.log(' -V, --verbose\t\tShow settings on start'); console.log(' -s, --save\t\tPath to file for saving results'); console.log(' -h, --help\t\tShow help'); @@ -36,7 +37,7 @@ const SPECIAL = { const ALPHANUMERIC = /[\u0000-\u007F\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u0370-\u03FF\u0400-\u04FF\u0500-\u052F]/u; const ANSI_ESCAPE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g; -const lineGen = lineGenerator(CONFIG.inputFile, CONFIG.wordsPerLine); +const lineGen = lineGenerator(CONFIG.inputFile, CONFIG.inputMode, CONFIG.wordsPerLine); let text, nextText, cursor; @@ -136,6 +137,7 @@ function initConfig() { wordsPerLine: argvParser(['-w', '--words'], 9, validateIntArg), givenSeconds: argvParser(['-t', '--time'], 60, validateIntArg), inputFile: argvParser(['-i', '--input'], __dirname + '/data/mostCommon1000.txt'), + inputMode: argvParser(['-m', '--input-mode'], 'wordlist'), verbose: flagExists('V', 'verbose'), debug: flagExists('d', 'debug'), savePath: argvParser(['-s', '--save'], false) @@ -210,14 +212,30 @@ function shuffle(obj) { return sample.slice(); } -function *lineGenerator(path, numberOfWords) { - const words = fs.readFileSync(path, 'utf8').split('\n'); +function *lineGenerator(path, mode, numberOfWords) { + const lines = fs.readFileSync(path, 'utf8').split('\n'); + + yield* ( + mode === 'wordlist' + ? wlistLineGenerator(lines, numberOfWords) + : textLineGenerator(lines) + ); +} + +function *wlistLineGenerator(words, numberOfWords) { const shuffledWords = shuffle(words); + for (let i = 0; i+numberOfWords < shuffledWords.length-1; i += numberOfWords) { yield shuffledWords.slice(i, i + numberOfWords).join(' '); } } +function *textLineGenerator(lines) { + for (let i = 0, len = lines.length; i < len; ++i) { + yield lines[i]; + } +} + // TODO tidy up function saveStats(stats, config) { const date = new Date(startTime).toLocaleString();