-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathconvert.js
186 lines (148 loc) · 4.68 KB
/
convert.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#!/usr/bin/env node
var restler = require('restler');
var fs = require('fs');
var q = require('q');
var optimist = require('optimist');
var argv = optimist
.usage('Convert an image to text image data.\nUsage: $0')
.demand('i')
.alias('i', 'image')
.describe('i', 'Image file path to convert.')
.alias('o', 'output')
.describe('o', 'Output file (default STDOUT)')
.alias('w', 'width')
.describe('w', 'Width of each line (default 80, MAX 80)')
.alias('v', 'variable')
.describe('v', 'Global variable name to assign data')
.argv;
var imagePath = argv.image;
var readImageStat = q.nfcall(fs.stat, imagePath);
// request to http://www.text-image.com/convert/
var postImageToConvert = function (stat) {
var url = 'http://www.text-image.com/convert/pic2html.cgi';
var deferred = q.defer();
restler.post(url, {
multipart: true,
data: {
characters: '1',
textType: 'sequence',
fontsize: 1,
width: argv.width || 80,
grayscale: 0,
bgcolor: 'BLACK',
contrast: 0,
browser: 'firefox',
// restler.file(path, filename, fileSize, encoding, contentType)
image: restler.file(imagePath, null, stat.size, null, null)
}
}).on('success', function (data) {
deferred.resolve(data);
}).on('fail', function () {
deferred.reject(new Error('Request failed to server.'));
});
return deferred.promise;
};
var parseResponseHtml = function (html) {
var deferred = q.defer();
var start = '<!-- IMAGE BEGINS HERE -->';
var end = '<!-- IMAGE ENDS HERE -->';
var regex = new RegExp(start + '(.*)' + end, 'm');
var str = html.replace(/[\r\n]/g, '');
var match = regex.exec(str);
if (match && match[1]) {
deferred.resolve(match[1]);
} else {
deferred.reject(new Error('Responsed HTML is invalid.'));
}
return deferred.promise;
};
var makeImageTextData = function (str) {
// remove start tag
str = str.replace(/^<font size="1"><pre>/, '');
// remove end tag
str = str.replace(/<br><\/pre><\/font>$/, '');
// fix unclosed <font> tags
// ex) `<font>A/font>` or `<font>Afont>`
str = str.replace(/([01]+)(?:\/?font>)/g, '$1</font>');
// fix case of `<fontA`
str = str.replace(/(#\w{6})(?!>)/g, '$1>');
// fix unopend <font> tag
// ex) `font>A`
str = str.replace(/>font/g, '><font');
// modify string to color code
// ex) black or white
str = str.replace(/black/ig, '#000000');
str = str.replace(/white/ig, '#ffffff');
var lines = str.split('<br>');
var regex = /<font color=#([a-z0-9]+)>([01]+)<\/font>/g;
// make data strings with `color{4}count{1}color{4}count{1}/color{4}count{1}` pattern.
// slash(/) character stands for line break
// ex) abcd 3 bcde k / cdef { efgh x
var result = lines.map(function (line) {
var blockData;
var lineData = '';
while (regex.test(line)) {
var color = RegExp.$1;
var code = RegExp.$2;
blockData = encodeColor(color) + encodeLength(code.length);
lineData += blockData;
}
return lineData;
});
return result.join('/');
};
/**
* encode color code using customized base64 in order to reduce data size.
* ex) 'abcdef' --> 'q83v'
* @param {String} code color code (6 hex, ex: efefef)
*/
var keystr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789<>!@#$%^&*()_+[]{}';
function encodeColor(color) {
var n, enc1, enc2;
var encoded = '';
for (var i = 0; i < 6; i += 3) {
n = parseInt(color.substr(i, 3), 16);
enc1 = n >> 6;
enc2 = n & 63;
encoded += keystr.charAt(enc1) + keystr.charAt(enc2);
}
return encoded;
}
/**
* encode code length using key string
* @param {Number} len code length (max value: 80)
*/
function encodeLength(len) {
return keystr[len - 1];
}
var assignToVariable = function (data) {
if (argv.v) {
// assign data to variable
// ex) var name = 'data';
return 'var ' + argv.v + '=\'' + data + '\';';
}
return data;
};
var writeToOutput = function (data) {
var deferred = q.defer();
var output = argv.o;
if (output) {
fs.writeFile(output, data, deferred.makeNodeResolver());
} else {
console.log(data);
deferred.resolve();
}
return deferred.promise;
};
// main job
readImageStat
.then(postImageToConvert)
.then(parseResponseHtml)
.timeout(20000)
.then(makeImageTextData)
.then(assignToVariable)
.then(writeToOutput)
.fail(function (reason) {
throw new Error(reason);
})
.done();