Skip to content

Instantly share code, notes, and snippets.

@vsemozhetbyt
Created January 17, 2016 11:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vsemozhetbyt/e3a504ce6f8a94f36d0a to your computer and use it in GitHub Desktop.
Save vsemozhetbyt/e3a504ce6f8a94f36d0a to your computer and use it in GitHub Desktop.
'use strict';
/******************************************************************************/
const path = process.argv[2];
if (!path) {
console.log('Add the file path, please.');
process.exit();
}
/******************************************************************************/
const fs = require('fs');
const stringWidth = require('string-width');
const wrap = require('wordwrap');
const rl = require('readline').createInterface({
input: fs.createReadStream(path, {encoding: 'utf8'}), //ascii utf8 utf16le
terminal: false,
historySize: 0
});
const outfile = fs.openSync(path.replace(/(?:\.[^.]+)?$/, '.txt'), 'w');
const bomRE = /^\uFEFF/;
const dicWidth = 80;
const border = `/${ '*'.repeat(dicWidth - 2) }/\n`;
const isHwRE = /^\S/;
const hwMark = '• ';
const hwWidth = dicWidth - hwMark.length;
const hwWithCJKWidth = Math.floor(hwWidth / 2);
const hwIsHardWrapRE = new RegExp(`\\S{${hwWidth + 1},}`);
const hwWithCJKIsHardWrapRE = new RegExp(`\\S{${hwWithCJKWidth + 1},}`);
const hwDeEscapeRE = /\\([\\\[\]{}@^~<>#()])/g;
const cardIndent = ' ';
const cardWidth = dicWidth - cardIndent.length;
const cardSubIndentTagRE = /\[m(\d+)\]/;
const cardResetSubIndentRE = /\[\/m\]/;
const cardWrappedLineStartRE = /^(?=.)/mg;
const cardDeTagRE = /(?:\[\/?[^\]\\]+\])+/g;
const cardDeEscapeRE = /\\([\\\[\]{}@^~<>#])/g;
const cardEmptyLineRE = /^\s+\\\s+$/;
let currentWidth;
let currentIsHardWrapRE;
let cardSubIndent = '';
let hwFirst = true;
let lineNm = 0;
/******************************************************************************/
process.on('exit', () => {
fs.closeSync(outfile);
});
/******************************************************************************/
fs.writeSync(outfile,
`\uFEFF${border}` +
wrap(0, dicWidth, {mode: 'soft'})(
fs.readFileSync(path.replace(/(\.[^.]+)?$/, '.ann'), 'utf8')
.replace(/^\uFEFF?/, '')
) +
border,
null, 'utf8');
/******************************************************************************/
rl.on('line', function(line) {
lineNm++;
if (lineNm === 1) line = line.replace(bomRE, '');
if (!line.startsWith('#')) {
if (isHwRE.test(line)) {
cardSubIndent = '';
line = line.replace(hwDeEscapeRE, '$1');
if (hasCJK(line)) {
currentWidth = hwWithCJKWidth;
currentIsHardWrapRE = hwWithCJKIsHardWrapRE;
} else {
currentWidth = hwWidth;
currentIsHardWrapRE = hwIsHardWrapRE;
}
if (line.length > currentWidth) {
line = wrap(0, currentWidth, {mode:
`${currentIsHardWrapRE.test(line)? 'hard' : 'soft'}`
})(line);
}
fs.writeSync(outfile,
`${hwFirst? '\n' : ''}${hwMark}${line}\n`, null, 'utf8');
hwFirst = false;
} else {
hwFirst = true;
const cardSubIndentTag = line.match(cardSubIndentTagRE);
if (cardSubIndentTag) cardSubIndent = ' '.repeat(cardSubIndentTag[1]);
const resetSubIndent = cardResetSubIndentRE.test(line);
line = line
.replace(cardDeTagRE, '')
.replace(cardDeEscapeRE, '$1')
.replace(cardEmptyLineRE, '')
.trim();
if(line) {
if (hasCJK(line)) {
currentWidth = Math.floor((cardWidth - cardSubIndent.length) / 2);
} else {
currentWidth = cardWidth - cardSubIndent.length;
}
currentIsHardWrapRE = new RegExp(`\\S{${currentWidth + 1},}`);
if (line.length > currentWidth) {
line = wrap(0, currentWidth, {mode:
`${currentIsHardWrapRE.test(line)? 'hard' : 'soft'}`
})(line);
}
}
fs.writeSync(outfile, `${
line.replace(cardWrappedLineStartRE, `${cardIndent}${cardSubIndent}`)
}\n`, null, 'utf8');
if (resetSubIndent) cardSubIndent = '';
}
}
});
/******************************************************************************/
function hasCJK(str) {
return str.length !== stringWidth(str);
}
/******************************************************************************/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment