Comparing version 6.0.4 to 6.1.0
# Changelog | ||
## v6.1.0 | ||
- Fix lost symlink #145, #128. | ||
- Print row:col for repeated words #142, #134. | ||
- Fix repeated words with code for markdown files #141, #134. | ||
## v6.0.4 | ||
@@ -4,0 +9,0 @@ - Fix: print a typo warning at the end if there are typos #121. |
'use strict'; | ||
const chalk = require('chalk'); | ||
const debug = require('./debug'); | ||
const { ERROR_TOO_MANY_ERRORS } = require('yandex-speller'); | ||
const exitCodes = require('./exit-codes'); | ||
const utils = require('./utils'); | ||
const printDebug = debug.print; | ||
const { replaceRusLettersWithAsterisk } = require('./helpers/string'); | ||
const { hasEngRusLetters, replaceEngLettersWithAsterisk } = require('./helpers/string'); | ||
const { loadFileAsJson } = require('./helpers/file'); | ||
const { uniq } = require('./helpers/array'); | ||
const { consoleError, consoleWarn, consoleLog, consoleDebug } = require('./helpers/console'); | ||
const letters = '[a-zа-яё\\d-]'; | ||
@@ -30,3 +35,3 @@ const reNotOptimized = new RegExp('(^|' + letters + ')' + | ||
commonUniqueWords = commonUniqueWords.concat(utils.uniq(words)); | ||
commonUniqueWords = commonUniqueWords.concat(uniq(words)); | ||
@@ -68,10 +73,10 @@ count++; | ||
printDebug('Get/check dictionary: ' + file); | ||
consoleDebug('Get/check dictionary: ' + file); | ||
try { | ||
data = utils.loadFileAsJson(file, true); | ||
data = loadFileAsJson(file, true); | ||
printDebug('Use dictionary: ' + file); | ||
consoleDebug('Use dictionary: ' + file); | ||
} catch (e) { | ||
console.error(chalk.red(e)); | ||
consoleError(e); | ||
process.exit(exitCodes.ERROR_DICTIONARY); | ||
@@ -92,3 +97,3 @@ } | ||
if (duplicates.length) { | ||
console.log(chalk.cyan(title + '\n' + duplicates.join('\n') + '\n')); | ||
consoleWarn(title + '\n' + duplicates.join('\n') + '\n'); | ||
@@ -110,3 +115,3 @@ return true; | ||
words.forEach(function(word) { | ||
if (utils.hasEnRu(word)) { | ||
if (hasEngRusLetters(word)) { | ||
typos.push(word); | ||
@@ -118,8 +123,10 @@ } | ||
if (hasTypos) { | ||
console.log(chalk.cyan('Has typos in "' + file + '":')); | ||
typos.forEach(function(typo) { | ||
console.log(chalk.cyan(typo + ' - en: ' + utils.replaceRu(typo) + | ||
', ru: ' + utils.replaceEn(typo))); | ||
consoleWarn('Has typos in "' + file + '":'); | ||
typos.forEach(item => { | ||
consoleWarn(item + | ||
' - en: ' + replaceRusLettersWithAsterisk(item) + | ||
', ru: ' + replaceEngLettersWithAsterisk(item) | ||
); | ||
}); | ||
console.log(''); | ||
consoleLog(''); | ||
} | ||
@@ -140,4 +147,3 @@ | ||
data.forEach(function(typo) { | ||
// ERROR_TOO_MANY_ERRORS = 4 | ||
if (typo.code === 4 || this.isTypo(typo.word, dictionary)) { | ||
if (typo.code === ERROR_TOO_MANY_ERRORS || this.isTypo(typo.word, dictionary)) { | ||
result.push(typo); | ||
@@ -171,3 +177,3 @@ } | ||
if (this.isNotOptimizedRegExp(word)) { | ||
console.log(chalk.cyan('Not optimized dictionary RegExp in "' + word + '"')); | ||
consoleWarn(`Not optimized dictionary RegExp in "${word}"`); | ||
} | ||
@@ -191,3 +197,3 @@ | ||
} catch (e) { | ||
console.error(chalk.red('Incorrect dictionary RegExp in "' + word + '", ' + e)); | ||
consoleError(`Incorrect dictionary RegExp in "${word}", ${e}`); | ||
} | ||
@@ -236,29 +242,2 @@ }, this); | ||
}, | ||
/** | ||
* Is a letter? | ||
* | ||
* @param {string} symbol | ||
* @returns {boolean} | ||
*/ | ||
isLetter(symbol) { | ||
return symbol.toLowerCase() !== symbol.toUpperCase(); | ||
}, | ||
/** | ||
* Is a letter in upper case? | ||
* | ||
* @param {string} letter | ||
* @returns {boolean} | ||
*/ | ||
isUpperCase(letter) { | ||
return letter === letter.toUpperCase(); | ||
}, | ||
/** | ||
* Is a letter in lower case? | ||
* | ||
* @param {string} letter | ||
* @returns {boolean} | ||
*/ | ||
isLowerCase(letter) { | ||
return letter === letter.toLowerCase(); | ||
} | ||
}; |
'use strict'; | ||
const program = require('commander'); | ||
const utils = require('./utils'); | ||
function splitTrim(value, separator) { | ||
return value.split(separator).map(el => el.trim()); | ||
} | ||
const { kebabCase, splitTrim, splitByCommas } = require('./helpers/string'); | ||
const { packageJson } = require('./helpers/package'); | ||
function splitByCommas(value) { | ||
return splitTrim(value, ','); | ||
} | ||
module.exports = { | ||
init(params) { | ||
program | ||
.version(require('../package.json').version) | ||
.version(packageJson.version) | ||
.usage('[options] <file-or-directory-or-link...>') | ||
@@ -39,3 +33,3 @@ .option('-l, --lang <value>', 'languages: en, ru or uk. Default: "en,ru"') | ||
this.apiOptions.forEach(function(el) { | ||
program.option('--' + utils.kebabCase(el[0]), el[1]); | ||
program.option('--' + kebabCase(el[0]), el[1]); | ||
}); | ||
@@ -42,0 +36,0 @@ }, |
@@ -6,8 +6,10 @@ 'use strict'; | ||
const pth = require('path'); | ||
const glob = require('glob'); | ||
const dict = require('./dictionary'); | ||
const exitCodes = require('./exit-codes'); | ||
const report = require('./report'); | ||
const utils = require('./utils'); | ||
const reports = require('./reports'); | ||
const yaspeller = require('./yaspeller'); | ||
const glob = require('glob'); | ||
const { findFiles, isDirectory, isExcludedFile } = require('./helpers/file'); | ||
const { isUrl, isSitemap } = require('./helpers/url'); | ||
@@ -36,3 +38,3 @@ function hasData(err, data) { | ||
report.oneach(err, data); | ||
reports.oneach(err, data); | ||
} | ||
@@ -51,3 +53,3 @@ | ||
for (const value of args) { | ||
if (utils.isUrl(value)) { | ||
if (isUrl(value)) { | ||
result.push(value); | ||
@@ -73,3 +75,3 @@ } else { | ||
return this.expandGlobArgs(resources).map(resource => callback => { | ||
if (utils.isUrl(resource)) { | ||
if (isUrl(resource)) { | ||
this.forUrl(resource, settings, callback); | ||
@@ -130,5 +132,4 @@ } else { | ||
forFiles(resource, settings, callback) { | ||
if (utils.isDir(resource)) { | ||
const tasks = utils | ||
.findFiles(resource, settings.fileExtensions, settings.excludeFiles) | ||
if (isDirectory(resource)) { | ||
const tasks = findFiles(resource, settings.fileExtensions, settings.excludeFiles) | ||
.map(file => cb => yaspeller.checkFile(file, (err, data, originalText) => { | ||
@@ -142,3 +143,3 @@ onResource(err, data, originalText); | ||
const file = pth.resolve(resource); | ||
if (utils.isExcludedFile(file, settings.excludeFiles)) { | ||
if (isExcludedFile(file, settings.excludeFiles)) { | ||
callback(); | ||
@@ -161,3 +162,3 @@ } else { | ||
forUrl(resource, settings, callback) { | ||
if (utils.isSitemap(resource)) { | ||
if (isSitemap(resource)) { | ||
yaspeller.checkSitemap(resource, callback, settings, onResource); | ||
@@ -164,0 +165,0 @@ } else { |
@@ -6,15 +6,23 @@ 'use strict'; | ||
const fs = require('fs'); | ||
const eyo = require('./eyo'); | ||
const formatModule = require('./format'); | ||
const ignore = require('./ignore'); | ||
const isutf8 = require('isutf8'); | ||
const fetch = require('node-fetch'); | ||
const pth = require('path'); | ||
const MarkdownIt = require('markdown-it'); | ||
const xml2js = require('xml2js'); | ||
const yaspellerApi = require('yandex-speller'); | ||
const MarkdownIt = require('markdown-it'); | ||
const md = new MarkdownIt(); | ||
const printDebug = require('../lib/debug').print; | ||
const eyo = require('./plugins/eyo'); | ||
const { getFormat, getApiFormat } = require('./helpers/format'); | ||
const { | ||
hasIgnoredText, | ||
ignoreComments, | ||
ignoreBlocks, | ||
ignoreTags, | ||
ignoreLines, | ||
} = require('./helpers/ignore'); | ||
const { consoleDebug } = require('../lib/helpers/console'); | ||
const { jsonStringify, stripTags } = require('./helpers/string'); | ||
const MAX_LEN_TEXT = 10000; // Max length of text for Yandex.Speller API | ||
const TOO_MANY_ERRORS = 4; | ||
@@ -25,6 +33,2 @@ function getMaxRequest(settings) { | ||
function stripTags(html) { | ||
return html.replace(/<\/?[a-z][^>]*>/gi, ' '); | ||
} | ||
/** | ||
@@ -45,4 +49,6 @@ * Check text for typos. | ||
consoleDebug(`Original text: ${originalText}`); | ||
const apiSettings = Object.assign({}, settings); | ||
const format = formatModule.getFormat(text, apiSettings); | ||
const format = getFormat(text, apiSettings); | ||
const lang = apiSettings.lang || 'en,ru'; | ||
@@ -56,5 +62,5 @@ | ||
if (ignore.hasIgnoredText(text)) { | ||
text = ignore.lines(text); | ||
text = ignore.blocks(text); | ||
if (hasIgnoredText(text)) { | ||
text = ignoreLines(text); | ||
text = ignoreBlocks(text); | ||
} | ||
@@ -68,6 +74,6 @@ | ||
if (apiSettings.ignoreTags) { | ||
text = ignore.tags(text, apiSettings.ignoreTags); | ||
text = ignoreTags(text, apiSettings.ignoreTags); | ||
} | ||
text = ignore.comments(text); | ||
text = ignoreComments(text); | ||
text = stripTags(text); | ||
@@ -78,2 +84,3 @@ text = entities.decodeHTML(text); | ||
text = prepareText(text, format); | ||
consoleDebug(`Prepared text for API: ${text}`); | ||
@@ -83,6 +90,6 @@ const tasks = []; | ||
apiSettings.format = formatModule.getApiFormat(format); | ||
apiSettings.format = getApiFormat(format); | ||
texts.forEach(function(el, i) { | ||
printDebug({ | ||
consoleDebug({ | ||
request: i, | ||
@@ -93,3 +100,3 @@ format: format, | ||
options: apiSettings.options, | ||
text: el.substring(0, 128) | ||
text: el.substring(0, 128), | ||
}); | ||
@@ -111,2 +118,5 @@ | ||
consoleDebug('Yandex.Speller API response:'); | ||
consoleDebug(jsonStringify(buf)); | ||
if (!buf.err && apiSettings.checkYo) { | ||
@@ -201,3 +211,3 @@ checkYo(text, buf.data); | ||
printDebug('get: ' + file); | ||
consoleDebug('Get file: ' + file); | ||
@@ -208,3 +218,3 @@ if (fs.existsSync(file)) { | ||
if (isutf8(buf)) { | ||
printDebug('post text -> Yandex.Speller API: ' + file); | ||
consoleDebug('Post text → Yandex.Speller API: ' + file); | ||
@@ -241,3 +251,3 @@ const startTime = Date.now(); | ||
printDebug('get: ' + url); | ||
consoleDebug('Get url: ' + url); | ||
@@ -280,3 +290,3 @@ fetch(url) | ||
printDebug('get: ' + url); | ||
consoleDebug('Get sitemap: ' + url); | ||
@@ -337,3 +347,3 @@ fetch(url) | ||
data.forEach(function(item) { | ||
if (item.code === TOO_MANY_ERRORS || item.position) { | ||
if (item.code === yaspellerApi.ERROR_TOO_MANY_ERRORS || item.position) { | ||
return; | ||
@@ -344,4 +354,9 @@ } | ||
const letters = '[^a-zA-Zа-яА-ЯЁёҐґЄєІіЇї]'; | ||
let word = item.word; | ||
text.replace(new RegExp(item.word + '(?:' + letters + '|$)', 'g'), function($0, index) { | ||
if (item.code === yaspellerApi.ERROR_REPEATED_WORD) { | ||
word = item.word + '\\s+' + item.word; | ||
} | ||
text.replace(new RegExp(word + '(?:' + letters + '|$)', 'mg'), function($0, index) { | ||
const prevSymbol = text[index - 1]; | ||
@@ -485,11 +500,11 @@ if (prevSymbol && prevSymbol.search(letters) === -1) { | ||
return text.trim(); | ||
return text; | ||
} | ||
function fixLineEndings(text) { | ||
return text.replace(/\r\n/g, '\n') // Fix Windows | ||
return text | ||
.replace(/\r\n/g, '\n') // Fix Windows | ||
.replace(/\r/g, '\n') // Fix MacOS | ||
.replace(/\s+\n/g, '\n') // Trailling spaces | ||
.replace(/\s+/g, ' ') // Repeat spaces | ||
.replace(/\n+/g, '\n'); // Repeat line endings | ||
.trimRight(); | ||
} | ||
@@ -508,13 +523,11 @@ | ||
function getErrors() { | ||
return yaspellerApi.errorCodes.filter(function(el) { | ||
return el.code !== TOO_MANY_ERRORS; | ||
}).map(function(el) { | ||
return { | ||
return yaspellerApi.errors | ||
.filter(el => el.code !== yaspellerApi.ERROR_TOO_MANY_ERRORS) | ||
.map(el => ({ | ||
code: el.code, | ||
title: el.text | ||
}; | ||
}).concat({ | ||
code: 100, // ERROR_EYO | ||
title: 'Letter Ё (Yo)' | ||
}); | ||
})).concat({ | ||
code: 100, // ERROR_EYO | ||
title: 'Letter Ё (Yo)' | ||
}); | ||
} | ||
@@ -521,0 +534,0 @@ |
@@ -13,3 +13,3 @@ { | ||
"description": "Search tool typos in the text, files and websites", | ||
"version": "6.0.4", | ||
"version": "6.1.0", | ||
"license": "MIT", | ||
@@ -50,3 +50,3 @@ "homepage": "https://github.com/hcodes/yaspeller", | ||
"xml2js": "^0.4.23", | ||
"yandex-speller": "^4.0.0" | ||
"yandex-speller": "^4.1.0" | ||
}, | ||
@@ -53,0 +53,0 @@ "devDependencies": { |
@@ -41,3 +41,3 @@ yaspeller | ||
+ `yaspeller "*.md"` — node glob syntax for Windows. | ||
+ `yaspeller -e ".md,.html,.js" ./texts/` — finding typos in files in the folder. | ||
+ `yaspeller -e ".md,.html,.txt" ./texts/` — finding typos in files in the folder. | ||
+ `yaspeller https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D0%B5%D1%87%D0%B0%D1%82%D0%BA%D0%B0` — search typos in the page. | ||
@@ -178,3 +178,2 @@ + `yaspeller http://bem.info/sitemap.xml` — search typos at the addresses specified in the sitemap.xml. | ||
".md", | ||
".js", | ||
".css" | ||
@@ -201,3 +200,2 @@ ], | ||
".md", | ||
".js", | ||
".css" | ||
@@ -204,0 +202,0 @@ ], |
@@ -23,5 +23,16 @@ yaspeller | ||
## Используйте с [pre-commit](https://pre-commit.com/) | ||
Добавте в ваш `.pre-commit-config.yaml`: | ||
```yaml | ||
- repo: https://github.com/hcodes/yaspeller.git | ||
rev: '' # Use the sha / tag you want to point at | ||
hooks: | ||
- id: yaspeller | ||
``` | ||
### Примеры | ||
+ `yaspeller README.md` — поиск опечаток в файле. | ||
+ `yaspeller -e ".md,.html,.js" ./texts/` — поиск опечаток в файлах в папке. | ||
+ `yaspeller -e ".md,.html" ./texts/` — поиск опечаток в файлах в папке. | ||
+ `yaspeller https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D0%B5%D1%87%D0%B0%D1%82%D0%BA%D0%B0` — поиск опечаток на странице сайта. | ||
@@ -158,4 +169,3 @@ + `yaspeller http://bem.info/sitemap.xml` — поиск опечаток в адресах, перечисленных в sitemap.xml. | ||
".md", | ||
".js", | ||
".css" | ||
".txt" | ||
], | ||
@@ -181,4 +191,3 @@ "dictionary": [ | ||
".md", | ||
".js", | ||
".css" | ||
".txt" | ||
], | ||
@@ -185,0 +194,0 @@ "report": ["console", "html"], |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
90688
39
2168
306
3
Updatedyandex-speller@^4.1.0