UNPKG

5.01 kBJavaScriptView Raw
1'use strict';
2
3const chalk = require('chalk');
4const charset = require('charset');
5
6const Eyo = require('eyo-kernel');
7
8const safeEyo = new Eyo();
9safeEyo.dictionary.loadSafeSync();
10
11const notSafeEyo = new Eyo();
12notSafeEyo.dictionary.loadNotSafeSync();
13
14const fs = require('fs');
15const iconv = require('iconv-lite');
16const isutf8 = require('isutf8');
17const program = require('commander');
18const request = require('request');
19
20const isWin = process.platform === 'win32';
21const okSym = isWin ? '[OK]' : '✓';
22const errSym = isWin ? '[ERR]' : '✗';
23const chalkDiff = isWin ? chalk.underline : chalk.bold;
24
25const exitCodes = {
26 NOT_UTF8: 21,
27 HAS_REPLACEMENT: 22,
28 NO_SUCH_FILE: 23,
29 UNKNOWN_CHARSET: 24
30};
31
32let isFirst = true;
33
34function printItem(color, item, i) {
35 const before = item.before;
36 const after = item.after;
37 const newBefore = [];
38 const newAfter = [];
39 const info = [];
40 const pos = Array.isArray(item.position) ? item.position[0] : item.position;
41
42 // Diff by letters
43 for (let n = 0; n < before.length; n++) {
44 if (before[n] !== after[n]) {
45 newBefore[n] = chalkDiff(before[n]);
46 newAfter[n] = chalkDiff(after[n]);
47 } else {
48 newBefore[n] = before[n];
49 newAfter[n] = after[n];
50 }
51 }
52
53 info.push(pos.line + ':' + pos.column);
54
55 if (item.count > 1) {
56 info.push('count: ' + item.count);
57 }
58
59 console.log(
60 (i + 1) + '. ' +
61 newBefore.join('') + ' → ' +
62 newAfter.join('') +
63 (info.length ? ' (' + info.join(', ') + ')' : '')
64 );
65}
66
67module.exports = {
68 /**
69 * Ёфицировать текст.
70 *
71 * @param {string} text
72 * @param {string} resource
73 */
74 _processText(text, resource) {
75 const n = isFirst ? '' : '\n';
76
77 if (program.lint) {
78 const safeReplacement = safeEyo.lint(text, program.sort);
79 if (safeReplacement.length) {
80 console.log(n + chalk.red(errSym) + ' ' + resource);
81 } else {
82 console.log(n + chalk.green(okSym) + ' ' + resource);
83 }
84
85 if (safeReplacement.length) {
86 console.log(chalk.yellow('Safe replacements:'));
87 safeReplacement.forEach(printItem.bind(this, 'red'));
88
89 if (!process.exitCode) {
90 process.exitCode = exitCodes.HAS_REPLACEMENT;
91 }
92 }
93
94 if (!program.onlySafe) {
95 const notSafeReplacement = notSafeEyo.lint(text, program.sort);
96 if (notSafeReplacement.length) {
97 console.log(chalk.red((notSafeReplacement.length ? '\n' : '') + 'Not safe replacements:'));
98 notSafeReplacement.forEach(printItem.bind(this, 'yellow'));
99 }
100 }
101 } else {
102 process.stdout.write(safeEyo.restore(text));
103 }
104
105 isFirst = false;
106 },
107 /**
108 * Ёфицировать файл.
109 *
110 * @param {string} file
111 * @param {Function} callback
112 */
113 _processFile(file, callback) {
114 if (fs.existsSync(file) && fs.statSync(file).isFile()) {
115 const buf = fs.readFileSync(file);
116 if (isutf8(buf)) {
117 this._processText(buf.toString('utf8'), file);
118 } else {
119 console.error(chalk.red(file + ': is not UTF-8.'));
120 process.exitCode = exitCodes.NOT_UTF8;
121 }
122 } else {
123 console.error(chalk.red(file + ': no such file.'));
124 process.exitCode = exitCodes.NO_SUCH_FILE;
125 }
126
127 callback();
128 },
129 /**
130 * Ёфицировать страницу.
131 *
132 * @param {string} url
133 * @param {Function} callback
134 */
135 _processUrl(url, callback) {
136 request.get(
137 {url, gzip: true, encoding: null},
138 function(error, res, buf) {
139 if (error) {
140 console.log(chalk.red(error));
141 process.exitCode = exitCodes.ERROR_LOADING;
142 }
143
144 if (res && res.statusCode !== 200) {
145 console.log(chalk.red(`${url}: returns status code is ${res.statusCode}.`));
146 process.exitCode = exitCodes.ERROR_LOADING;
147 callback();
148
149 return;
150 }
151
152 if (isutf8(buf)) {
153 this._processText(buf.toString('utf8'), url);
154 } else {
155 const enc = charset(res.headers['content-type'], buf);
156 if (iconv.encodingExists(enc)) {
157 this._processText(iconv.decode(buf, enc), url);
158 } else {
159 console.error(enc + ': is unknown charset.');
160 process.exitCode = exitCodes.UNKNOWN_CHARSET;
161 }
162 }
163
164 callback();
165 }.bind(this));
166 },
167 exitCodes
168};