Add editorconfig and normalize indent

This commit is contained in:
Samy Pessé
2015-03-14 23:23:28 +01:00
parent 8320484b88
commit 9448562156
35 changed files with 1048 additions and 1038 deletions
+10
View File
@@ -0,0 +1,10 @@
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
+316 -316
View File
@@ -22,68 +22,68 @@ var PluginsList = require("./pluginslist");
var generators = require("./generators");
var Book = function(root, context, parent) {
var that = this;
var that = this;
this.context = _.defaults(context || {}, {
// Extend book configuration
config: {},
this.context = _.defaults(context || {}, {
// Extend book configuration
config: {},
// Log function
log: function(msg) {
process.stdout.write(msg);
},
// Log function
log: function(msg) {
process.stdout.write(msg);
},
// Log level
logLevel: "info"
});
// Log level
logLevel: "info"
});
// Log
this.log = logger(this.context.log, this.context.logLevel);
// Log
this.log = logger(this.context.log, this.context.logLevel);
// Root folder of the book
this.root = path.resolve(root);
// Root folder of the book
this.root = path.resolve(root);
// Parent book
this.parent = parent;
// Parent book
this.parent = parent;
// Configuration
this.config = new Configuration(this, this.context.config);
Object.defineProperty(this, "options", {
get: function () {
return this.config.options;
}
});
// Configuration
this.config = new Configuration(this, this.context.config);
Object.defineProperty(this, "options", {
get: function () {
return this.config.options;
}
});
// Template
this.template = new TemplateEngine(this);
// Template
this.template = new TemplateEngine(this);
// Summary
this.summary = {};
this.navigation = [];
// Summary
this.summary = {};
this.navigation = [];
// Glossary
this.glossary = [];
// Glossary
this.glossary = [];
// Langs
this.langs = [];
// Langs
this.langs = [];
// Sub-books
this.books = [];
// Sub-books
this.books = [];
// Files in the book
this.files = [];
// Files in the book
this.files = [];
// List of plugins
this.plugins = new PluginsList(this);
// List of plugins
this.plugins = new PluginsList(this);
// Structure files
// Structure files
this.summaryFile = null;
this.glossaryFile = null;
this.readmeFile = null;
this.readmeFile = null;
this.langsFile = null;
// Search Index
this.searchIndex = lunr(function () {
// Search Index
this.searchIndex = lunr(function () {
this.ref('url');
this.field('title', { boost: 10 });
@@ -91,153 +91,153 @@ var Book = function(root, context, parent) {
});
// Bind methods
_.bindAll(this);
_.bindAll(this);
};
// Initialize and parse the book: config, summary, glossary
Book.prototype.parse = function() {
var that = this;
var multilingual = false;
var that = this;
var multilingual = false;
return this.parseConfig()
return this.parseConfig()
.then(function() {
return that.parsePlugins();
})
.then(function() {
return that.parsePlugins();
})
.then(function() {
return that.parseLangs()
.then(function() {
multilingual = that.langs.length > 0;
if (multilingual) that.log.info.ln("Parsing multilingual book, with", that.langs.length, "lanuages");
.then(function() {
return that.parseLangs()
.then(function() {
multilingual = that.langs.length > 0;
if (multilingual) that.log.info.ln("Parsing multilingual book, with", that.langs.length, "lanuages");
// Sub-books that inherit from the current book configuration
that.books = _.map(that.langs, function(lang) {
that.log.info.ln("Preparing language book", lang.lang);
return new Book(
path.join(that.root, lang.path),
_.merge({}, that.context, {
config: _.extend({}, that.options, {
'output': path.join(that.options.output, lang.lang),
'language': lang.lang
})
}),
that
)
});
});
})
// Sub-books that inherit from the current book configuration
that.books = _.map(that.langs, function(lang) {
that.log.info.ln("Preparing language book", lang.lang);
return new Book(
path.join(that.root, lang.path),
_.merge({}, that.context, {
config: _.extend({}, that.options, {
'output': path.join(that.options.output, lang.lang),
'language': lang.lang
})
}),
that
)
});
});
})
.then(function() {
if (multilingual) return;
return that.listAllFiles();
})
.then(function() {
if (multilingual) return;
return that.parseReadme();
})
.then(function() {
if (multilingual) return;
return that.parseSummary();
})
.then(function() {
if (multilingual) return;
return that.parseGlossary();
})
.then(function() {
if (multilingual) return;
return that.listAllFiles();
})
.then(function() {
if (multilingual) return;
return that.parseReadme();
})
.then(function() {
if (multilingual) return;
return that.parseSummary();
})
.then(function() {
if (multilingual) return;
return that.parseGlossary();
})
.then(function() {
// Init sub-books
return _.reduce(that.books, function(prev, book) {
return prev.then(function() {
return book.parse();
});
}, Q());
})
.then(function() {
// Init sub-books
return _.reduce(that.books, function(prev, book) {
return prev.then(function() {
return book.parse();
});
}, Q());
})
.thenResolve(this);
.thenResolve(this);
};
// Generate the output
Book.prototype.generate = function(generator) {
var that = this;
that.options.generator = generator || that.options.generator;
var that = this;
that.options.generator = generator || that.options.generator;
that.log.info.ln("start generation with", that.options.generator, "generator");
return Q()
that.log.info.ln("start generation with", that.options.generator, "generator");
return Q()
// Clean output folder
.then(function() {
// Clean output folder
.then(function() {
that.log.info("clean", that.options.generator, "generator");
return fs.clean(that.options.output)
return fs.clean(that.options.output)
.progress(function(p) {
that.log.debug.ln("remove", p.file, "("+p.i+"/"+p.count+")");
})
.then(function() {
that.log.info.ok();
});
})
})
// Create generator
.then(function() {
var Generator = generators[generator];
if (!Generator) throw "Generator '"+that.options.generator+"' doesn't exist";
generator = new Generator(that);
// Create generator
.then(function() {
var Generator = generators[generator];
if (!Generator) throw "Generator '"+that.options.generator+"' doesn't exist";
generator = new Generator(that);
return generator.prepare();
})
return generator.prepare();
})
// Generate content
.then(function() {
if (that.isMultilingual()) {
return that.generateMultiLingual(generator);
} else {
// Separate list of files into the different operations needed
var ops = _.groupBy(that.files, function(file) {
if (file[file.length -1] == "/") {
return "directories";
// Generate content
.then(function() {
if (that.isMultilingual()) {
return that.generateMultiLingual(generator);
} else {
// Separate list of files into the different operations needed
var ops = _.groupBy(that.files, function(file) {
if (file[file.length -1] == "/") {
return "directories";
} else if (_.contains(parsers.extensions, path.extname(file)) && that.navigation[file]) {
return "content";
return "content";
} else {
return "files";
return "files";
}
});
});
return Q()
return Q()
// First, let's create folder
.then(function() {
return _.reduce(ops["directories"] || [], function(prev, folder) {
return prev.then(function() {
that.log.debug.ln("transferring folder", folder);
return Q(generator.transferFolder(folder));
});
}, Q());
})
// First, let's create folder
.then(function() {
return _.reduce(ops["directories"] || [], function(prev, folder) {
return prev.then(function() {
that.log.debug.ln("transferring folder", folder);
return Q(generator.transferFolder(folder));
});
}, Q());
})
// Then, let's copy other files
.then(function() {
return Q.all(_.map(ops["files"] || [], function(file) {
that.log.debug.ln("transferring file", file);
// Then, let's copy other files
.then(function() {
return Q.all(_.map(ops["files"] || [], function(file) {
that.log.debug.ln("transferring file", file);
return Q(generator.transferFile(file));
}));
})
}));
})
// Finally let's generate content
.then(function() {
// Finally let's generate content
.then(function() {
var nFiles = (ops["content"] || []).length;
return _.reduce(ops["content"] || [], function(prev, file, i) {
return prev.then(function() {
return prev.then(function() {
var p = ((i*100)/nFiles).toFixed(0)+"%";
that.log.info.ln("processing", file, p);
return Q(generator.convertFile(file));
});
}, Q());
});
}
})
that.log.info.ln("processing", file, p);
return Q(generator.convertFile(file));
});
}, Q());
});
}
})
// Finish generation
// Finish generation
.then(function() {
return generator.callHook("finish:before");
})
@@ -248,28 +248,28 @@ Book.prototype.generate = function(generator) {
return generator.callHook("finish");
})
.then(function() {
that.log.info.ln("generation is finished");
that.log.info.ln("generation is finished");
});
};
// Generate the output for a multilingual book
Book.prototype.generateMultiLingual = function(generator) {
var that = this;
var that = this;
return Q()
.then(function() {
// Generate sub-books
return _.reduce(that.books, function(prev, book) {
return prev.then(function() {
return book.generate(that.options.generator);
});
}, Q());
});
return Q()
.then(function() {
// Generate sub-books
return _.reduce(that.books, function(prev, book) {
return prev.then(function() {
return book.generate(that.options.generator);
});
}, Q());
});
};
// Extract files from ebook generated
Book.prototype.generateFile = function(output, options) {
var book = this;
var book = this;
options = _.defaults(options || {}, {
ebookFormat: path.extname(output).slice(1)
@@ -278,7 +278,7 @@ Book.prototype.generateFile = function(output, options) {
return fs.tmp.dir()
.then(function(tmpDir) {
book.setOutput(tmpDir);
book.setOutput(tmpDir);
return book.generate(options.ebookFormat)
.then(function(_options) {
@@ -313,7 +313,7 @@ Book.prototype.generateFile = function(output, options) {
}
})
.then(function(n) {
book.log.info.ok(n+" file(s) generated");
book.log.info.ok(n+" file(s) generated");
return fs.remove(tmpDir);
});
@@ -323,147 +323,147 @@ Book.prototype.generateFile = function(output, options) {
// Parse configuration
Book.prototype.parseConfig = function() {
var that = this;
var that = this;
that.log.info("loading book configuration....")
return that.config.load()
.then(function() {
that.log.info.ok();
});
that.log.info("loading book configuration....")
return that.config.load()
.then(function() {
that.log.info.ok();
});
};
// Parse list of plugins
Book.prototype.parsePlugins = function() {
var that = this;
var failed = [];
var that = this;
var failed = [];
// Load plugins
return that.plugins.load(that.options.plugins)
.then(function() {
if (_.size(that.plugins.failed) > 0) return Q.reject(new Error("Error loading plugins: "+that.plugins.failed.join(",")+". Run 'gitbook install' to install plugins from NPM."));
if (_.size(that.plugins.failed) > 0) return Q.reject(new Error("Error loading plugins: "+that.plugins.failed.join(",")+". Run 'gitbook install' to install plugins from NPM."));
that.log.info.ok(that.plugins.count()+" plugins loaded");
that.log.debug.ln("normalize plugins list");
that.log.info.ok(that.plugins.count()+" plugins loaded");
that.log.debug.ln("normalize plugins list");
});
};
// Parse readme to extract defaults title and description
Book.prototype.parseReadme = function() {
var that = this;
var structure = that.config.getStructure("readme");
that.log.debug.ln("start parsing readme:", structure);
var that = this;
var structure = that.config.getStructure("readme");
that.log.debug.ln("start parsing readme:", structure);
return that.findFile(structure)
.then(function(readme) {
if (!readme) throw "No README file";
if (!_.contains(that.files, readme.path)) throw "README file is ignored";
return that.findFile(structure)
.then(function(readme) {
if (!readme) throw "No README file";
if (!_.contains(that.files, readme.path)) throw "README file is ignored";
that.readmeFile = readme.path;
that.readmeFile = readme.path;
that._defaultsStructure(that.readmeFile);
that.log.debug.ln("readme located at", that.readmeFile);
return that.template.renderFile(that.readmeFile)
.then(function(content) {
return readme.parser.readme(content);
});
})
.then(function(readme) {
that.options.title = that.options.title || readme.title;
that.options.description = that.options.description || readme.description;
});
that.log.debug.ln("readme located at", that.readmeFile);
return that.template.renderFile(that.readmeFile)
.then(function(content) {
return readme.parser.readme(content);
});
})
.then(function(readme) {
that.options.title = that.options.title || readme.title;
that.options.description = that.options.description || readme.description;
});
};
// Parse langs to extract list of sub-books
Book.prototype.parseLangs = function() {
var that = this;
var that = this;
var structure = that.config.getStructure("langs");
that.log.debug.ln("start parsing languages index:", structure);
var structure = that.config.getStructure("langs");
that.log.debug.ln("start parsing languages index:", structure);
return that.findFile(structure)
.then(function(langs) {
if (!langs) return [];
return that.findFile(structure)
.then(function(langs) {
if (!langs) return [];
that.langsFile = langs.path;
that._defaultsStructure(that.langsFile);
that.log.debug.ln("languages index located at", that.langsFile);
return that.template.renderFile(that.langsFile)
.then(function(content) {
return langs.parser.langs(content);
});
})
.then(function(langs) {
that.langs = langs;
});
that.log.debug.ln("languages index located at", that.langsFile);
return that.template.renderFile(that.langsFile)
.then(function(content) {
return langs.parser.langs(content);
});
})
.then(function(langs) {
that.langs = langs;
});
};
// Parse summary to extract list of chapters
Book.prototype.parseSummary = function() {
var that = this;
var that = this;
var structure = that.config.getStructure("summary");
that.log.debug.ln("start parsing summary:", structure);
var structure = that.config.getStructure("summary");
that.log.debug.ln("start parsing summary:", structure);
return that.findFile(structure)
.then(function(summary) {
if (!summary) throw "No SUMMARY file";
return that.findFile(structure)
.then(function(summary) {
if (!summary) throw "No SUMMARY file";
// Remove the summary from the list of files to parse
// Remove the summary from the list of files to parse
that.summaryFile = summary.path;
that._defaultsStructure(that.summaryFile);
that.files = _.without(that.files, that.summaryFile);
that.files = _.without(that.files, that.summaryFile);
that.log.debug.ln("summary located at", that.summaryFile);
return that.template.renderFile(that.summaryFile)
.then(function(content) {
return summary.parser.summary(content, {
entryPoint: that.readmeFile,
that.log.debug.ln("summary located at", that.summaryFile);
return that.template.renderFile(that.summaryFile)
.then(function(content) {
return summary.parser.summary(content, {
entryPoint: that.readmeFile,
entryPointTitle: "",
files: that.files
});
});
})
.then(function(summary) {
that.summary = summary;
that.navigation = parseNavigation(that.summary, that.files);
});
files: that.files
});
});
})
.then(function(summary) {
that.summary = summary;
that.navigation = parseNavigation(that.summary, that.files);
});
};
// Parse glossary to extract terms
Book.prototype.parseGlossary = function() {
var that = this;
var that = this;
var structure = that.config.getStructure("glossary");
that.log.debug.ln("start parsing glossary: ", structure);
var structure = that.config.getStructure("glossary");
that.log.debug.ln("start parsing glossary: ", structure);
return that.findFile(structure)
.then(function(glossary) {
if (!glossary) return [];
return that.findFile(structure)
.then(function(glossary) {
if (!glossary) return [];
// Remove the glossary from the list of files to parse
// Remove the glossary from the list of files to parse
that.glossaryFile = glossary.path;
that._defaultsStructure(that.glossaryFile);
that.files = _.without(that.files, that.glossaryFile);
that.files = _.without(that.files, that.glossaryFile);
that.log.debug.ln("glossary located at", that.glossaryFile);
return that.template.renderFile(that.glossaryFile)
.then(function(content) {
return glossary.parser.glossary(content);
});
})
.then(function(glossary) {
that.glossary = glossary;
});
that.log.debug.ln("glossary located at", that.glossaryFile);
return that.template.renderFile(that.glossaryFile)
.then(function(content) {
return glossary.parser.glossary(content);
});
})
.then(function(glossary) {
that.glossary = glossary;
});
};
// Parse a page
Book.prototype.parsePage = function(filename, options) {
var that = this, page = {};
var that = this, page = {};
options = _.defaults(options || {}, {
// Transform svg images
convertImages: false,
// Transform svg images
convertImages: false,
// Interpolate before templating
interpolateTemplate: _.identity,
@@ -479,12 +479,12 @@ Book.prototype.parsePage = function(filename, options) {
});
};
that.log.debug.ln("start parsing file", filename);
that.log.debug.ln("start parsing file", filename);
var extension = path.extname(filename);
var filetype = parsers.get(extension);
var extension = path.extname(filename);
var filetype = parsers.get(extension);
if (!filetype) return Q.reject(new Error("Can't parse file: "+filename));
if (!filetype) return Q.reject(new Error("Can't parse file: "+filename));
// Type of parser used
page.type = filetype.name;
@@ -498,7 +498,7 @@ Book.prototype.parsePage = function(filename, options) {
// Progress in the book
page.progress = parseProgress(that.navigation, filename);
that.log.debug.ln("render template", filename);
that.log.debug.ln("render template", filename);
// Read file content
return that.readFile(page.path)
@@ -531,88 +531,88 @@ Book.prototype.parsePage = function(filename, options) {
// Post process sections
.then(function(_page) {
return _.reduce(_page.sections, function(prev, section) {
return prev.then(function(_sections) {
return that.template.postProcess(section.content || "")
.then(function(content) {
section.content = content;
return _sections.concat([section]);
})
});
}, Q([]));
return _.reduce(_page.sections, function(prev, section) {
return prev.then(function(_sections) {
return that.template.postProcess(section.content || "")
.then(function(content) {
section.content = content;
return _sections.concat([section]);
})
});
}, Q([]));
})
// Prepare html
.then(function(_sections) {
return pageUtil.normalize(_sections, {
book: that,
convertImages: options.convertImages,
input: filename,
.then(function(_sections) {
return pageUtil.normalize(_sections, {
book: that,
convertImages: options.convertImages,
input: filename,
navigation: that.navigation,
base: path.dirname(filename) || './',
output: path.dirname(filename) || './',
glossary: that.glossary
});
})
})
// Interpolate output
.then(function(_sections) {
page.sections = _sections;
return interpolate(options.interpolateContent);
})
// Interpolate output
.then(function(_sections) {
page.sections = _sections;
return interpolate(options.interpolateContent);
})
.then(function() {
that.indexPage(page);
return page;
});
.then(function() {
that.indexPage(page);
return page;
});
};
// Find file that can be parsed with a specific filename
Book.prototype.findFile = function(filename) {
var that = this;
var that = this;
return _.reduce(parsers.extensions, function(prev, ext) {
return prev.then(function(output) {
// Stop if already find a parser
if (output) return output;
return _.reduce(parsers.extensions, function(prev, ext) {
return prev.then(function(output) {
// Stop if already find a parser
if (output) return output;
var filepath = filename+ext;
var filepath = filename+ext;
return that.fileExists(filepath)
.then(function(exists) {
if (!exists) return null;
return {
parser: parsers.get(ext),
path: filepath
};
})
});
}, Q(null));
return that.fileExists(filepath)
.then(function(exists) {
if (!exists) return null;
return {
parser: parsers.get(ext),
path: filepath
};
})
});
}, Q(null));
};
// Check if a file exists in the book
Book.prototype.fileExists = function(filename) {
return fs.exists(
path.join(this.root, filename)
);
return fs.exists(
path.join(this.root, filename)
);
};
// Read a file
Book.prototype.readFile = function(filename) {
return fs.readFile(
path.join(this.root, filename),
{ encoding: "utf8" }
);
return fs.readFile(
path.join(this.root, filename),
{ encoding: "utf8" }
);
};
// Return stat for a file
Book.prototype.statFile = function(filename) {
return fs.stat(path.join(this.root, filename));
return fs.stat(path.join(this.root, filename));
};
// List all files in the book
Book.prototype.listAllFiles = function() {
var that = this;
var that = this;
return fs.list(this.root, {
ignoreFiles: ['.ignore', '.gitignore', '.bookignore'],
@@ -646,18 +646,18 @@ Book.prototype.listAllFiles = function() {
// Return true if the book is a multilingual book
Book.prototype.isMultilingual = function(filename) {
return this.books.length > 0;
return this.books.length > 0;
};
// Return root of the parent
Book.prototype.parentRoot = function() {
if (this.parent) return this.parent.parentRoot();
return this.root;
if (this.parent) return this.parent.parentRoot();
return this.root;
};
// Return true if it's a sub-book
Book.prototype.isSubBook = function() {
return !!this.parent;
return !!this.parent;
};
// Test if the file is the entry point
@@ -685,11 +685,11 @@ Book.prototype.contentLink = function(link) {
// Index a page into the search index
Book.prototype.indexPage = function(page) {
var nav = this.navigation[page.path];
if (!nav) return;
var nav = this.navigation[page.path];
if (!nav) return;
this.log.debug.ln("index page", page.path);
this.searchIndex.add({
this.log.debug.ln("index page", page.path);
this.searchIndex.add({
url: this.contentLink(page.path),
title: nav.title,
body: pageUtil.extractText(page.sections),
@@ -709,12 +709,12 @@ Book.prototype._defaultsStructure = function(filename) {
// Change output path
Book.prototype.setOutput = function(p) {
var that = this;
this.options.output = path.resolve(p);
var that = this;
this.options.output = path.resolve(p);
_.each(this.books, function(book) {
book.setOutput(path.join(that.options.output, book.options.language));
});
_.each(this.books, function(book) {
book.setOutput(path.join(that.options.output, book.options.language));
});
};
+6 -6
View File
@@ -64,10 +64,10 @@ function normalizePluginsNames(plugins) {
var Configuration = function(book, options) {
var that = this;
this.book = book;
this.book = book;
this.options = _.cloneDeep(Configuration.DEFAULT);
this.options = _.merge(this.options, options || {});
this.options = _.merge(this.options, options || {});
// options.input == book.root
Object.defineProperty(this.options, "input", {
@@ -79,15 +79,15 @@ var Configuration = function(book, options) {
// Read and parse the configuration
Configuration.prototype.load = function() {
var that = this;
var that = this;
return Q()
return Q()
.then(function() {
try {
var _config = require(path.resolve(that.book.root, that.options.configFile));
that.options = _.merge(
that.options,
_.omit(_config, 'configFile', 'defaultsPlugins', 'generator', 'extension')
that.options,
_.omit(_config, 'configFile', 'defaultsPlugins', 'generator', 'extension')
);
}
catch(err) {
+1 -1
View File
@@ -30,7 +30,7 @@ Generator.prototype.prepareTemplates = function() {
this.templates["summary"] = this.book.plugins.template("ebook:summary") || path.resolve(this.options.theme, 'templates/ebook/summary.html');
this.templates["glossary"] = this.book.plugins.template("ebook:glossary") || path.resolve(this.options.theme, 'templates/ebook/glossary.html');
return Q();
return Q();
};
// Generate table of contents
+6 -6
View File
@@ -2,10 +2,10 @@ var _ = require("lodash");
var EbookGenerator = require("./ebook");
module.exports = {
json: require("./json"),
website: require("./website"),
ebook: EbookGenerator,
pdf: _.partialRight(EbookGenerator, "pdf"),
mobi: _.partialRight(EbookGenerator, "mobi"),
epub: _.partialRight(EbookGenerator, "epub")
json: require("./json"),
website: require("./website"),
ebook: EbookGenerator,
pdf: _.partialRight(EbookGenerator, "pdf"),
mobi: _.partialRight(EbookGenerator, "mobi"),
epub: _.partialRight(EbookGenerator, "epub")
};
+18 -18
View File
@@ -64,11 +64,11 @@ Generator.prototype.prepareStyles = function() {
// Prepare templates
Generator.prototype.prepareTemplates = function() {
this.templates["page"] = this.book.plugins.template("site:page") || path.resolve(this.options.theme, 'templates/website/page.html');
this.templates["page"] = this.book.plugins.template("site:page") || path.resolve(this.options.theme, 'templates/website/page.html');
this.templates["langs"] = this.book.plugins.template("site:langs") || path.resolve(this.options.theme, 'templates/website/langs.html');
this.templates["glossary"] = this.book.plugins.template("site:glossary") || path.resolve(this.options.theme, 'templates/website/glossary.html');
return Q();
return Q();
};
// Prepare template engine
@@ -213,38 +213,38 @@ Generator.prototype._writeTemplate = function(tpl, options, output, interpolate)
interpolate = interpolate || _.identity;
return Q()
.then(function(sections) {
return that.env.render(
tpl,
_.extend({
return that.env.render(
tpl,
_.extend({
gitbook: {
version: pkg.version
},
styles: that.styles,
styles: that.styles,
revision: that.revision,
revision: that.revision,
title: that.options.title,
description: that.options.description,
title: that.options.title,
description: that.options.description,
language: that.book.config.normalizeLanguage(),
glossary: that.book.glossary,
glossary: that.book.glossary,
summary: that.book.summary,
allNavigation: that.book.navigation,
summary: that.book.summary,
allNavigation: that.book.navigation,
plugins: {
plugins: {
resources: that.book.plugins.resources(that.namespace)
},
pluginsConfig: JSON.stringify(that.options.pluginsConfig),
htmlSnippet: _.partial(_.partialRight(that.book.plugins.html, that, options), that.namespace),
pluginsConfig: JSON.stringify(that.options.pluginsConfig),
htmlSnippet: _.partial(_.partialRight(that.book.plugins.html, that, options), that.namespace),
options: that.options,
options: that.options,
basePath: ".",
staticBase: path.join(".", "gitbook"),
}, options)
);
}, options)
);
})
.then(interpolate)
.then(function(html) {
+170 -170
View File
@@ -12,199 +12,199 @@ var watch = require("./utils/watch");
var logger = require("./utils/logger");
var LOG_OPTION = {
name: "log",
description: "Minimum log level to display",
values: _.chain(logger.LEVELS).keys().map(stringUtils.toLowerCase).value(),
defaults: "info"
name: "log",
description: "Minimum log level to display",
values: _.chain(logger.LEVELS).keys().map(stringUtils.toLowerCase).value(),
defaults: "info"
};
var FORMAT_OPTION = {
name: "format",
description: "Format to build to",
values: ["website", "json", "ebook"],
defaults: "website"
name: "format",
description: "Format to build to",
values: ["website", "json", "ebook"],
defaults: "website"
};
module.exports = {
Book: Book,
LOG_LEVELS: logger.LEVELS,
Book: Book,
LOG_LEVELS: logger.LEVELS,
commands: _.flatten([
{
name: "build [book] [output]",
description: "build a book",
options: [
FORMAT_OPTION,
LOG_OPTION
],
exec: function(args, kwargs) {
var input = args[0] || process.cwd();
var output = args[1] || path.join(input, "_book");
commands: _.flatten([
{
name: "build [book] [output]",
description: "build a book",
options: [
FORMAT_OPTION,
LOG_OPTION
],
exec: function(args, kwargs) {
var input = args[0] || process.cwd();
var output = args[1] || path.join(input, "_book");
var book = new Book(input, _.extend({}, {
'config': {
'output': output
},
'logLevel': kwargs.log
}));
var book = new Book(input, _.extend({}, {
'config': {
'output': output
},
'logLevel': kwargs.log
}));
return book.parse()
.then(function() {
return book.generate(kwargs.format);
})
.then(function(){
console.log("");
console.log(color.green("Done, without error"));
});
}
},
return book.parse()
.then(function() {
return book.generate(kwargs.format);
})
.then(function(){
console.log("");
console.log(color.green("Done, without error"));
});
}
},
_.map(["pdf", "epub", "mobi"], function(ebookType) {
return {
name: ebookType+" [book] [output]",
description: "build a book to "+ebookType,
options: [
LOG_OPTION
],
exec: function(args, kwargs) {
var input = args[0] || process.cwd();
var output = args[1];
_.map(["pdf", "epub", "mobi"], function(ebookType) {
return {
name: ebookType+" [book] [output]",
description: "build a book to "+ebookType,
options: [
LOG_OPTION
],
exec: function(args, kwargs) {
var input = args[0] || process.cwd();
var output = args[1];
var book = new Book(input, _.extend({}, {
'logLevel': kwargs.log
}));
var book = new Book(input, _.extend({}, {
'logLevel': kwargs.log
}));
return book.parse()
.then(function() {
return book.generateFile(output, {
ebookFormat: ebookType
});
})
.then(function(){
console.log("");
console.log(color.green("Done, without error"));
});
}
};
}),
return book.parse()
.then(function() {
return book.generateFile(output, {
ebookFormat: ebookType
});
})
.then(function(){
console.log("");
console.log(color.green("Done, without error"));
});
}
};
}),
{
name: "serve [book]",
description: "Build then serve a gitbook from a directory",
options: [
{
name: "port",
description: "Port for server to listen on",
defaults: 4000
},
{
name: "lrport",
description: "Port for livereload server to listen on",
defaults: 35729
},
{
name: "watch",
description: "Enable/disable file watcher",
defaults: true
},
FORMAT_OPTION,
LOG_OPTION
],
exec: function(args, kwargs) {
var input = args[0] || process.cwd();
var server = new Server();
{
name: "serve [book]",
description: "Build then serve a gitbook from a directory",
options: [
{
name: "port",
description: "Port for server to listen on",
defaults: 4000
},
{
name: "lrport",
description: "Port for livereload server to listen on",
defaults: 35729
},
{
name: "watch",
description: "Enable/disable file watcher",
defaults: true
},
FORMAT_OPTION,
LOG_OPTION
],
exec: function(args, kwargs) {
var input = args[0] || process.cwd();
var server = new Server();
// Init livereload server
var lrServer = tinylr({});
var lrPath = undefined;
// Init livereload server
var lrServer = tinylr({});
var lrPath = undefined;
var generate = function() {
if (server.isRunning()) console.log("Stopping server");
var generate = function() {
if (server.isRunning()) console.log("Stopping server");
return server.stop()
.then(function() {
var book = new Book(input, _.extend({}, {
'config': {
'defaultsPlugins': ["livereload"]
},
'logLevel': kwargs.log
}));
return server.stop()
.then(function() {
var book = new Book(input, _.extend({}, {
'config': {
'defaultsPlugins': ["livereload"]
},
'logLevel': kwargs.log
}));
return book.parse()
.then(function() {
return book.generate(kwargs.format);
})
.thenResolve(book);
})
.then(function(book) {
console.log();
console.log('Starting server ...');
return server.start(book.options.output, kwargs.port)
.then(function() {
console.log('Serving book on http://localhost:'+kwargs.port);
return book.parse()
.then(function() {
return book.generate(kwargs.format);
})
.thenResolve(book);
})
.then(function(book) {
console.log();
console.log('Starting server ...');
return server.start(book.options.output, kwargs.port)
.then(function() {
console.log('Serving book on http://localhost:'+kwargs.port);
if (lrPath) {
// trigger livereload
lrServer.changed({
body: {
files: [lrPath]
}
});
}
if (lrPath) {
// trigger livereload
lrServer.changed({
body: {
files: [lrPath]
}
});
}
if (!kwargs.watch) return;
if (!kwargs.watch) return;
return watch(book.root)
.then(function(filepath) {
// set livereload path
lrPath = filepath;
console.log("Restart after change in files");
console.log('');
return generate();
})
})
});
};
return watch(book.root)
.then(function(filepath) {
// set livereload path
lrPath = filepath;
console.log("Restart after change in files");
console.log('');
return generate();
})
})
});
};
return Q.nfcall(lrServer.listen.bind(lrServer), kwargs.lrport)
.then(function() {
console.log('Live reload server started on port:', kwargs.lrport);
console.log('Press CTRL+C to quit ...');
console.log('')
return generate();
});
}
},
return Q.nfcall(lrServer.listen.bind(lrServer), kwargs.lrport)
.then(function() {
console.log('Live reload server started on port:', kwargs.lrport);
console.log('Press CTRL+C to quit ...');
console.log('')
return generate();
});
}
},
{
name: "install [book]",
description: "install plugins dependencies",
exec: function(args, kwargs) {
var input = args[0] || process.cwd();
{
name: "install [book]",
description: "install plugins dependencies",
exec: function(args, kwargs) {
var input = args[0] || process.cwd();
var book = new Book(input);
var book = new Book(input);
return book.config.load()
.then(function() {
return book.plugins.install();
})
.then(function(){
console.log("");
console.log(color.green("Done, without error"));
});
}
},
return book.config.load()
.then(function() {
return book.plugins.install();
})
.then(function(){
console.log("");
console.log(color.green("Done, without error"));
});
}
},
{
name: "init [directory]",
description: "create files and folders based on contents of SUMMARY.md",
exec: function(args, kwargs) {
return Book.init(args[0] || process.cwd())
.then(function(){
console.log("");
console.log(color.green("Done, without error"));
});
}
}
])
{
name: "init [directory]",
description: "create files and folders based on contents of SUMMARY.md",
exec: function(args, kwargs) {
return Book.init(args[0] || process.cwd())
.then(function(){
console.log("");
console.log(color.green("Done, without error"));
});
}
}
])
};
+114 -114
View File
@@ -8,113 +8,113 @@ var Plugin = require("./plugin");
var pkg = require("../package.json");
var initNPM = _.memoize(function() {
return Q.nfcall(npm.load, { silent: true, loglevel: 'silent' });
return Q.nfcall(npm.load, { silent: true, loglevel: 'silent' });
});
var PluginsList = function(book, plugins) {
this.book = book;
this.log = this.book.log;
this.book = book;
this.log = this.book.log;
// List of Plugin objects
this.list = [];
// List of Plugin objects
this.list = [];
// List of names of failed plugins
this.failed = [];
// List of names of failed plugins
this.failed = [];
// Namespaces
this.namespaces = _.chain(["website", "ebook"])
.map(function(namespace) {
return [
namespace,
{
html: {},
resources: _.chain(Plugin.RESOURCES)
.map(function(type) {
return [type, []];
})
.object()
.value()
}
];
})
.object()
.value();
// Namespaces
this.namespaces = _.chain(["website", "ebook"])
.map(function(namespace) {
return [
namespace,
{
html: {},
resources: _.chain(Plugin.RESOURCES)
.map(function(type) {
return [type, []];
})
.object()
.value()
}
];
})
.object()
.value();
// Bind methods
_.bindAll(this);
// Bind methods
_.bindAll(this);
if (plugins) this.load(plugins);
if (plugins) this.load(plugins);
};
// return count of plugins
PluginsList.prototype.count = function() {
return this.list.length;
return this.list.length;
};
// Add and load a plugin
PluginsList.prototype.load = function(plugin, options) {
var that = this;
var that = this;
if (_.isArray(plugin)) {
return _.reduce(plugin, function(prev, p) {
return prev.then(function() {
return that.load(p);
});
}, Q());
}
if (_.isObject(plugin) && !(plugin instanceof Plugin)) plugin = plugin.name;
if (_.isString(plugin)) plugin = new Plugin(this.book, plugin);
if (_.isArray(plugin)) {
return _.reduce(plugin, function(prev, p) {
return prev.then(function() {
return that.load(p);
});
}, Q());
}
if (_.isObject(plugin) && !(plugin instanceof Plugin)) plugin = plugin.name;
if (_.isString(plugin)) plugin = new Plugin(this.book, plugin);
that.log.info("load plugin", plugin.name, "....");
if (!plugin.isValid()) {
that.log.info.fail();
that.failed.push(plugin.name);
return Q();
that.log.info("load plugin", plugin.name, "....");
if (!plugin.isValid()) {
that.log.info.fail();
that.failed.push(plugin.name);
return Q();
} else {
that.log.info.ok();
that.log.info.ok();
// Push in the list
that.list.push(plugin);
// Push in the list
that.list.push(plugin);
}
// Extract filters
_.each(plugin.getFilters(), function(filterFunc, filterName) {
// Extract filters
_.each(plugin.getFilters(), function(filterFunc, filterName) {
that.book.template.addFilter(filterName, filterFunc);
});
// Extract blocks
_.each(plugin.getBlocks(), function(block, blockName) {
_.each(plugin.getBlocks(), function(block, blockName) {
that.book.template.addBlock(blockName, block);
});
return _.reduce(_.keys(that.namespaces), function(prev, namespaceName) {
return prev.then(function() {
return plugin.getResources(namespaceName)
.then(function(plResources) {
var namespace = that.namespaces[namespaceName];
return _.reduce(_.keys(that.namespaces), function(prev, namespaceName) {
return prev.then(function() {
return plugin.getResources(namespaceName)
.then(function(plResources) {
var namespace = that.namespaces[namespaceName];
// Extract js and css
_.each(Plugin.RESOURCES, function(resourceType) {
namespace.resources[resourceType] = (namespace.resources[resourceType] || []).concat(plResources[resourceType] || []);
});
// Extract js and css
_.each(Plugin.RESOURCES, function(resourceType) {
namespace.resources[resourceType] = (namespace.resources[resourceType] || []).concat(plResources[resourceType] || []);
});
// Map of html resources by name added by each plugin
_.each(plResources.html || {}, function(value, tag) {
// Turn into function if not one already
if (!_.isFunction(value)) value = _.constant(value);
// Map of html resources by name added by each plugin
_.each(plResources.html || {}, function(value, tag) {
// Turn into function if not one already
if (!_.isFunction(value)) value = _.constant(value);
namespace.html[tag] = namespace.html[tag] || [];
namespace.html[tag].push(value);
});
})
});
}, Q());
namespace.html[tag] = namespace.html[tag] || [];
namespace.html[tag].push(value);
});
})
});
}, Q());
};
// Call a hook
PluginsList.prototype.hook = function(name, data) {
return _.reduce(this.list, function(prev, plugin) {
return _.reduce(this.list, function(prev, plugin) {
return prev.then(function(ret) {
return plugin.callHook(name, ret);
});
@@ -123,7 +123,7 @@ PluginsList.prototype.hook = function(name, data) {
// Return a template from a plugin
PluginsList.prototype.template = function(name) {
var withTpl = _.find(this.list, function(plugin) {
var withTpl = _.find(this.list, function(plugin) {
return (
plugin.infos.templates &&
plugin.infos.templates[name]
@@ -136,7 +136,7 @@ PluginsList.prototype.template = function(name) {
// Return an html snippet
PluginsList.prototype.html = function(namespace, tag, context, options) {
var htmlSnippets = this.namespaces[namespace].html[tag];
var htmlSnippets = this.namespaces[namespace].html[tag];
return _.map(htmlSnippets || [], function(code) {
return code.call(context, options);
}).join("\n");
@@ -144,13 +144,13 @@ PluginsList.prototype.html = function(namespace, tag, context, options) {
// Return a resources map for a namespace
PluginsList.prototype.resources = function(namespace) {
return this.namespaces[namespace].resources;
return this.namespaces[namespace].resources;
};
// Install plugins from a book
PluginsList.prototype.install = function() {
var that = this;
var defaultsPlugins = _.pluck(that.book.options.defaultsPlugins)
var that = this;
var defaultsPlugins = _.pluck(that.book.options.defaultsPlugins)
// Remove defaults (no need to install)
var plugins = _.filter(that.book.options.plugins, function(plugin) {
@@ -167,51 +167,51 @@ PluginsList.prototype.install = function() {
// Resolve version if needed
.then(function() {
if (plugin.version) return plugin.version;
if (plugin.version) return plugin.version;
that.book.log.info.ln("No version specified, resolve plugin", plugin.name);
return initNPM()
.then(function() {
return Q.nfcall(npm.commands.view, [fullname+"@*", "engines"], true);
})
.then(function(versions) {
return _.chain(versions)
.pairs()
.map(function(v) {
return {
version: v[0],
gitbook: (v[1].engines || {})["gitbook"]
}
})
.filter(function(v) {
return v.gitbook && semver.satisfies(pkg.version, v.gitbook);
})
.sort(function(v1, v2) {
return semver.lt(v1.version, v2.version)? 1 : -1;
})
.pluck("version")
.first()
.value();
});
that.book.log.info.ln("No version specified, resolve plugin", plugin.name);
return initNPM()
.then(function() {
return Q.nfcall(npm.commands.view, [fullname+"@*", "engines"], true);
})
.then(function(versions) {
return _.chain(versions)
.pairs()
.map(function(v) {
return {
version: v[0],
gitbook: (v[1].engines || {})["gitbook"]
}
})
.filter(function(v) {
return v.gitbook && semver.satisfies(pkg.version, v.gitbook);
})
.sort(function(v1, v2) {
return semver.lt(v1.version, v2.version)? 1 : -1;
})
.pluck("version")
.first()
.value();
});
})
// Install the plugin with the resolved version
.then(function(version) {
if (!version) {
throw "Found no satisfactory version for plugin "+plugin.name;
}
if (!version) {
throw "Found no satisfactory version for plugin "+plugin.name;
}
that.book.log.info.ln("install plugin", plugin.name, "from npm ("+fullname+") with version", version);
return Q.nfcall(npmi, {
'name': fullname,
'version': version,
'path': that.book.root,
'npmLoad': {
'loglevel': 'silent',
'loaded': true,
'prefix': that.book.root
}
});
that.book.log.info.ln("install plugin", plugin.name, "from npm ("+fullname+") with version", version);
return Q.nfcall(npmi, {
'name': fullname,
'version': version,
'path': that.book.root,
'npmLoad': {
'loglevel': 'silent',
'loaded': true,
'prefix': that.book.root
}
});
})
.then(function() {
that.book.log.info.ok("plugin", plugin.name, "installed with success");
+37 -37
View File
@@ -12,31 +12,31 @@ var pkg = require("../package.json");
// The loader should handle relative and git url
var BookLoader = nunjucks.Loader.extend({
async: true,
async: true,
init: function(book) {
this.book = book;
this.book = book;
},
getSource: function(fileurl, callback) {
var that = this;
var that = this;
git.resolveFile(fileurl)
.then(function(filepath) {
// Is local file
if (!filepath) filepath = path.resolve(that.book.root, fileurl);
else that.book.log.debug.ln("resolve from git", fileurl, "to", filepath)
git.resolveFile(fileurl)
.then(function(filepath) {
// Is local file
if (!filepath) filepath = path.resolve(that.book.root, fileurl);
else that.book.log.debug.ln("resolve from git", fileurl, "to", filepath)
// Read file from absolute path
return fs.readFile(filepath)
.then(function(source) {
return {
src: source.toString(),
path: filepath
}
});
})
.nodeify(callback);
// Read file from absolute path
return fs.readFile(filepath)
.then(function(source) {
return {
src: source.toString(),
path: filepath
}
});
})
.nodeify(callback);
},
resolve: function(from, to) {
@@ -46,27 +46,27 @@ var BookLoader = nunjucks.Loader.extend({
var TemplateEngine = function(book) {
this.book = book;
this.book = book;
this.log = this.book.log;
// Nunjucks env
this.env = new nunjucks.Environment(
new BookLoader(book),
{
// Escaping is done after by the markdown parser
autoescape: false,
// Nunjucks env
this.env = new nunjucks.Environment(
new BookLoader(book),
{
// Escaping is done after by the markdown parser
autoescape: false,
// Tags
tags: {
blockStart: '{%',
blockEnd: '%}',
variableStart: '{{',
variableEnd: '}}',
commentStart: '{###',
commentEnd: '###}'
}
}
);
// Tags
tags: {
blockStart: '{%',
blockEnd: '%}',
variableStart: '{{',
variableEnd: '}}',
commentStart: '{###',
commentEnd: '###}'
}
}
);
// List of tags shortcuts
this.shortcuts = [];
@@ -336,7 +336,7 @@ TemplateEngine.prototype.renderString = function(content, context, options) {
// Render a file from the book
TemplateEngine.prototype.renderFile = function(filename, options) {
var that = this, context;
var that = this, context;
return that.book.readFile(filename)
.then(function(content) {
+58 -58
View File
@@ -15,7 +15,7 @@ var GIT_TMP = null;
// Check if an url is a git dependency url
function checkGitUrl(giturl) {
return (giturl.indexOf(GIT_PREFIX) === 0);
return (giturl.indexOf(GIT_PREFIX) === 0);
}
// Validates a SHA in hexadecimal
@@ -25,88 +25,88 @@ function validateSha(str) {
// Parse and extract infos
function parseGitUrl(giturl) {
var ref, uri, fileParts, filepath;
var ref, uri, fileParts, filepath;
if (!checkGitUrl(giturl)) return null;
giturl = giturl.slice(GIT_PREFIX.length);
if (!checkGitUrl(giturl)) return null;
giturl = giturl.slice(GIT_PREFIX.length);
uri = new URI(giturl);
ref = uri.fragment() || "master";
uri.fragment(null);
uri = new URI(giturl);
ref = uri.fragment() || "master";
uri.fragment(null);
// Extract file inside the repo (after the .git)
fileParts =uri.path().split(".git");
filepath = fileParts.length > 1? fileParts.slice(1).join(".git") : "";
if (filepath[0] == "/") filepath = filepath.slice(1);
// Extract file inside the repo (after the .git)
fileParts =uri.path().split(".git");
filepath = fileParts.length > 1? fileParts.slice(1).join(".git") : "";
if (filepath[0] == "/") filepath = filepath.slice(1);
// Recreate pathname without the real filename
uri.path(_.first(fileParts)+".git");
// Recreate pathname without the real filename
uri.path(_.first(fileParts)+".git");
return {
host: uri.toString(),
ref: ref || "master",
filepath: filepath
};
return {
host: uri.toString(),
ref: ref || "master",
filepath: filepath
};
}
// Clone a git repo from a specific ref
function cloneGitRepo(host, ref) {
var isBranch = false;
var isBranch = false;
ref = ref || "master";
if (!validateSha(ref)) isBranch = true;
ref = ref || "master";
if (!validateSha(ref)) isBranch = true;
return Q()
return Q()
// Create temporary folder to store git repos
.then(function() {
if (GIT_TMP) return;
return fs.tmp.dir()
.then(function(_tmp) {
GIT_TMP = _tmp;
});
})
// Create temporary folder to store git repos
.then(function() {
if (GIT_TMP) return;
return fs.tmp.dir()
.then(function(_tmp) {
GIT_TMP = _tmp;
});
})
// Return or clone the git repo
.then(function() {
// Unique ID for repo/ref combinaison
var repoId = crc.crc32(host+"#"+ref).toString(16);
// Return or clone the git repo
.then(function() {
// Unique ID for repo/ref combinaison
var repoId = crc.crc32(host+"#"+ref).toString(16);
// Absolute path to the folder
var repoPath = path.resolve(GIT_TMP, repoId);
// Absolute path to the folder
var repoPath = path.resolve(GIT_TMP, repoId);
return fs.exists(repoPath)
.then(function(doExists) {
if (doExists) return;
return fs.exists(repoPath)
.then(function(doExists) {
if (doExists) return;
// Clone repo
return exec("git clone "+host+" "+repoPath)
.then(function() {
return exec("git checkout "+ref, { cwd: repoPath });
})
})
.thenResolve(repoPath);
});
// Clone repo
return exec("git clone "+host+" "+repoPath)
.then(function() {
return exec("git checkout "+ref, { cwd: repoPath });
})
})
.thenResolve(repoPath);
});
}
// Get file from a git repo
function resolveFileFromGit(giturl) {
if (_.isString(giturl)) giturl = parseGitUrl(giturl);
if (!giturl) return Q(null);
if (_.isString(giturl)) giturl = parseGitUrl(giturl);
if (!giturl) return Q(null);
// Clone or get from cache
return cloneGitRepo(giturl.host, giturl.ref)
.then(function(repo) {
// Clone or get from cache
return cloneGitRepo(giturl.host, giturl.ref)
.then(function(repo) {
// Resolve relative path
return path.resolve(repo, giturl.filepath);
});
// Resolve relative path
return path.resolve(repo, giturl.filepath);
});
};
module.exports = {
checkUrl: checkGitUrl,
parseUrl: parseGitUrl,
resolveFile: resolveFileFromGit
checkUrl: checkGitUrl,
parseUrl: parseGitUrl,
resolveFile: resolveFileFromGit
};
+38 -38
View File
@@ -5,14 +5,14 @@ var fs = require("fs");
var I18N_PATH = path.resolve(__dirname, "../../theme/i18n/")
var getLocales = _.memoize(function() {
var locales = fs.readdirSync(I18N_PATH);
return _.chain(locales)
var locales = fs.readdirSync(I18N_PATH);
return _.chain(locales)
.map(function(local) {
local = path.basename(local, ".json");
return [local, _.extend({
direction: "ltr"
direction: "ltr"
}, require(path.join(I18N_PATH, local)), {
id: local
id: local
})];
})
.object()
@@ -20,53 +20,53 @@ var getLocales = _.memoize(function() {
});
var getLanguages = function() {
return _.keys(getLocales());
return _.keys(getLocales());
};
var getByLanguage = function(lang) {
lang = normalizeLanguage(lang);
var locales = getLocales();
return locales[lang];
lang = normalizeLanguage(lang);
var locales = getLocales();
return locales[lang];
};
var compareLocales = function(lang, locale) {
var langMain = _.first(lang.split("-"));
var langSecond = _.last(lang.split("-"));
var langMain = _.first(lang.split("-"));
var langSecond = _.last(lang.split("-"));
var localeMain = _.first(locale.split("-"));
var localeSecond = _.last(locale.split("-"));
var localeMain = _.first(locale.split("-"));
var localeSecond = _.last(locale.split("-"));
if (locale == lang) return 100;
if (localeMain == langMain) return 50;
if (localeSecond == langSecond) return 20;
return 0;
if (locale == lang) return 100;
if (localeMain == langMain) return 50;
if (localeSecond == langSecond) return 20;
return 0;
};
var normalizeLanguage = _.memoize(function(lang) {
var locales = getLocales();
var language = _.chain(locales)
.values()
.map(function(locale) {
locale = locale.id;
var locales = getLocales();
var language = _.chain(locales)
.values()
.map(function(locale) {
locale = locale.id;
return {
locale: locale,
score: compareLocales(lang, locale)
}
})
.filter(function(lang) {
return lang.score > 0;
})
.sortBy("score")
.pluck("locale")
.last()
.value();
return language || lang;
return {
locale: locale,
score: compareLocales(lang, locale)
}
})
.filter(function(lang) {
return lang.score > 0;
})
.sortBy("score")
.pluck("locale")
.last()
.value();
return language || lang;
});
module.exports = {
getLocales: getLocales,
getLanguages: getLanguages,
getByLanguage: getByLanguage,
normalizeLanguage: normalizeLanguage
getLocales: getLocales,
getLanguages: getLanguages,
getByLanguage: getByLanguage,
normalizeLanguage: normalizeLanguage
};
+8 -8
View File
@@ -7,14 +7,14 @@ var links = require("./links");
// Convert a svg file
var convertSVG = function(source, dest, options) {
if (!fs.existsSync(source)) return Q.reject(new Error("File doesn't exist: "+source));
var d = Q.defer();
if (!fs.existsSync(source)) return Q.reject(new Error("File doesn't exist: "+source));
var d = Q.defer();
options = _.defaults(options || {}, {
options = _.defaults(options || {}, {
});
});
//var command = shellescape(['svgexport', source, dest]);
//var command = shellescape(['svgexport', source, dest]);
var child = spawn('svgexport', [source, dest]);
child.on("error", function(error) {
@@ -30,10 +30,10 @@ var convertSVG = function(source, dest, options) {
}
});
return d.promise;
return d.promise;
};
module.exports = {
convertSVG: convertSVG,
INVALID: [".svg"]
convertSVG: convertSVG,
INVALID: [".svg"]
};
+75 -75
View File
@@ -3,100 +3,100 @@ var util = require('util');
var color = require('bash-color');
var LEVELS = {
DEBUG: 0,
INFO: 1,
WARN: 2,
ERROR: 3,
DISABLED: 10
DEBUG: 0,
INFO: 1,
WARN: 2,
ERROR: 3,
DISABLED: 10
};
var COLORS = {
DEBUG: color.purple,
INFO: color.cyan,
WARN: color.yellow,
ERROR: color.red
DEBUG: color.purple,
INFO: color.cyan,
WARN: color.yellow,
ERROR: color.red
};
module.exports = function(_write, logLevel) {
var logger = {};
var lastChar = '\n';
if (_.isString(logLevel)) logLevel = LEVELS[logLevel.toUpperCase()];
var logger = {};
var lastChar = '\n';
if (_.isString(logLevel)) logLevel = LEVELS[logLevel.toUpperCase()];
// Write a simple message
logger.write = function(msg) {
msg = msg.toString();
lastChar = _.last(msg);
return _write(msg);
};
// Write a simple message
logger.write = function(msg) {
msg = msg.toString();
lastChar = _.last(msg);
return _write(msg);
};
// Format a message
logger.format = function() {
return util.format.apply(util, arguments);
};
// Format a message
logger.format = function() {
return util.format.apply(util, arguments);
};
// Write a line
logger.writeLn = function(msg) {
return this.write((msg || "")+"\n");
};
// Write a line
logger.writeLn = function(msg) {
return this.write((msg || "")+"\n");
};
// Write a message with a certain level
logger.log = function(level) {
if (level < logLevel) return;
// Write a message with a certain level
logger.log = function(level) {
if (level < logLevel) return;
var levelKey = _.findKey(LEVELS, function(v) { return v == level; });
var args = Array.prototype.slice.apply(arguments, [1]);
var msg = logger.format.apply(logger, args);
var levelKey = _.findKey(LEVELS, function(v) { return v == level; });
var args = Array.prototype.slice.apply(arguments, [1]);
var msg = logger.format.apply(logger, args);
if (lastChar == '\n') {
msg = COLORS[levelKey](levelKey.toLowerCase()+":")+" "+msg;
}
if (lastChar == '\n') {
msg = COLORS[levelKey](levelKey.toLowerCase()+":")+" "+msg;
}
return logger.write(msg);
};
logger.logLn = function() {
if (lastChar != '\n') logger.write("\n");
return logger.write(msg);
};
logger.logLn = function() {
if (lastChar != '\n') logger.write("\n");
var args = Array.prototype.slice.apply(arguments);
args.push("\n");
logger.log.apply(logger, args);
};
var args = Array.prototype.slice.apply(arguments);
args.push("\n");
logger.log.apply(logger, args);
};
// Write a OK
logger.ok = function(level) {
var args = Array.prototype.slice.apply(arguments, [1]);
var msg = logger.format.apply(logger, args);
if (arguments.length > 1) {
logger.logLn(level, color.green('>> ') + msg.trim().replace(/\n/g, color.green('\n>> ')));
} else {
logger.log(level, color.green("OK"), "\n");
}
};
// Write a OK
logger.ok = function(level) {
var args = Array.prototype.slice.apply(arguments, [1]);
var msg = logger.format.apply(logger, args);
if (arguments.length > 1) {
logger.logLn(level, color.green('>> ') + msg.trim().replace(/\n/g, color.green('\n>> ')));
} else {
logger.log(level, color.green("OK"), "\n");
}
};
// Write an "FAIL"
logger.fail = function(level) {
return logger.log(level, color.red("ERROR")+"\n");
};
// Write an "FAIL"
logger.fail = function(level) {
return logger.log(level, color.red("ERROR")+"\n");
};
_.each(_.omit(LEVELS, 'DISABLED'), function(level, levelKey) {
levelKey = levelKey.toLowerCase();
_.each(_.omit(LEVELS, 'DISABLED'), function(level, levelKey) {
levelKey = levelKey.toLowerCase();
logger[levelKey] = _.partial(logger.log, level);
logger[levelKey].ln = _.partial(logger.logLn, level);
logger[levelKey].ok = _.partial(logger.ok, level);
logger[levelKey].fail = _.partial(logger.fail, level);
logger[levelKey].promise = function(p) {
return p.
then(function(st) {
logger[levelKey].ok();
return st;
}, function(err) {
logger[levelKey].fail();
throw err;
});
}
});
logger[levelKey] = _.partial(logger.log, level);
logger[levelKey].ln = _.partial(logger.logLn, level);
logger[levelKey].ok = _.partial(logger.ok, level);
logger[levelKey].fail = _.partial(logger.fail, level);
logger[levelKey].promise = function(p) {
return p.
then(function(st) {
logger[levelKey].ok();
return st;
}, function(err) {
logger[levelKey].fail();
throw err;
});
}
});
return logger;
return logger;
};
module.exports.LEVELS = LEVELS;
module.exports.COLORS = COLORS;
+1 -1
View File
@@ -1,3 +1,3 @@
{
"title": "Test"
"title": "Test"
}
+1 -1
View File
@@ -1,3 +1,3 @@
body {
background: red;
background: red;
}
+3 -3
View File
@@ -1,5 +1,5 @@
{
"structure": {
"readme": "intro.md"
}
"structure": {
"readme": "intro.md"
}
}
+1 -1
View File
@@ -1,3 +1,3 @@
module.exports = {
title: "Test 2"
title: "Test 2"
};
+6 -6
View File
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
<svg version="1.1" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="svg-root" width="100%" height="100%" viewBox="0 0 480 360">
<title id="test-title">basic SVG tiny doc</title>
<g id="test-body-content">
<text font-family="Arial" font-size="14" text-anchor="middle" x="225" y="25">hello world</text>
</g>
<text id="revision" x="10" y="340" font-size="40" stroke="none" fill="black">Revision: 1.1</text>
<rect id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000000"/>
<title id="test-title">basic SVG tiny doc</title>
<g id="test-body-content">
<text font-family="Arial" font-size="14" text-anchor="middle" x="225" y="25">hello world</text>
</g>
<text id="revision" x="10" y="340" font-size="40" stroke="none" fill="black">Revision: 1.1</text>
<rect id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000000"/>
</svg>

Before

Width:  |  Height:  |  Size: 709 B

After

Width:  |  Height:  |  Size: 730 B

+3 -3
View File
@@ -49,7 +49,7 @@ global.books = _.chain(books)
before(function(done) {
qdone(
_.reduce(global.books, function(prev, book) {
_.reduce(global.books, function(prev, book) {
return prev.then(function() {
return fsUtil.remove(path.join(book.root, "_book"));
})
@@ -57,6 +57,6 @@ before(function(done) {
return book.parse();
});
}, Q()),
done
);
done
);
});
+2 -2
View File
@@ -15,7 +15,7 @@ describe('JSON generator', function () {
});
it('should correctly generate a book to json with sub folders', function(done) {
testGeneration(books[1], "json", function(output) {
testGeneration(books[1], "json", function(output) {
assert(fs.existsSync(path.join(output, "README.json")));
assert(fs.existsSync(path.join(output, "intro.json")));
assert(fs.existsSync(path.join(output, "sub/test1.json")));
@@ -26,7 +26,7 @@ describe('JSON generator', function () {
});
it('should correctly generate a multilingual book to json', function(done) {
testGeneration(books[2], "json", function(output) {
testGeneration(books[2], "json", function(output) {
assert(fs.existsSync(path.join(output, "README.json")));
assert(fs.existsSync(path.join(output, "en/README.json")));
assert(fs.existsSync(path.join(output, "fr/README.json")));
+2 -2
View File
@@ -5,7 +5,7 @@ var assert = require('assert');
describe('Book parsing', function () {
it('should correctly parse the readme', function() {
assert.equal(books[1].options.title, 'My Book');
assert.equal(books[1].options.description, 'Test description');
assert.equal(books[1].options.description, 'Test description');
});
it('should correctly parse the readme with asciidoc', function() {
@@ -21,7 +21,7 @@ describe('Book parsing', function () {
assert.equal(LEXED.chapters[0].introduction, true);
assert.equal(LEXED.chapters[0].external, false);
assert.equal(LEXED.chapters[1].path, 'test.md');
assert.equal(LEXED.chapters[1].path, 'test.md');
assert.equal(LEXED.chapters[1].exists, false);
assert.equal(LEXED.chapters[1].introduction, false);
assert.equal(LEXED.chapters[1].external, false);
+11 -11
View File
@@ -2,22 +2,22 @@ var assert = require("assert");
module.exports = {
blocks: {
"test": {
"test": {
shortcuts: {
parsers: ["markdown"],
start: "$$",
end: "$$"
},
process: function(blk) {
return "test"+blk.body+"test";
}
},
"test2": {
end: "endtest2end",
process: function(blk) {
return "test2"+blk.body+"test2";
}
},
process: function(blk) {
return "test"+blk.body+"test";
}
},
"test2": {
end: "endtest2end",
process: function(blk) {
return "test2"+blk.body+"test2";
}
},
"test3join": {
blocks: [
"also"
+1 -1
View File
@@ -4,7 +4,7 @@ module.exports = {
return "Hello "+text;
},
helloCtx: function(text) {
return text+":"+this.book.root;
return text+":"+this.book.root;
}
}
};
+4 -4
View File
@@ -1,12 +1,12 @@
module.exports = {
website: {
website: {
js: [
"https://cdn.mathjax.org/mathjax/2.4-latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
]
},
ebook: {
css: [
"test"
]
css: [
"test"
]
}
};
+18 -18
View File
@@ -1,20 +1,20 @@
{
"LANGS_CHOOSE": "ভাষা নির্বাচন করুন",
"GLOSSARY": "গ্লোসারি",
"GLOSSARY_INDEX": "ইন্ডেক্স",
"GLOSSARY_OPEN": "গ্লোসারি",
"GITBOOK_LINK": "গিটবুকের মাধ্যমে প্রকাশিত",
"SUMMARY": "সূচিপত্র",
"SUMMARY_INTRODUCTION": "সূচনা",
"SUMMARY_TOGGLE": "সূচিপত্র",
"SEARCH_TOGGLE": "অনুসন্ধান",
"SEARCH_PLACEHOLDER": "অনুসন্ধান",
"FONTSETTINGS_TOGGLE": "ফন্ট সেটিংস",
"SHARE_TOGGLE": "শেয়ার",
"SHARE_ON": "__platform__-এ শেয়ার",
"FONTSETTINGS_WHITE": "সাদা",
"FONTSETTINGS_SEPIA": "সেপিয়া",
"FONTSETTINGS_NIGHT": "রাত",
"FONTSETTINGS_SANS": "স্যান্স",
"FONTSETTINGS_SERIF": "শেরিফ"
"LANGS_CHOOSE": "ভাষা নির্বাচন করুন",
"GLOSSARY": "গ্লোসারি",
"GLOSSARY_INDEX": "ইন্ডেক্স",
"GLOSSARY_OPEN": "গ্লোসারি",
"GITBOOK_LINK": "গিটবুকের মাধ্যমে প্রকাশিত",
"SUMMARY": "সূচিপত্র",
"SUMMARY_INTRODUCTION": "সূচনা",
"SUMMARY_TOGGLE": "সূচিপত্র",
"SEARCH_TOGGLE": "অনুসন্ধান",
"SEARCH_PLACEHOLDER": "অনুসন্ধান",
"FONTSETTINGS_TOGGLE": "ফন্ট সেটিংস",
"SHARE_TOGGLE": "শেয়ার",
"SHARE_ON": "__platform__-এ শেয়ার",
"FONTSETTINGS_WHITE": "সাদা",
"FONTSETTINGS_SEPIA": "সেপিয়া",
"FONTSETTINGS_NIGHT": "রাত",
"FONTSETTINGS_SANS": "স্যান্স",
"FONTSETTINGS_SERIF": "শেরিফ"
}
+18 -18
View File
@@ -1,20 +1,20 @@
{
"LANGS_CHOOSE": "Sprache auswählen",
"GLOSSARY": "Glossar",
"GLOSSARY_INDEX": "Index",
"GLOSSARY_OPEN": "Glossar",
"GITBOOK_LINK": "Veröffentlicht mit GitBook",
"SUMMARY": "Inhaltsverzeichnis",
"SUMMARY_INTRODUCTION": "Einleitung",
"SUMMARY_TOGGLE": "Inhaltsverzeichnis",
"SEARCH_TOGGLE": "Suche",
"SEARCH_PLACEHOLDER": "Suchbegriff eingeben",
"FONTSETTINGS_TOGGLE": "Schrifteinstellungen",
"SHARE_TOGGLE": "Teilen",
"SHARE_ON": "Auf __platform__ teilen",
"FONTSETTINGS_WHITE": "Hell",
"FONTSETTINGS_SEPIA": "Sepia",
"FONTSETTINGS_NIGHT": "Nacht",
"FONTSETTINGS_SANS": "Sans",
"FONTSETTINGS_SERIF": "Serif"
"LANGS_CHOOSE": "Sprache auswählen",
"GLOSSARY": "Glossar",
"GLOSSARY_INDEX": "Index",
"GLOSSARY_OPEN": "Glossar",
"GITBOOK_LINK": "Veröffentlicht mit GitBook",
"SUMMARY": "Inhaltsverzeichnis",
"SUMMARY_INTRODUCTION": "Einleitung",
"SUMMARY_TOGGLE": "Inhaltsverzeichnis",
"SEARCH_TOGGLE": "Suche",
"SEARCH_PLACEHOLDER": "Suchbegriff eingeben",
"FONTSETTINGS_TOGGLE": "Schrifteinstellungen",
"SHARE_TOGGLE": "Teilen",
"SHARE_ON": "Auf __platform__ teilen",
"FONTSETTINGS_WHITE": "Hell",
"FONTSETTINGS_SEPIA": "Sepia",
"FONTSETTINGS_NIGHT": "Nacht",
"FONTSETTINGS_SANS": "Sans",
"FONTSETTINGS_SERIF": "Serif"
}
+18 -18
View File
@@ -1,20 +1,20 @@
{
"LANGS_CHOOSE": "Choose a language",
"GLOSSARY": "Glossary",
"GLOSSARY_INDEX": "Index",
"GLOSSARY_OPEN": "Glossary",
"GITBOOK_LINK": "Published with GitBook",
"SUMMARY": "Table of Contents",
"SUMMARY_INTRODUCTION": "Introduction",
"SUMMARY_TOGGLE": "Table of Contents",
"SEARCH_TOGGLE": "Search",
"SEARCH_PLACEHOLDER": "Type to search",
"FONTSETTINGS_TOGGLE": "Font Settings",
"SHARE_TOGGLE": "Share",
"SHARE_ON": "Share on __platform__",
"FONTSETTINGS_WHITE": "White",
"FONTSETTINGS_SEPIA": "Sepia",
"FONTSETTINGS_NIGHT": "Night",
"FONTSETTINGS_SANS": "Sans",
"FONTSETTINGS_SERIF": "Serif"
"LANGS_CHOOSE": "Choose a language",
"GLOSSARY": "Glossary",
"GLOSSARY_INDEX": "Index",
"GLOSSARY_OPEN": "Glossary",
"GITBOOK_LINK": "Published with GitBook",
"SUMMARY": "Table of Contents",
"SUMMARY_INTRODUCTION": "Introduction",
"SUMMARY_TOGGLE": "Table of Contents",
"SEARCH_TOGGLE": "Search",
"SEARCH_PLACEHOLDER": "Type to search",
"FONTSETTINGS_TOGGLE": "Font Settings",
"SHARE_TOGGLE": "Share",
"SHARE_ON": "Share on __platform__",
"FONTSETTINGS_WHITE": "White",
"FONTSETTINGS_SEPIA": "Sepia",
"FONTSETTINGS_NIGHT": "Night",
"FONTSETTINGS_SANS": "Sans",
"FONTSETTINGS_SERIF": "Serif"
}
+19 -19
View File
@@ -1,21 +1,21 @@
{
"direction": "rtl",
"LANGS_CHOOSE": "انتخاب زبان",
"GLOSSARY": "واژه‌نامه",
"GLOSSARY_INDEX": "فهرست واژه‌ها",
"GLOSSARY_OPEN": "واژه‌نامه",
"GITBOOK_LINK": "انتشار یافته توسط GitBook",
"SUMMARY": "فهرست مطالب",
"SUMMARY_INTRODUCTION": "مقدمه",
"SUMMARY_TOGGLE": "فهرست مطالب",
"SEARCH_TOGGLE": "جستجو",
"SEARCH_PLACEHOLDER": "چیزی برای جستجو بنویسید",
"FONTSETTINGS_TOGGLE": "تنظیمات فونت",
"SHARE_TOGGLE": "اشتراک",
"SHARE_ON": "در __platform__ به اشتراک بگذارید",
"FONTSETTINGS_WHITE": "سفید",
"FONTSETTINGS_SEPIA": "سپیا",
"FONTSETTINGS_NIGHT": "شب",
"FONTSETTINGS_SANS": "سنس",
"FONTSETTINGS_SERIF": "سریف"
"direction": "rtl",
"LANGS_CHOOSE": "انتخاب زبان",
"GLOSSARY": "واژه‌نامه",
"GLOSSARY_INDEX": "فهرست واژه‌ها",
"GLOSSARY_OPEN": "واژه‌نامه",
"GITBOOK_LINK": "انتشار یافته توسط GitBook",
"SUMMARY": "فهرست مطالب",
"SUMMARY_INTRODUCTION": "مقدمه",
"SUMMARY_TOGGLE": "فهرست مطالب",
"SEARCH_TOGGLE": "جستجو",
"SEARCH_PLACEHOLDER": "چیزی برای جستجو بنویسید",
"FONTSETTINGS_TOGGLE": "تنظیمات فونت",
"SHARE_TOGGLE": "اشتراک",
"SHARE_ON": "در __platform__ به اشتراک بگذارید",
"FONTSETTINGS_WHITE": "سفید",
"FONTSETTINGS_SEPIA": "سپیا",
"FONTSETTINGS_NIGHT": "شب",
"FONTSETTINGS_SANS": "سنس",
"FONTSETTINGS_SERIF": "سریف"
}
+18 -18
View File
@@ -1,20 +1,20 @@
{
"LANGS_CHOOSE": "Choisissez une langue",
"GLOSSARY": "Glossaire",
"GLOSSARY_INDEX": "Index",
"GLOSSARY_OPEN": "Glossaire",
"GITBOOK_LINK": "Publié avec GitBook",
"SUMMARY": "Table des matières",
"SUMMARY_INTRODUCTION": "Introduction",
"SUMMARY_TOGGLE": "Table des matières",
"SEARCH_TOGGLE": "Recherche",
"SEARCH_PLACEHOLDER": "Tapez pour rechercher",
"FONTSETTINGS_TOGGLE": "Paramètres de Police",
"SHARE_TOGGLE": "Partage",
"SHARE_ON": "Partager sur __platform__",
"FONTSETTINGS_WHITE": "Clair",
"FONTSETTINGS_SEPIA": "Sépia",
"FONTSETTINGS_NIGHT": "Nuit",
"FONTSETTINGS_SANS": "Sans",
"FONTSETTINGS_SERIF": "Serif"
"LANGS_CHOOSE": "Choisissez une langue",
"GLOSSARY": "Glossaire",
"GLOSSARY_INDEX": "Index",
"GLOSSARY_OPEN": "Glossaire",
"GITBOOK_LINK": "Publié avec GitBook",
"SUMMARY": "Table des matières",
"SUMMARY_INTRODUCTION": "Introduction",
"SUMMARY_TOGGLE": "Table des matières",
"SEARCH_TOGGLE": "Recherche",
"SEARCH_PLACEHOLDER": "Tapez pour rechercher",
"FONTSETTINGS_TOGGLE": "Paramètres de Police",
"SHARE_TOGGLE": "Partage",
"SHARE_ON": "Partager sur __platform__",
"FONTSETTINGS_WHITE": "Clair",
"FONTSETTINGS_SEPIA": "Sépia",
"FONTSETTINGS_NIGHT": "Nuit",
"FONTSETTINGS_SANS": "Sans",
"FONTSETTINGS_SERIF": "Serif"
}
+18 -18
View File
@@ -1,20 +1,20 @@
{
"LANGS_CHOOSE": "Scegli una lingua",
"GLOSSARY": "Glossario",
"GLOSSARY_INDEX": "Indice",
"GLOSSARY_OPEN": "Glossario",
"GITBOOK_LINK": "Pubblicato con GitBook",
"SUMMARY": "Sommario",
"SUMMARY_INTRODUCTION": "Introduzione",
"SUMMARY_TOGGLE": "Sommario",
"SEARCH_TOGGLE": "Cerca",
"SEARCH_PLACEHOLDER": "Scrivi per cercare",
"FONTSETTINGS_TOGGLE": "Impostazioni dei caratteri",
"SHARE_TOGGLE": "Condividi",
"SHARE_ON": "Condividi su __platform__",
"FONTSETTINGS_WHITE": "Bianco",
"FONTSETTINGS_SEPIA": "Seppia",
"FONTSETTINGS_NIGHT": "Notte",
"FONTSETTINGS_SANS": "Sans",
"FONTSETTINGS_SERIF": "Serif"
"LANGS_CHOOSE": "Scegli una lingua",
"GLOSSARY": "Glossario",
"GLOSSARY_INDEX": "Indice",
"GLOSSARY_OPEN": "Glossario",
"GITBOOK_LINK": "Pubblicato con GitBook",
"SUMMARY": "Sommario",
"SUMMARY_INTRODUCTION": "Introduzione",
"SUMMARY_TOGGLE": "Sommario",
"SEARCH_TOGGLE": "Cerca",
"SEARCH_PLACEHOLDER": "Scrivi per cercare",
"FONTSETTINGS_TOGGLE": "Impostazioni dei caratteri",
"SHARE_TOGGLE": "Condividi",
"SHARE_ON": "Condividi su __platform__",
"FONTSETTINGS_WHITE": "Bianco",
"FONTSETTINGS_SEPIA": "Seppia",
"FONTSETTINGS_NIGHT": "Notte",
"FONTSETTINGS_SANS": "Sans",
"FONTSETTINGS_SERIF": "Serif"
}
+18 -18
View File
@@ -1,20 +1,20 @@
{
"LANGS_CHOOSE": "Выберите язык",
"GLOSSARY": "Алфавитный указатель",
"GLOSSARY_INDEX": "Алфавитный указатель",
"GLOSSARY_OPEN": "Алфавитный указатель",
"GITBOOK_LINK": "Опубликовано с помощью GitBook",
"SUMMARY": "Содержание",
"SUMMARY_INTRODUCTION": "Введение",
"SUMMARY_TOGGLE": "Содержание",
"SEARCH_TOGGLE": "Поиск",
"SEARCH_PLACEHOLDER": "Введите условия поиска",
"FONTSETTINGS_TOGGLE": "Шрифт",
"SHARE_TOGGLE": "Поделиться",
"SHARE_ON": "Поделиться в __platform__",
"FONTSETTINGS_WHITE": "Светлый",
"FONTSETTINGS_SEPIA": "Сепия",
"FONTSETTINGS_NIGHT": "Тёмный",
"FONTSETTINGS_SANS": "Sans",
"FONTSETTINGS_SERIF": "Serif"
"LANGS_CHOOSE": "Выберите язык",
"GLOSSARY": "Алфавитный указатель",
"GLOSSARY_INDEX": "Алфавитный указатель",
"GLOSSARY_OPEN": "Алфавитный указатель",
"GITBOOK_LINK": "Опубликовано с помощью GitBook",
"SUMMARY": "Содержание",
"SUMMARY_INTRODUCTION": "Введение",
"SUMMARY_TOGGLE": "Содержание",
"SEARCH_TOGGLE": "Поиск",
"SEARCH_PLACEHOLDER": "Введите условия поиска",
"FONTSETTINGS_TOGGLE": "Шрифт",
"SHARE_TOGGLE": "Поделиться",
"SHARE_ON": "Поделиться в __platform__",
"FONTSETTINGS_WHITE": "Светлый",
"FONTSETTINGS_SEPIA": "Сепия",
"FONTSETTINGS_NIGHT": "Тёмный",
"FONTSETTINGS_SANS": "Sans",
"FONTSETTINGS_SERIF": "Serif"
}
+2 -2
View File
@@ -41,7 +41,7 @@ html {
body {
text-rendering: optimizeLegibility;
font-smoothing: antialiased;
font-family: @font-family-base;
font-smoothing: antialiased;
font-family: @font-family-base;
font-size: @font-size-base;
}
+11 -11
View File
@@ -1,15 +1,15 @@
.book-header{
#font-settings-wrapper{
#enlarge-font-size, #reduce-font-size {
line-height: 30px;
}
#font-settings-wrapper{
#enlarge-font-size, #reduce-font-size {
line-height: 30px;
}
#enlarge-font-size{
font-size: 1.4em;
}
#reduce-font-size{
font-size: 1em;
}
}
#enlarge-font-size{
font-size: 1.4em;
}
#reduce-font-size{
font-size: 1em;
}
}
}
+11 -11
View File
@@ -3,15 +3,15 @@
{% block title %}{% i18n "GLOSSARY" %}Glossary{% endi18n %} | {{ title }}{% endblock %}
{% block page_inner %}
{% for item in glossary %}
<section class="normal glossary" id="{{ item.id }}">
<h2><a href="#{{ item.id }}">{{ item.name }}</a></h2>
<p>{{ item.description|safe }}</p>
<ul class="glossary-index">
{% for file in item.files %}
<li><a href="{{ basePath }}/{{ file.path|contentLink }}"><span class="level">{{ file.level }}.</span> {{ file.title }}</a></li>
{% endfor %}
</ul>
</section>
{% endfor %}
{% for item in glossary %}
<section class="normal glossary" id="{{ item.id }}">
<h2><a href="#{{ item.id }}">{{ item.name }}</a></h2>
<p>{{ item.description|safe }}</p>
<ul class="glossary-index">
{% for file in item.files %}
<li><a href="{{ basePath }}/{{ file.path|contentLink }}"><span class="level">{{ file.level }}.</span> {{ file.title }}</a></li>
{% endfor %}
</ul>
</section>
{% endfor %}
{% endblock %}
@@ -37,14 +37,14 @@
</div>
<ul class="summary">
{% set _divider = false %}
{% if options.links.sidebar %}
{% for linkTitle, link in options.links.sidebar %}
{% set _divider = true %}
{% if options.links.sidebar %}
{% for linkTitle, link in options.links.sidebar %}
{% set _divider = true %}
<li>
<a href="{{ link }}" target="blank" class="custom-link">{{ linkTitle }}</a>
</li>
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
{% if _divider %}
<li class="divider"></li>