Comparing version 2.2.0 to 2.3.0
# Changelog | ||
## 2.3.0 | ||
- JSON comments in dictionaries and configs #35 | ||
- Аbility to specify multiple dictionaries in option --dictionary #33 | ||
- Markdown report #31 | ||
- Update deps in package.json | ||
## 2.2.0 | ||
@@ -4,0 +10,0 @@ - Exit code for error loading in API #29. |
@@ -1,7 +0,6 @@ | ||
var fs = require('fs'), | ||
chalk = require('chalk'), | ||
var chalk = require('chalk'), | ||
util = require('util'), | ||
debug = require('./debug'), | ||
exitCodes = require('./exit-codes'), | ||
isutf8 = require('isutf8'), | ||
util = require('util'), | ||
utils = require('./utils'), | ||
printDebug = debug.print; | ||
@@ -19,7 +18,7 @@ | ||
* | ||
* @param {string} file - File name (example: yaspeller.dictionary.json) | ||
* @param {Array} files | ||
* @param {Array} dictionary - Dictionary from .yaspellerrc | ||
* @return {Array} | ||
*/ | ||
getDictionary: function(file, dictionary) { | ||
getDictionary: function(files, dictionary) { | ||
var result = []; | ||
@@ -31,5 +30,5 @@ | ||
if(file) { | ||
files && files.forEach(function(file) { | ||
result = result.concat(this.loadDictionary(file)); | ||
} | ||
}, this); | ||
@@ -45,26 +44,16 @@ return this.prepareDictionary(result); | ||
loadDictionary: function(file) { | ||
/* istanbul ignore next */ | ||
if(fs.existsSync(file)) { | ||
printDebug('get/check dictionary: ' + file); | ||
try { | ||
var bufDict = fs.readFileSync(file); | ||
if(!isutf8(bufDict)) { | ||
console.error(chalk.red(file + ': is not utf-8')); | ||
process.exit(exitCodes.ERROR_DICTIONARY); | ||
} | ||
var data = []; | ||
printDebug('use dictionary: ' + file.dictionary); | ||
printDebug('Get/check dictionary: ' + file); | ||
return JSON.parse(bufDict.toString('utf-8')); | ||
} catch(e) { | ||
console.error(chalk.red(file + ': error parsing JSON')); | ||
process.exit(exitCodes.ERROR_DICTIONARY); | ||
} | ||
} else { | ||
console.error(chalk.red(file + ': is not exists')); | ||
try { | ||
data = utils.loadJsonFile(file, true); | ||
printDebug('Use dictionary: ' + file); | ||
} catch(e) { | ||
console.error(chalk.red(e)); | ||
process.exit(exitCodes.ERROR_DICTIONARY); | ||
} | ||
/* istanbul ignore next */ | ||
return []; | ||
return data; | ||
}, | ||
@@ -71,0 +60,0 @@ /** |
@@ -5,6 +5,10 @@ /*jshint maxlen:1000 */ | ||
function splitOnCommas(val) { | ||
return val.split(',').map(function(el) {return el.trim()}); | ||
function splitTrim(value, separator) { | ||
return value.split(separator).map(function(el) {return el.trim()}); | ||
} | ||
function splitByCommas(value) { | ||
return splitTrim(value, ','); | ||
} | ||
module.exports = { | ||
@@ -18,9 +22,11 @@ set: function(prefs) { | ||
.option('-c, --config <path>', 'configuration file path') | ||
.option('-e, --file-extensions <value>', 'set file extensions to search for files in a folder. Example: ".md,.html"', splitOnCommas, null) | ||
.option('--dictionary <file>', 'json file for own dictionary') | ||
.option('-e, --file-extensions <value>', 'set file extensions to search for files in a folder. Example: ".md,.html"', splitByCommas, null) | ||
.option('--dictionary <file>', 'json file for own dictionary', function(value) { | ||
return splitTrim(value, ':'); | ||
}, []) | ||
.option('--no-colors', 'clean output without colors') | ||
.option('--report <type>', 'generate a report: console, text, html or json. Default: console', splitOnCommas, null) | ||
.option('--report <type>', 'generate a report: console, text, html or json. Default: console', splitByCommas, null) | ||
.option('--ignore-tags <tags>', 'ignore tags. Default: "' + | ||
prefs.defaultIgnoreTags + | ||
'"', splitOnCommas, null) | ||
'"', splitByCommas, null) | ||
.option('--max-requests <number>', 'max count of requests at a time. Default: 2', parseInt, 0) | ||
@@ -27,0 +33,0 @@ .option('--only-errors', 'output only errors') |
var chalk = require('chalk'), | ||
program = require('commander'), | ||
pth = require('path'), | ||
stats = { | ||
total: 0, | ||
errors: 0, | ||
ok: 0 | ||
}, | ||
reports = [], | ||
@@ -25,13 +31,28 @@ reportNames = {}, | ||
oneach: function(err, data, dictionary) { | ||
buffer.push([err, data]); | ||
var isError = err || (!err && data.data && data.data.length); | ||
stats.total++; | ||
reports.forEach(function(name) { | ||
name.oneach && name.oneach(err, data, dictionary); | ||
}); | ||
if(isError) { | ||
stats.errors++; | ||
buffer.push([err, data]); | ||
} else { | ||
stats.ok++; | ||
if(!program.onlyErrors) { | ||
buffer.push([err, data]); | ||
} | ||
} | ||
if((program.onlyErrors && isError) || !program.onlyErrors) { | ||
reports.forEach(function(name) { | ||
name.oneach && name.oneach(err, data, dictionary); | ||
}); | ||
} | ||
}, | ||
onend: function() { | ||
reports.forEach(function(name) { | ||
name.onend && name.onend(buffer); | ||
name.onend && name.onend(buffer, stats); | ||
}); | ||
} | ||
}; |
var chalk = require('chalk'), | ||
program = require('commander'), | ||
utils = require('../utils'), | ||
yaspeller = require('../yaspeller'), | ||
hasErrors = false, | ||
counter = 0; | ||
yaspeller = require('../yaspeller'); | ||
function getTypos(data, code) { | ||
function getTyposByCode(code, data) { | ||
var typos = [], | ||
@@ -24,4 +22,4 @@ num = 1; | ||
if(utils.hasEnRu(word)) { | ||
comment.push(chalk.red('en: ' + word.replace(/[а-яё]/gi, '*'))); | ||
comment.push(chalk.green('ru: ' + word.replace(/[a-z]/gi, '*'))); | ||
comment.push(chalk.red('en: ' + utils.replaceRu(word))); | ||
comment.push(chalk.green('ru: ' + utils.replaceEn(word))); | ||
} | ||
@@ -40,21 +38,9 @@ | ||
function hasManyErrors(data) { | ||
return data.some(function(el) { | ||
return el.code === 4; // ERROR_TOO_MANY_ERRORS | ||
}); | ||
} | ||
module.exports = { | ||
oneach: function(err, data) { | ||
counter++; | ||
var errors = []; | ||
if(err || (data && data.data && data.data.length)) { | ||
hasErrors = true; | ||
} | ||
if(err) { | ||
console.error(chalk.red(data)); | ||
} else { | ||
if(hasManyErrors(data.data)) { | ||
if(utils.hasManyErrors(data.data)) { | ||
errors.push(chalk.red('Too many errors')); | ||
@@ -64,3 +50,3 @@ } | ||
yaspeller.errors.forEach(function(el) { | ||
var typos = getTypos(data.data, el.code); | ||
var typos = getTyposByCode(el.code, data.data); | ||
if(typos.length) { | ||
@@ -84,3 +70,3 @@ errors.push(chalk.red(el.title + ': ' + | ||
separator + errors.join('\n') + separator); | ||
} else if(!program.onlyErrors) { | ||
} else { | ||
console.log(chalk.green(utils.okSym) + ' ' + res + time); | ||
@@ -90,11 +76,11 @@ } | ||
}, | ||
onend: function() { | ||
if(!program.onlyErrors && counter) { | ||
if(!hasErrors) { | ||
onend: function(data, stats) { | ||
if(!program.onlyErrors && stats.total) { | ||
if(!stats.errors) { | ||
console.log(chalk.green('No errors.')); | ||
} | ||
console.log(chalk.magenta('Checking finished: ' + process.uptime() + ' sec.')); | ||
console.log(chalk.magenta('Checking finished: ' + utils.uptime())); | ||
} | ||
} | ||
}; |
@@ -6,5 +6,5 @@ var fs = require('fs'), | ||
module.exports = { | ||
filename: 'yaspeller_error_dictionary.json', | ||
onend: function(data) { | ||
var filename = 'yaspeller.error_dictionary.json', | ||
buffer = []; | ||
var buffer = []; | ||
@@ -37,4 +37,4 @@ data.forEach(function(el) { | ||
try { | ||
fs.writeFileSync(filename, JSON.stringify(buffer, null, ' ')); | ||
console.log(chalk.cyan('JSON dictionary with typos: ./' + filename)); | ||
fs.writeFileSync(this.filename, JSON.stringify(buffer, null, ' ')); | ||
console.log(chalk.cyan('JSON dictionary with typos: ./' + this.filename)); | ||
} catch(e) { | ||
@@ -41,0 +41,0 @@ console.error(chalk.red(e)); |
@@ -10,21 +10,2 @@ /*jshint maxlen:1000 */ | ||
function getTypos(data, code) { | ||
var typos = []; | ||
data.forEach(function(el) { | ||
if(el.code !== code) { | ||
return; | ||
} | ||
typos.push(el); | ||
}); | ||
return typos; | ||
} | ||
function hasManyErrors(data) { | ||
return data.some(function(el) { | ||
return el.code === 4; // ERROR_TOO_MANY_ERRORS | ||
}); | ||
} | ||
function makeLink(resource) { | ||
@@ -56,2 +37,3 @@ var href = resource, | ||
module.exports = { | ||
filename: 'yaspeller_report.html', | ||
oneach: function(err, data) { | ||
@@ -63,8 +45,8 @@ var html = []; | ||
html.push('<div class="typo">'); | ||
if(hasManyErrors(data.data)) { | ||
html.push('<div class="title">Too many errors</div>'); | ||
if(utils.hasManyErrors(data.data)) { | ||
html.push('<div class="title">Too many errors.</div>'); | ||
} | ||
yaspeller.errors.forEach(function(el) { | ||
var typos = getTypos(data.data, el.code); | ||
var typos = utils.getTyposByCode(el.code, data.data); | ||
if(typos.length) { | ||
@@ -82,4 +64,4 @@ html.push('<table class="table"><caption>' + el.title + '</caption>'); | ||
if(utils.hasEnRu(word)) { | ||
comment.push('<code class="letters-en">en: ' + _.escape(word.replace(/[а-яё]/gi, '*')) + '</code>'); | ||
comment.push('<code class="letters-ru">ru: ' + _.escape(word.replace(/[a-z]/gi, '*')) + '</code>'); | ||
comment.push('<code class="letters-en">en: ' + _.escape(utils.replaceRu(word)) + '</code>'); | ||
comment.push('<code class="letters-ru">ru: ' + _.escape(utils.replaceEn(word)) + '</code>'); | ||
} | ||
@@ -104,5 +86,5 @@ | ||
if(data.data && data.data.length) { | ||
html.unshift('<div class="err"><span class="sym-err">χ</span>' + makeLink(data.resource) + time + '</div>'); | ||
html.unshift('<div class="err"><span class="sym-err">χ</span>' + makeLink(data.resource) + time + '</div>'); | ||
} else { | ||
html.unshift('<div class="ok"><span class="sym-ok">✓</span>' + makeLink(data.resource) + time + '</div>'); | ||
html.unshift('<div class="ok"><span class="sym-ok">✓</span>' + makeLink(data.resource) + time + '</div>'); | ||
} | ||
@@ -115,27 +97,13 @@ | ||
}, | ||
onend: function(data) { | ||
var total = 0, | ||
err = 0, | ||
ok = 0; | ||
data.forEach(function(el) { | ||
total++; | ||
if(el[0] || (!el[0] && el[1].data && el[1].data.length)) { | ||
err++; | ||
} else { | ||
ok++; | ||
} | ||
}); | ||
onend: function(data, stats) { | ||
var template = fs.readFileSync(pth.join(__dirname, 'template.html')).toString(), | ||
filename = 'yaspeller_report.html', | ||
html = '<div class="total">Processed resources: ' + total + | ||
' (<span class="sym-err">χ</span>– ' + err + | ||
'</span>, <span class="sym-ok">✓</span>– ' + ok + ')<br/>' + | ||
'Checking finished: ' + process.uptime() + ' sec.</div>' + | ||
html = '<div class="total">Processed resources: ' + stats.total + | ||
' (<span class="sym-err">χ</span>– ' + stats.errors + | ||
'</span>, <span class="sym-ok">✓</span>– ' + stats.ok + ')<br/>' + | ||
'Checking finished: ' + utils.uptime() + '</div>' + | ||
buffer.join(''); | ||
try { | ||
fs.writeFileSync(filename, template.replace(/\{\{content\}\}/, html)); | ||
console.log(chalk.cyan('HTML report: ./' + filename)); | ||
fs.writeFileSync(this.filename, template.replace(/\{\{content\}\}/, html)); | ||
console.log(chalk.cyan('HTML report: ./' + this.filename)); | ||
} catch(e) { | ||
@@ -142,0 +110,0 @@ console.error(chalk.red(e)); |
@@ -5,7 +5,7 @@ var fs = require('fs'), | ||
module.exports = { | ||
filename: 'yaspeller_report.json', | ||
onend: function(data) { | ||
var filename = 'yaspeller_report.json'; | ||
try { | ||
fs.writeFileSync(filename, JSON.stringify(data, null, ' ')); | ||
console.log(chalk.cyan('JSON report: ./' + filename)); | ||
fs.writeFileSync(this.filename, JSON.stringify(data, null, ' ')); | ||
console.log(chalk.cyan('JSON report: ./' + this.filename)); | ||
} catch(e) { | ||
@@ -12,0 +12,0 @@ console.error(chalk.red(e)); |
136
lib/utils.js
var chalk = require('chalk'), | ||
fs = require('fs'), | ||
isutf8 = require('isutf8'), | ||
minimatch = require('minimatch'), | ||
@@ -11,24 +12,2 @@ pth = require('path'), | ||
function loadConfig(file) { | ||
var data; | ||
if(fs.existsSync(file)) { | ||
try { | ||
var config = fs.readFileSync(file, 'utf8'); | ||
if(['.js', '.json'].indexOf(pth.extname(file)) === -1) { | ||
config = stripJsonComments(config); | ||
} | ||
data = JSON.parse(config); | ||
printDebug('Using config: ' + file); | ||
} catch(e) { | ||
console.error(chalk.red('Error parsing ' + file)); | ||
process.exit(exitCodes.ERROR_CONFIG); | ||
} | ||
} | ||
return data; | ||
} | ||
module.exports = { | ||
@@ -53,11 +32,18 @@ /** | ||
printDebug('get/check JSON config'); | ||
printDebug('Get/check config.'); | ||
if(file) { | ||
data = loadConfig(file); | ||
} else { | ||
data = loadConfig('./.yaspellerrc'); | ||
if(!data) { | ||
data = loadConfig('./.yaspeller.json'); | ||
try { | ||
if(file) { | ||
data = this.loadJsonFile(file); | ||
} else { | ||
data = this.loadJsonFile('./.yaspellerrc'); | ||
if(!data) { | ||
data = this.loadJsonFile('./.yaspeller.json'); | ||
} | ||
} | ||
printDebug('Using config: ' + file); | ||
} catch(e) { | ||
console.error(chalk.red(e)); | ||
process.exit(exitCodes.ERROR_CONFIG); | ||
} | ||
@@ -68,2 +54,34 @@ | ||
/** | ||
* Load JSON file with comments. | ||
* | ||
* @param {string} file | ||
* @param {boolean} [throwIfFileNotExists] | ||
* @return {*} | ||
*/ | ||
loadJsonFile: function(file, throwIfFileNotExists) { | ||
var data; | ||
if(fs.existsSync(file)) { | ||
try { | ||
var json = fs.readFileSync(file); | ||
if(isutf8(json)) { | ||
json = json.toString('utf-8'); | ||
if(['.js', '.json'].indexOf(pth.extname(file)) !== -1) { | ||
json = stripJsonComments(json); | ||
} | ||
data = JSON.parse(json); | ||
} else { | ||
throw new Error(file + ': is not utf-8.'); | ||
} | ||
} catch(e) { | ||
throw new Error('Error parsing in the file: ' + file); | ||
} | ||
} else if(throwIfFileNotExists) { | ||
throw new Error(file + ': is not exists.'); | ||
} | ||
return data; | ||
}, | ||
/** | ||
* Find files to search for typos. | ||
@@ -137,2 +155,22 @@ * | ||
/** | ||
* Replace Russian symbols on a asterisk. | ||
* | ||
* @param {string} word | ||
* | ||
* @return {string} | ||
*/ | ||
replaceRu: function(word) { | ||
return word.replace(/[а-яё]/gi, '*'); | ||
}, | ||
/** | ||
* Replace Latin symbols on a asterisk. | ||
* | ||
* @param {string} word | ||
* | ||
* @return {string} | ||
*/ | ||
replaceEn: function(word) { | ||
return word.replace(/[a-z]/gi, '*'); | ||
}, | ||
/** | ||
* Is url? | ||
@@ -158,2 +196,42 @@ * | ||
/** | ||
* Get typos by code. | ||
* | ||
* @param {number} code | ||
* @param {Array} data | ||
* | ||
* @return {Array} | ||
*/ | ||
getTyposByCode: function(code, data) { | ||
var typos = []; | ||
data.forEach(function(el) { | ||
if(el.code !== code) { | ||
return; | ||
} | ||
typos.push(el); | ||
}); | ||
return typos; | ||
}, | ||
/** | ||
* Has many errors. | ||
* | ||
* @param {Array} data | ||
* | ||
* @return {boolean} | ||
*/ | ||
hasManyErrors: function(data) { | ||
return data.some(function(el) { | ||
return el.code === 4; // ERROR_TOO_MANY_ERRORS | ||
}); | ||
}, | ||
/** | ||
* Get uptime in sec. | ||
* | ||
* @return {string} | ||
*/ | ||
uptime: function() { | ||
return (Math.floor(process.uptime() * 1000) / 1000) + ' sec.'; | ||
}, | ||
/** | ||
* Ok symbol. | ||
@@ -160,0 +238,0 @@ * |
@@ -9,6 +9,6 @@ /* jshint maxlen: 300 */ | ||
pth = require('path'), | ||
Showdown = require('showdown'), | ||
showdown = require('showdown'), | ||
xml2js = require('xml2js'), | ||
_ = require('lodash'), | ||
markdownConverter = new Showdown.converter(), | ||
markdownConverter = new showdown.Converter(), | ||
printDebug = require('../lib/debug').print, | ||
@@ -15,0 +15,0 @@ YASPELLER_API_CHECKTEXT = 'https://speller.yandex.net/services/spellservice.json/checkText', |
@@ -13,3 +13,3 @@ { | ||
"description": "Search tool typos in the text, files and websites", | ||
"version": "2.2.0", | ||
"version": "2.3.0", | ||
"license": "MIT", | ||
@@ -36,6 +36,6 @@ "homepage": "https://github.com/hcodes/yaspeller", | ||
"dependencies": { | ||
"async": "~0.9.0", | ||
"async": "~1.0.0", | ||
"chalk": "~1.0.0", | ||
"commander": "~2.8.0", | ||
"eyo": "~1.0.0", | ||
"eyo": "~1.1.0", | ||
"entities": "~1.1.1", | ||
@@ -46,3 +46,3 @@ "isutf8": "~1.0.11", | ||
"request": "2.x", | ||
"showdown": "~0.5.0", | ||
"showdown": "~1.0.1", | ||
"strip-json-comments": "~1.0.2", | ||
@@ -56,3 +56,4 @@ "xml2js": "~0.4.5" | ||
"jshint": "~2.7.0", | ||
"mocha": "~2.2.1" | ||
"mocha": "~2.2.1", | ||
"sinon": "^1.14.1" | ||
}, | ||
@@ -59,0 +60,0 @@ "engines": { |
@@ -65,5 +65,9 @@ yaspeller | ||
``` | ||
Examples:<br/> | ||
`yaspeller --dictionary my_dict.json .`<br/> | ||
`yaspeller --dictionary my_dict.json:my_dict2.json .` | ||
#### `--report <type>` | ||
Set type of report: `console`, `html` or `json`.<br/> | ||
Set type of report: `console`, `html`, `markdown` or `json`.<br/> | ||
Default: `console`<br/> | ||
@@ -70,0 +74,0 @@ Example: `console,html,custom_report.js` |
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
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
57056
21
1317
238
6
+ Addedasync@1.0.0(transitive)
+ Addedeyo@1.1.0(transitive)
+ Addedshowdown@1.0.2(transitive)
- Removedasync@0.9.2(transitive)
- Removedeyo@1.0.0(transitive)
- Removedshowdown@0.5.4(transitive)
Updatedasync@~1.0.0
Updatedeyo@~1.1.0
Updatedshowdown@~1.0.1