diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/generate/fs.js | 3 | ||||
-rw-r--r-- | lib/generate/index.js | 110 | ||||
-rw-r--r-- | lib/parse/index.js | 1 | ||||
-rw-r--r-- | lib/parse/lex.js | 2 | ||||
-rw-r--r-- | lib/parse/page.js | 22 | ||||
-rw-r--r-- | lib/parse/readme.js | 32 |
6 files changed, 146 insertions, 24 deletions
diff --git a/lib/generate/fs.js b/lib/generate/fs.js index f5f74a5..f96efb3 100644 --- a/lib/generate/fs.js +++ b/lib/generate/fs.js @@ -16,7 +16,8 @@ var getFiles = function(path) { // Add extra rules to ignore common folders ig.addIgnoreRules([ - '.git/' + '.git/', + '.gitignore', ], '__custom_stuff'); // Push each file to our list diff --git a/lib/generate/index.js b/lib/generate/index.js index 4804548..33edc1f 100644 --- a/lib/generate/index.js +++ b/lib/generate/index.js @@ -1,8 +1,8 @@ var Q = require("q"); var _ = require("lodash"); - var path = require("path"); var swig = require('swig'); +var tmp = require('tmp'); var fs = require("./fs"); var parse = require("../parse"); @@ -15,6 +15,12 @@ var generators = { "json": require("./json") }; +var defaultDescription = "Book generated using GitBook"; + +/* + * Use a specific generator to convert a gitbook to a site/pdf/ebook/ + * output is always a folder + */ var generate = function(options) { var generator = null; var files; @@ -29,7 +35,7 @@ var generate = function(options) { // Book title, keyword, description title: null, - description: "Book generated using GitBook", + description: null, // Origin github repository id github: null, @@ -39,14 +45,16 @@ var generate = function(options) { theme: path.resolve(__dirname, '../../theme') }); - if (!options.title || !options.input || !options.output) { - return Q.reject(new Error("Need options: title, input, output")); + if (!options.input) { + return Q.reject(new Error("Need option input (book input directory)")); } if (!generators[options.generator]) { return Q.reject(new Error("Invalid generator (availables are: "+_.keys(generators).join(", "))); } + options.output = options.output || path.join(options.input, "_book"); + // Clean output folder return fs.remove(options.output) @@ -97,14 +105,37 @@ var generate = function(options) { return Q.reject(new Error("Invalid gitbook repository, need SUMMARY.md and README.md")); } else { // Generate the book - return fs.readFile(path.join(options.input, "SUMMARY.md"), "utf-8") + return Q() + + // Read readme + .then(function() { + return fs.readFile(path.join(options.input, "README.md"), "utf-8") + .then(function(_readme) { + _readme = parse.readme(_readme); + + options.title = options.title || _readme.title; + options.description = options.description || _readme.description || defaultDescription; + }); + }) // Get summary - .then(function(_summary) { - options.summary = parse.summary(_summary); + .then(function() { + return fs.readFile(path.join(options.input, "SUMMARY.md"), "utf-8") + .then(function(_summary) { + options.summary = parse.summary(_summary); + + // Parse navigation + options.navigation = parse.navigation(options.summary); + }); + }) - // Parse navigation - options.navigation = parse.navigation(options.summary); + // Skip processing some files + .then(function() { + files = _.filter(files, function (file) { + return !( + file === 'SUMMARY.md' + ); + }); }) // Copy file and replace markdown file @@ -142,7 +173,66 @@ var generate = function(options) { }); }; +/* + * Extract files from generate output in a temporary folder + */ +var generateFile = function(options) { + options = _.defaults(options || {}, { + input: null, + output: null, + extension: null + }); + + return Q.nfcall(tmp.dir) + .then(function(tmpDir) { + return generate( + _.extend({}, + options, + { + output: tmpDir + }) + ) + .then(function(_options) { + var ext = options.extension; + var outputFile = options.output || path.resolve(options.input, "book."+ext); + + var copyFile = function(lang) { + var _outputFile = outputFile; + var _tmpDir = tmpDir; + + if (lang) { + _outputFile = _outputFile.slice(0, -path.extname(_outputFile).length)+"_"+lang+path.extname(_outputFile); + _tmpDir = path.join(_tmpDir, lang); + } + + return fs.copy( + path.join(_tmpDir, "index."+ext), + _outputFile + ); + }; + + // Multi-langs book + return Q() + .then(function() { + if (_options.langsSummary) { + return Q.all( + _.map(_options.langsSummary.list, function(lang) { + return copyFile(lang.lang); + }) + ); + } else { + return copyFile(); + } + }) + .then(function() { + return fs.remove(tmpDir); + }); + }); + }); +}; + module.exports = { generators: generators, - folder: generate + folder: generate, + file: generateFile }; diff --git a/lib/parse/index.js b/lib/parse/index.js index 0e333e4..0ebb03a 100644 --- a/lib/parse/index.js +++ b/lib/parse/index.js @@ -5,4 +5,5 @@ module.exports = { lex: require('./lex'), progress: require('./progress'), navigation: require('./navigation'), + readme: require('./readme') }; diff --git a/lib/parse/lex.js b/lib/parse/lex.js index 813dd33..17eab69 100644 --- a/lib/parse/lex.js +++ b/lib/parse/lex.js @@ -56,7 +56,7 @@ function isQuiz(nodes) { if( // List of questions - listIdx !== -1 && isQuizNode(quizNodes[listIdx + 1]) && + listIdx !== -1 && isQuizNode(quizNodes[listIdx + 1]) || // Table of questions ( diff --git a/lib/parse/page.js b/lib/parse/page.js index eb118e4..efadf82 100644 --- a/lib/parse/page.js +++ b/lib/parse/page.js @@ -8,17 +8,6 @@ var renderer = require('./renderer'); var lnormalize = require('../utils/lang').normalize; -// Synchronous highlighting with highlight.js -marked.setOptions({ - highlight: function (code, lang) { - try { - return hljs.highlight(lang, code).value; - } catch(e) { - return hljs.highlightAuto(code).value; - } - } -}); - // Render a section using our custom renderer function render(section, _options) { @@ -30,7 +19,16 @@ function render(section, _options) { // Build options using defaults and our custom renderer var options = _.extend({}, marked.defaults, { - renderer: renderer(null, _options) + renderer: renderer(null, _options), + + // Synchronous highlighting with highlight.js + highlight: function (code, lang) { + try { + return hljs.highlight(lang, code).value; + } catch(e) { + return hljs.highlightAuto(code).value; + } + } }); return marked.parser(section, options); diff --git a/lib/parse/readme.js b/lib/parse/readme.js new file mode 100644 index 0000000..aab094d --- /dev/null +++ b/lib/parse/readme.js @@ -0,0 +1,32 @@ +var _ = require('lodash'); +var marked = require('marked'); + +function extractFirstNode(nodes, nType) { + return _.chain(nodes) + .filter(function(node) { + return node.type == nType; + }) + .pluck("text") + .first() + .value(); +} + + +function parseReadme(src) { + var nodes, title, description; + + // Parse content + nodes = marked.lexer(src); + + var title = extractFirstNode(nodes, "heading"); + var description = extractFirstNode(nodes, "paragraph"); + + return { + title: title, + description: description + }; +} + + +// Exports +module.exports = parseReadme; |