#! /usr/bin/env runjs
var ByteArrayOutputStream = java.io.ByteArrayOutputStream;
var Bytes = Packages.me.hatter.tools.commons.bytes.Bytes;
var FileUtil = Packages.me.hatter.tools.commons.file.FileUtil;
var argsjs = require('component-args.js');
var CALIBRE_HOME = '/Applications/calibre.app/Contents/MacOS';
var DOT = 'dot';
var NPM = 'npm';
var GITBOOK = 'gitbook';
var CALIBRE_EBOOK_CONVERT = 'ebook-convert';
var NODE_INSTALL_URL = 'https://nodejs.org/en/download/';
var CALIBRE_INSTALL_URL = 'https://calibre-ebook.com/download';
var DOT_INSTALL = 'brew install graphviz';
var GITBOOK_INSTALL = 'npm install -g gitbook-cli';
var DEFAULT_PROCESSOR_VIZ = null;
var DEFAULT_PROCESSOR = {
'plantuml': (lns, tmpDir) => {
$ONCE('gitbook.js-defaultprocessor-plantuml-requirejar-plantuml').run(() => {
requireJAR('plantuml-8059.jar');
});
var FileFormat = Packages.net.sourceforge.plantuml.FileFormat;
var FileFormatOption = Packages.net.sourceforge.plantuml.FileFormatOption;
var SourceStringReader = Packages.net.sourceforge.plantuml.SourceStringReader;
var puml = $ARR(lns).join('\n');
var dgst = Bytes.from(puml).digest($$.digests().sha256()).asHex();
var baos = new ByteArrayOutputStream();
var reader = new SourceStringReader(puml);
reader.generateImage(baos, new FileFormatOption(FileFormat.PNG, false));
$$.rFile(tmpDir, dgst + '.png').write(baos.toByteArray());
return '
';
},
'graphviz': (lns, tmpDir) => {
var viz = $ARR(lns).join('\n');
var vizB64 = Bytes.from(viz).asBase64();
var dgst = Bytes.from(viz).digest($$.digests().sha256()).asHex();
var vizToPngRes = $$.shell().commands('sh', '-c', 'echo ' + vizB64 + ' | base64 -D | dot -Tpng').start();
$$.rFile(tmpDir, dgst + '.png').write(vizToPngRes[0].bytes());
return '
';
}
};
// return null or string
var dealWithMarkdown = (f, tmpDir, mdList, plugins) => {
var list = [];
var codeTag = null;
var codeList = [];
var inCode = false;
$ARR(mdList).forEach((ln) => {
if (inCode) {
if ($STR(ln.trim()) == '```') {
// CODE ENDED
inCode = false;
var plugInFunc = null;
plugins.forEach((p) => {
if (plugInFunc == null) {
plugInFunc = p[codeTag || 'default'];
}
});
if (plugInFunc == null) {
// plugin not found
list.push('```' + codeTag);
codeList.forEach((ln) => { list.push(ln) } );
list.push('```');
} else {
list.push(plugInFunc(codeList, tmpDir));
}
} else {
codeList.push(ln);
}
} else if (ln.trim().startsWith('```')) {
// CODE STARTED
inCode = true;
codeList = [];
codeTag = ln.trim().substring(3).trim();
} else {
list.push(ln);
}
});
if (inCode) {
xprintln('[ERROR] Markdown content error: ' + f);
return null;
}
return list.join('\n');
};
// gitbook-cli OR https://github.com/GitbookIO/gitbook-pdf ?
var main = () => {
var args = argsjs.parseDefARGs(['default-processor', 'skip-delete-tmp']);
if (args.length < 1) {
xprintln('[ERROR] Need arguments.');
xprintln();
xprintln('gitbook.js [args] ');
xprintln(' --default-processor enable default processor');
xprintln(' --skip-delete-tmp skip delete tmp dir');
xprintln(' -p, --processor with file processor');
xprintln(' -t, --type <"pdf"> default pdf');
xprintln(' -d, --dir default "."');
return;
}
var whichRes = $$.shell().commands('which', NPM).start();
if ($STR(whichRes[0].toString().trim()) == '') {
xprintln('[ERROR] Node is not installed.');
xprintln('[INFO] Install node URL: ' + NODE_INSTALL_URL);
return;
}
xprintln('[OK] Check node installed: ' + $$.shell().commands('node', '-v').start()[0].toString().trim());
var gitbookRes = $$.shell().commands('which', GITBOOK).start();
if ($STR(gitbookRes[0].toString().trim()) == '') {
xprintln('[ERROR] Gitbook is not installed.');
xprintln('[INFO] Install gitbook command: ' + GITBOOK_INSTALL);
return;
}
xprintln('[OK] Check gitbook installed: ' + $$.shell().commands('gitbook', '-V').start()[0].toString().trim().replace('\n', '; '));
var dotRes = $$.shell().commands('which', DOT).start();
if ($STR(dotRes[0].toString().trim()) == '') {
xprintln('[ERROR] Graphviz is not installed.');
xprintln('[INFO] Install graphviz command: ' + DOT_INSTALL);
return;
}
xprintln('[OK] Check graphviz installed: ' + $$.shell().commands('dot', '-V').mergeErrorOutput(true).start()[0].toString().trim().replace('\n', '; '));
var ebookConvert = $$.file(CALIBRE_HOME, CALIBRE_EBOOK_CONVERT);
if (!(ebookConvert.exists())) {
xprintln('[ERROR] Calibre is not installed.');
xprintln('[INFO] Install calibre URL: ' + CALIBRE_INSTALL_URL);
return;
}
xprintln('[OK] Check calibre installed: ' + $$.shell().commands(ebookConvert.getAbsolutePath(), '--version').start()[0].list().get(0));
var gitbookShell = $$.shell();
var ebookConvertRes = $$.shell().commands('which', CALIBRE_EBOOK_CONVERT).start();
if ($STR(ebookConvertRes[0].toString().trim()) == '') {
xprintln('[INFO] $PATH add calibre home: ' + CALIBRE_HOME);
gitbookShell.env('PATH', '$PATH:' + CALIBRE_HOME);
}
var _type = args.val('t', 'type') || 'pdf';
var _dir = args.val('d', 'dir') || '.';
if ($STR(_type) != 'pdf') {
xprintln('[ERROR] Currently only supports pdf.');
return;
}
var _tempDir = $$.file(_dir, '.tmp');
var plugins = [];
var processors = args.vals('p', 'processor');
processors.forEach((p) => {
xprintln('[INFO] Load processor: ' + p);
plugins.push(require('file://' + p));
});
if (args.flg('default-processor')) {
plugins.push(DEFAULT_PROCESSOR);
}
if (plugins.length > 0) {
if (_tempDir.exists()) {
xprintln('[INFO] Delete exists tmp dir: ' + _tempDir);
FileUtil.deleteDirectory(_tempDir);
}
xprintln('[INFO] Create tmp dir: ' + _tempDir);
_tempDir.mkdirs();
$ARR($$.file(_dir).listFiles()).forEach((f) => {
if (f.getName().toLowerCase().endsWith('.md')) {
var contents = $$.rFile(f).list();
var newContents = dealWithMarkdown(f, _tempDir, contents, plugins);
if (newContents != null) {
xprintln('[INFO] Update md file: ' + f.getName());
$$.rFile(_tempDir, f.getName()).write(newContents);
} else {
$$.rFile(_tempDir, f.getName()).write(contents.join('\n'));
}
}
});
}
var commands = [];
commands.push(GITBOOK);
commands.push(_type);
commands.push((plugins.length > 0) ? _tempDir : _dir);
commands.push(args[0]);
xprintln('[INFO] Run gitbook command: ' + $TO_JAVA_LIST(commands));
gitbookShell.commands(commands).run();
if (_tempDir.exists()) {
if (!(args.flg('skip-delete-tmp'))) {
xprintln('[INFO] Delete tmp dir: ' + _tempDir);
FileUtil.deleteDirectory(_tempDir);
}
}
};
main();