summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@gmail.com>2014-10-15 21:29:23 +0200
committerAaron O'Mullan <aaron.omullan@gmail.com>2014-10-15 21:29:23 +0200
commitce50b893e926fed8905419efc8bce4a64ab2d5dc (patch)
tree83cf19e47f26fd77072ac63aeaf2152a4b30ffa6
parent49e3bbc3d6e9e128df721494e9a10eaf15b7ddc8 (diff)
parent225ff27dd15b904d6a4a784c219522a28f316a5b (diff)
downloadgitbook-ce50b893e926fed8905419efc8bce4a64ab2d5dc.zip
gitbook-ce50b893e926fed8905419efc8bce4a64ab2d5dc.tar.gz
gitbook-ce50b893e926fed8905419efc8bce4a64ab2d5dc.tar.bz2
Merge pull request #482 from GitbookIO/feature/includes
Add include support, with variables and the whole shebang
-rw-r--r--lib/generate/generator.js23
-rw-r--r--lib/generate/index.js2
-rw-r--r--lib/generate/site/index.js35
-rw-r--r--lib/parse/code_include.js20
-rw-r--r--lib/parse/include.js48
-rw-r--r--lib/parse/page.js15
-rw-r--r--lib/parse/renderer.js5
7 files changed, 96 insertions, 52 deletions
diff --git a/lib/generate/generator.js b/lib/generate/generator.js
index 8724a4f..84c65d7 100644
--- a/lib/generate/generator.js
+++ b/lib/generate/generator.js
@@ -14,12 +14,35 @@ var BaseGenerator = function(options) {
this.options.plugins = Plugin.normalizeNames(this.options.plugins);
this.options.plugins = _.union(this.options.plugins, this.options.defaultsPlugins);
this.plugins = [];
+
+ // Include variables (not yet loaded)
+ this.variables = {};
};
BaseGenerator.prototype.callHook = function(name, data) {
return this.plugins.hook(name, data);
};
+// Sets up generator
+BaseGenerator.prototype.load = function() {
+ return this.loadVariables()
+ .then(this.loadPlugins.bind(this));
+};
+
+BaseGenerator.prototype.loadVariables = function() {
+ var that = this;
+
+ return fs.readFile(path.join(this.options.input, 'variables.json'), 'utf8')
+ .then(function(content) {
+ try {
+ that.variables = JSON.parse(content);
+ } catch(err) {
+ console.log('No variables.json');
+ }
+ })
+ .fail(function() {});
+};
+
BaseGenerator.prototype.loadPlugins = function() {
var that = this;
diff --git a/lib/generate/index.js b/lib/generate/index.js
index 4fc78a7..2118c46 100644
--- a/lib/generate/index.js
+++ b/lib/generate/index.js
@@ -40,7 +40,7 @@ var loadGenerator = function(options) {
.then(function() {
var generator = new generators[options.generator](options);
- return generator.loadPlugins()
+ return generator.load()
.then(_.constant(generator));
});
};
diff --git a/lib/generate/site/index.js b/lib/generate/site/index.js
index a694f39..4179917 100644
--- a/lib/generate/site/index.js
+++ b/lib/generate/site/index.js
@@ -23,6 +23,16 @@ var Generator = function() {
};
util.inherits(Generator, BaseGenerator);
+// Add template loading to load
+Generator.prototype.load = function() {
+ var that = this;
+
+ return BaseGenerator.prototype.load.apply(this)
+ .then(function() {
+ return that.loadTemplates();
+ });
+};
+
// Load all templates
Generator.prototype.loadTemplates = function() {
this.template = swig.compileFile(
@@ -36,16 +46,6 @@ Generator.prototype.loadTemplates = function() {
);
};
-// Load plugins
-Generator.prototype.loadPlugins = function() {
- var that = this;
-
- return BaseGenerator.prototype.loadPlugins.apply(this)
- .then(function() {
- return that.loadTemplates();
- });
-};
-
// Generate a template
Generator.prototype._writeTemplate = function(tpl, options, output, interpolate) {
var that = this;
@@ -118,16 +118,17 @@ Generator.prototype.prepareFile = function(content, _input) {
return _callHook("page:before");
})
.then(function() {
- // Lex page
- return parse.lex(page.content);
- })
- .then(function(lexed) {
- page.lexed = lexed;
-
+ // Lex, parse includes and get
// Get HTML generated sections
- return parse.page(lexed, {
+ return parse.page(page.content, {
+ // Local files path
dir: path.dirname(_input) || '/',
+ // Project's include folder
+ includes_dir: path.join(that.options.input, '_includes'),
+ // Output directory
outdir: path.dirname(_input) || '/',
+ // Templating variables
+ variables: that.variables,
});
})
.then(function(sections) {
diff --git a/lib/parse/code_include.js b/lib/parse/code_include.js
deleted file mode 100644
index 977dc3d..0000000
--- a/lib/parse/code_include.js
+++ /dev/null
@@ -1,20 +0,0 @@
-var fs = require('graceful-fs');
-var path = require('path');
-
-module.exports = function(code, folder) {
- folder = folder || '';
-
- return code.replace(/{{([\s\S]+?)}}/g, function(match, filename) {
- // Normalize filename
- var fname = path.join(folder, filename.trim());
-
- // Try including snippet from FS
- try {
- // Trim trailing newlines/space of imported snippets
- return fs.readFileSync(fname, 'utf8').trimRight();
- } catch(err) {}
-
- // If fails leave content as is
- return match;
- });
-};
diff --git a/lib/parse/include.js b/lib/parse/include.js
new file mode 100644
index 0000000..5fba2be
--- /dev/null
+++ b/lib/parse/include.js
@@ -0,0 +1,48 @@
+var _ = require('lodash');
+var fs = require('graceful-fs');
+var path = require('path');
+
+
+// Include helper
+function importInclude(name, paths) {
+ return paths
+ .map(function(folder) {
+ // Try including snippet from FS
+ try {
+ var fname = path.join(folder, name);
+ // Trim trailing newlines/space of imported snippets
+ return fs.readFileSync(fname, 'utf8').trimRight();
+ } catch(err) {}
+ })
+ .filter(Boolean)[0];
+}
+
+function includer(ctx, folders) {
+ return function(key) {
+ key = key.trim();
+ return ctx[key] || importInclude(key, folders);
+ };
+}
+
+module.exports = function(markdown, folder, ctx) {
+ // List of folders to search for includes
+ var folders = [];
+
+ // Handle folder arg (string or array)
+ if(_.isString(folder)) {
+ folders = [folder];
+ } else if(_.isArray(folder)) {
+ folders = folder;
+ }
+
+ // variable context
+ ctx = ctx || {};
+
+ // Memoized include function (to cache lookups)
+ var _include = _.memoize(includer(ctx, folders));
+
+ return markdown.replace(/{{([\s\S]+?)}}/g, function(match, key) {
+ // If fails leave content as is
+ return _include(key) || match;
+ });
+};
diff --git a/lib/parse/page.js b/lib/parse/page.js
index ae71666..e694f1c 100644
--- a/lib/parse/page.js
+++ b/lib/parse/page.js
@@ -5,7 +5,7 @@ var hljs = require('highlight.js');
var lex = require('./lex');
var renderer = require('./renderer');
-var codeInclude = require('./code_include');
+var include = require('./include');
var lnormalize = require('../utils/lang').normalize;
@@ -51,7 +51,7 @@ function parsePage(src, options) {
options = options || {};
// Lex if not already lexed
- return (_.isArray(src) ? src : lex(src))
+ return (_.isArray(src) ? src : lex(include(src, [options.dir, options.includes_dir], options.variables)))
.map(function(section) {
// Transform given type
if(section.type === 'exercise') {
@@ -74,20 +74,15 @@ function parsePage(src, options) {
// Main language
var lang = validLangs ? langs[0] : null;
- // codeInclude shortcut
- var ci = function(code) {
- return codeInclude(code, options.dir);
- };
-
return {
id: section.id,
type: section.type,
content: render(nonCodeNodes, options),
lang: lang,
code: {
- base: ci(codeNodes[0].text),
- solution: ci(codeNodes[1].text),
- validation: ci(codeNodes[2].text),
+ base: codeNodes[0].text,
+ solution: codeNodes[1].text,
+ validation: codeNodes[2].text,
// Context is optional
context: codeNodes[3] ? codeNodes[3].text : null,
}
diff --git a/lib/parse/renderer.js b/lib/parse/renderer.js
index faa416c..61b3d9b 100644
--- a/lib/parse/renderer.js
+++ b/lib/parse/renderer.js
@@ -1,8 +1,6 @@
var url = require('url');
var inherits = require('util').inherits;
var links = require('../utils').links;
-var codeInclude = require('./code_include');
-
var path = require('path');
@@ -130,8 +128,7 @@ GitBookRenderer.prototype.listitem = function(text) {
GitBookRenderer.prototype.code = function(code, lang, escaped) {
return GitBookRenderer.super_.prototype.code.call(
this,
- // Import code snippets
- codeInclude(code, this._extra_options.dir),
+ code,
lang,
escaped
);