mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-26 20:27:00 +00:00
Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 16128c7e60 | |||
| 8b6a80cffb | |||
| 86f8a9d8fb | |||
| 790dfd601e | |||
| 3426428142 | |||
| 6c5c8e6eb7 | |||
| 3aefcaea73 | |||
| 04c025774d | |||
| 80aac7f581 | |||
| 266f7ca73d | |||
| d6eb8e4c60 | |||
| c87edb155a | |||
| ef0468ad5d | |||
| f03153eb0c | |||
| 3d8b6e550a | |||
| 4c3dbca5ca | |||
| a258feea37 | |||
| 3a3332d0b9 | |||
| 4259283f32 | |||
| 243d977cd6 | |||
| 94bbbecedf | |||
| f49eab42a9 | |||
| ce6b2bc47d | |||
| 3245d7e430 | |||
| 6ee17c32ae | |||
| bf7ffe6d4c | |||
| ec7bc6b347 | |||
| b425db0979 | |||
| 30c6d1c9de | |||
| cee1d90fc6 | |||
| 522342667c | |||
| d1c1277bb9 | |||
| 9a66f56c79 | |||
| 087ca28ca2 | |||
| 3d5281ff3a | |||
| f62cf340c5 | |||
| 7e12bd3588 | |||
| 4dbdb95ebe | |||
| 2c5ddbcd8f | |||
| be4fd74f90 | |||
| 57491e3a8b | |||
| f7a442d297 | |||
| cfebdc6f6b |
@@ -2,4 +2,3 @@ language: node_js
|
||||
node_js:
|
||||
- "0.11"
|
||||
- "0.10"
|
||||
- "0.8"
|
||||
|
||||
+2
-1
@@ -44,7 +44,8 @@ module.exports = function (grunt) {
|
||||
"requireLib": 'vendors/requirejs/require',
|
||||
"Mousetrap": 'vendors/mousetrap/mousetrap',
|
||||
"lunr": 'vendors/lunr.js/lunr',
|
||||
"URI": 'vendors/URIjs/src/URI'
|
||||
"URI": 'vendors/URIjs/src/URI',
|
||||
"ace": 'vendors/ace-builds/src-noconflict/'
|
||||
},
|
||||
shim: {
|
||||
'jQuery': {
|
||||
|
||||
@@ -3,7 +3,7 @@ GitBook
|
||||
|
||||
[](https://travis-ci.org/GitbookIO/gitbook)
|
||||
|
||||
GitBook is a command line tool (and Node.js library) for building beautiful books and exercises using GitHub/Git and Markdown. You can see an example: [Learn Javascript](https://www.gitbook.io/book/GitBookIO/javascript). An [editor](https://github.com/GitbookIO/editor) is available for Windows, Mac and Linux. You can follow [@GitBookIO](https://twitter.com/GitBookIO) on Twitter. Complete documentation is available at [help.gitbook.io](http://help.gitbook.io/).
|
||||
GitBook is a command line tool (and Node.js library) for building beautiful books and exercises using GitHub/Git and Markdown. Here is an example: [Learn Javascript](https://www.gitbook.io/book/GitBookIO/javascript). You can publish book easily online using [gitbook.io](https://www.gitbook.io) and an [editor](https://github.com/GitbookIO/editor) is available for Windows, Mac and Linux. You can follow [@GitBookIO](https://twitter.com/GitBookIO) on Twitter. Complete documentation is available at [help.gitbook.io](http://help.gitbook.io/).
|
||||
|
||||

|
||||
|
||||
@@ -253,3 +253,12 @@ Plugins can used to extend your book's functionality. Read [GitbookIO/plugin](ht
|
||||
* [Markdown within HTML](https://github.com/mrpotes/gitbook-plugin-nestedmd): Process markdown within HTML blocks - allows custom layout options for individual pages
|
||||
* [Bootstrap JavaScript plugins](https://github.com/mrpotes/gitbook-plugin-bootstrapjs): Use the [Bootstrap JavaScript plugins](http://getbootstrap.com/javascript) in your online GitBook
|
||||
* [Piwik Open Analytics](https://github.com/emmanuel-keller/gitbook-plugin-piwik): Piwik Open Analytics tracking for your book
|
||||
|
||||
#### Debugging
|
||||
|
||||
You can use the environment variable `DEBUG=true` to get better error messages (with stack trace). For example:
|
||||
|
||||
```
|
||||
$ export DEBUG=true
|
||||
$ gitbook build ./
|
||||
```
|
||||
|
||||
+13
-3
@@ -10,9 +10,10 @@ var generators = require("../lib/generate").generators;
|
||||
|
||||
var buildCommand = function(command) {
|
||||
return command
|
||||
.option('-v, --verbose', 'Activate verbose mode, useful for debugging errors')
|
||||
.option('-o, --output <directory>', 'Path to output directory, defaults to ./_book')
|
||||
.option('-f, --format <name>', 'Change generation format, defaults to site, availables are: '+_.keys(generators).join(", "))
|
||||
.option('--config <config file>', 'Configuration file to use, defaults to book.js or book.json')
|
||||
.option('--config <config file>', 'Configuration file to use, defaults to book.js or book.json');
|
||||
};
|
||||
|
||||
|
||||
@@ -26,6 +27,11 @@ var makeBuildFunc = function(converter) {
|
||||
dir = dir || process.cwd();
|
||||
outputDir = options.output;
|
||||
|
||||
// Set debugging
|
||||
if(options.verbose) {
|
||||
process.env.DEBUG = "true";
|
||||
}
|
||||
|
||||
console.log('Starting build ...');
|
||||
return converter(
|
||||
_.extend({}, options || {}, {
|
||||
@@ -38,8 +44,12 @@ var makeBuildFunc = function(converter) {
|
||||
.then(function(output) {
|
||||
console.log("Successfully built!");
|
||||
return output;
|
||||
}, utils.logError)
|
||||
.fail(function() {
|
||||
})
|
||||
.fail(function(err) {
|
||||
// Log error
|
||||
utils.logError(err);
|
||||
|
||||
// Exit process with failure code
|
||||
process.exit(-1);
|
||||
});
|
||||
};
|
||||
|
||||
+2
-1
@@ -7,6 +7,7 @@
|
||||
"requirejs": "2.1.11",
|
||||
"URIjs": "1.13.1",
|
||||
"mousetrap": "1.4.6",
|
||||
"lunr.js": "0.5.2"
|
||||
"lunr.js": "0.5.2",
|
||||
"ace-builds": "1.1.3"
|
||||
}
|
||||
}
|
||||
@@ -61,6 +61,7 @@ Generator.prototype.finish = function() {
|
||||
"--margin-bottom": String(pdfOptions.margin.bottom),
|
||||
"--pdf-add-toc": Boolean(pdfOptions.toc),
|
||||
"--pdf-default-font-size": String(pdfOptions.fontSize),
|
||||
"--pdf-mono-font-size": String(pdfOptions.fontSize),
|
||||
"--paper-size": String(pdfOptions.paperSize),
|
||||
"--pdf-page-numbers": Boolean(pdfOptions.pageNumbers)
|
||||
});
|
||||
|
||||
+12
-1
@@ -16,9 +16,20 @@ var getFiles = function(path) {
|
||||
|
||||
// Add extra rules to ignore common folders
|
||||
ig.addIgnoreRules([
|
||||
// Skip Git stuff
|
||||
'.git/',
|
||||
'.gitignore',
|
||||
'.DS_Store'
|
||||
|
||||
// Skip OS X meta data
|
||||
'.DS_Store',
|
||||
|
||||
// Skip stuff installed by plugins
|
||||
'node_modules',
|
||||
|
||||
// Skip book outputs
|
||||
'*.pdf',
|
||||
'*.epub',
|
||||
'*.mobi',
|
||||
], '__custom_stuff');
|
||||
|
||||
// Push each file to our list
|
||||
|
||||
@@ -45,6 +45,27 @@ BaseGenerator.prototype.transferFolder = function(input) {
|
||||
);
|
||||
};
|
||||
|
||||
BaseGenerator.prototype.copyCover = function() {
|
||||
var that = this;
|
||||
|
||||
return Q.all([
|
||||
fs.copy(path.join(this.options.input, "cover.jpg"), path.join(this.options.output, "cover.jpg")),
|
||||
fs.copy(path.join(this.options.input, "cover_small.jpg"), path.join(this.options.output, "cover_small.jpg"))
|
||||
])
|
||||
.fail(function() {
|
||||
// If orignally from multi-lang, try copy from originalInput
|
||||
if (!that.options.originalInput) return;
|
||||
|
||||
return Q.all([
|
||||
fs.copy(path.join(that.options.originalInput, "cover.jpg"), path.join(that.options.output, "cover.jpg")),
|
||||
fs.copy(path.join(that.options.originalInput, "cover_small.jpg"), path.join(that.options.output, "cover_small.jpg"))
|
||||
]);
|
||||
})
|
||||
.fail(function(err) {
|
||||
return Q();
|
||||
});
|
||||
};
|
||||
|
||||
BaseGenerator.prototype.langsIndex = function(langs) {
|
||||
return Q.reject(new Error("Langs index is not supported in this generator"));
|
||||
};
|
||||
|
||||
+24
-4
@@ -1,9 +1,9 @@
|
||||
var Q = require("q");
|
||||
var _ = require("lodash");
|
||||
var path = require("path");
|
||||
var swig = require('swig');
|
||||
var tmp = require('tmp');
|
||||
|
||||
var swig = require('./template');
|
||||
var fs = require("./fs");
|
||||
var parse = require("../parse");
|
||||
var Plugin = require("./plugin");
|
||||
@@ -161,7 +161,9 @@ var generateMultiLang = function(options) {
|
||||
return prev.then(function() {
|
||||
return generate(_.extend({}, options, {
|
||||
input: path.join(options.input, entry.path),
|
||||
output: path.join(options.output, entry.path)
|
||||
output: path.join(options.output, entry.path),
|
||||
originalInput: options.input,
|
||||
originalOutput: options.output
|
||||
}));
|
||||
})
|
||||
}, Q());
|
||||
@@ -176,6 +178,17 @@ var generateMultiLang = function(options) {
|
||||
return generator.langsIndex(options.langsSummary);
|
||||
})
|
||||
|
||||
// Copy cover file
|
||||
.then(function() {
|
||||
return Q.all([
|
||||
fs.copy(path.join(options.input, "cover.jpg"), path.join(options.output, "cover.jpg")),
|
||||
fs.copy(path.join(options.input, "cover_small.jpg"), path.join(options.output, "cover_small.jpg"))
|
||||
])
|
||||
.fail(function() {
|
||||
return Q();
|
||||
})
|
||||
})
|
||||
|
||||
// Return options to caller
|
||||
.then(_.constant(options));
|
||||
};
|
||||
@@ -211,8 +224,15 @@ var generateBook = function(options) {
|
||||
options.github = null;
|
||||
return null;
|
||||
} else if(options.github) {
|
||||
// Git already specified in options
|
||||
return options.github;
|
||||
// Git already specified in options
|
||||
options.github = (
|
||||
// Support URLs in "github" entry of book.json
|
||||
parse.git.githubID(options.github) ||
|
||||
|
||||
// Fallback
|
||||
options.github
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try auto detecting
|
||||
|
||||
@@ -2,32 +2,12 @@ var _ = require("lodash");
|
||||
var util = require("util");
|
||||
var path = require("path");
|
||||
var Q = require("q");
|
||||
var swig = require('swig');
|
||||
var hljs = require('highlight.js');
|
||||
var swig = require("../template");
|
||||
|
||||
var fs = require("../fs");
|
||||
var parse = require("../../parse");
|
||||
var BaseGenerator = require("../site");
|
||||
|
||||
// Swig filter: highlight coloration
|
||||
swig.setFilter('code', function(code, lang) {
|
||||
try {
|
||||
return hljs.highlight(lang, code).value;
|
||||
} catch(e) {
|
||||
return hljs.highlightAuto(code).value;
|
||||
}
|
||||
});
|
||||
|
||||
// Convert a level into a deep level
|
||||
swig.setFilter('lvl', function(lvl) {
|
||||
return lvl.split(".").length;
|
||||
});
|
||||
|
||||
// Join path
|
||||
swig.setFilter('pathJoin', function(base, _path) {
|
||||
return path.join(base, _path);
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
* This generator will generate a simple index.html which can be converted as a PDF
|
||||
@@ -95,6 +75,11 @@ Generator.prototype.finish = function() {
|
||||
}, output);
|
||||
})
|
||||
|
||||
// Copy cover
|
||||
.then(function() {
|
||||
return that.copyCover();
|
||||
})
|
||||
|
||||
// Copy assets
|
||||
.then(function() {
|
||||
return fs.copy(
|
||||
|
||||
@@ -2,26 +2,16 @@ var util = require("util");
|
||||
var path = require("path");
|
||||
var Q = require("q");
|
||||
var _ = require("lodash");
|
||||
var swig = require('swig');
|
||||
var swig = require("../template");
|
||||
|
||||
var fs = require("../fs");
|
||||
var parse = require("../../parse");
|
||||
var BaseGenerator = require("../generator");
|
||||
|
||||
var links = require("../../utils/links");
|
||||
var indexer = require('./search_indexer');
|
||||
var Manifest = require('../manifest');
|
||||
|
||||
// Swig filter for returning the count of lines in a code section
|
||||
swig.setFilter('lines', function(content) {
|
||||
return content.split('\n').length;
|
||||
});
|
||||
|
||||
// Swig filter for returning a link to the associated html file of a markdown file
|
||||
swig.setFilter('mdLink', function(link) {
|
||||
var link = link.replace(".md", ".html");
|
||||
if (link == "README.html") link = "index.html";
|
||||
return link;
|
||||
});
|
||||
|
||||
var Generator = function() {
|
||||
BaseGenerator.apply(this, arguments);
|
||||
@@ -162,7 +152,7 @@ Generator.prototype.convertFile = function(content, _input) {
|
||||
content: page.sections,
|
||||
|
||||
basePath: basePath,
|
||||
staticBase: path.join(basePath, "gitbook"),
|
||||
staticBase: links.join(basePath, "gitbook"),
|
||||
}, output, function(html) {
|
||||
page.content = html;
|
||||
|
||||
@@ -198,7 +188,7 @@ Generator.prototype.copyAssets = function() {
|
||||
path.join(that.options.output, "gitbook")
|
||||
)
|
||||
|
||||
// Add to cach manifest
|
||||
// Add to cache manifest
|
||||
.then(function() {
|
||||
return that.manifest.addFolder(path.join(that.options.output, "gitbook"), "gitbook");
|
||||
})
|
||||
@@ -237,7 +227,9 @@ Generator.prototype.writeCacheManifest = function() {
|
||||
};
|
||||
|
||||
Generator.prototype.finish = function() {
|
||||
var deferred = this.copyAssets().then(this.writeSearchIndex);
|
||||
var deferred = this.copyAssets()
|
||||
.then(this.copyCover)
|
||||
.then(this.writeSearchIndex);
|
||||
|
||||
if (this.options.cache !== false) {
|
||||
deferred = deferred.then(this.writeCacheManifest);
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
var path = require("path");
|
||||
var swig = require('swig');
|
||||
var hljs = require('highlight.js');
|
||||
|
||||
var links = require('../utils/').links;
|
||||
var pkg = require('../../package.json');
|
||||
|
||||
swig.setDefaults({
|
||||
locals: {
|
||||
gitbook: {
|
||||
version: pkg.version
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Swig filter for returning the count of lines in a code section
|
||||
swig.setFilter('lines', function(content) {
|
||||
return content.split('\n').length;
|
||||
});
|
||||
|
||||
// Swig filter for returning a link to the associated html file of a markdown file
|
||||
swig.setFilter('mdLink', function(link) {
|
||||
var link = link.replace(".md", ".html");
|
||||
if (link == "README.html") link = "index.html";
|
||||
return link;
|
||||
});
|
||||
|
||||
// Swig filter: highlight coloration
|
||||
swig.setFilter('code', function(code, lang) {
|
||||
try {
|
||||
return hljs.highlight(lang, code).value;
|
||||
} catch(e) {
|
||||
return hljs.highlightAuto(code).value;
|
||||
}
|
||||
});
|
||||
|
||||
// Convert a level into a deep level
|
||||
swig.setFilter('lvl', function(lvl) {
|
||||
return lvl.split(".").length;
|
||||
});
|
||||
|
||||
// Join path
|
||||
swig.setFilter('pathJoin', function(base, _path) {
|
||||
return path.join(base, _path);
|
||||
});
|
||||
|
||||
// Is a link an absolute link
|
||||
swig.setFilter('isExternalLink', function(link) {
|
||||
return links.isExternal(link);
|
||||
});
|
||||
|
||||
module.exports = swig;
|
||||
+1
-1
@@ -28,7 +28,7 @@ function gitURL(path) {
|
||||
// Parse a git URL to a github ID : username/reponame
|
||||
function githubID(_url) {
|
||||
// Remove .git if it's in _url
|
||||
var sliceEnd = _url.slice(-4) === '.git' ? -4 : _url.length;
|
||||
var sliceEnd = _url.slice(-4) === '.git' ? -4 : undefined;
|
||||
|
||||
// Detect HTTPS repos
|
||||
var parsed = url.parse(_url);
|
||||
|
||||
+8
-6
@@ -1,13 +1,14 @@
|
||||
var _ = require("lodash")
|
||||
var parseSummary = require("./summary");
|
||||
var _ = require("lodash");
|
||||
var parseEntries = require("./summary").entries;
|
||||
|
||||
|
||||
var parseLangs = function(content) {
|
||||
var summary = parseSummary(content);
|
||||
var entries = parseEntries(content);
|
||||
|
||||
return {
|
||||
list: _.chain(summary.chapters)
|
||||
list: _.chain(entries)
|
||||
.filter(function(entry) {
|
||||
return entry.path != null;
|
||||
return Boolean(entry.path);
|
||||
})
|
||||
.map(function(entry) {
|
||||
return {
|
||||
@@ -17,7 +18,8 @@ var parseLangs = function(content) {
|
||||
};
|
||||
})
|
||||
.value()
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
module.exports = parseLangs;
|
||||
@@ -26,15 +26,9 @@ function navigation(summary, files) {
|
||||
// Support single files as well as list
|
||||
files = _.isArray(files) ? files : (_.isString(files) ? [files] : null);
|
||||
|
||||
// Special README nav
|
||||
var README_NAV = {
|
||||
path: 'README.md',
|
||||
title: 'Introduction',
|
||||
level: '0',
|
||||
};
|
||||
|
||||
// List of all navNodes
|
||||
var navNodes = [README_NAV].concat(flattenChapters(summary.chapters));
|
||||
// Flatten chapters, then add in default README node if ndeeded etc ...
|
||||
var navNodes = flattenChapters(summary.chapters);
|
||||
var prevNodes = [null].concat(navNodes.slice(0, -1));
|
||||
var nextNodes = navNodes.slice(1).concat([null]);
|
||||
|
||||
|
||||
@@ -11,9 +11,6 @@ var calculProgress = function(navigation, current) {
|
||||
nav.path = path;
|
||||
return nav;
|
||||
})
|
||||
.sortBy(function(nav) {
|
||||
return parseFloat(nav.level);
|
||||
})
|
||||
.map(function(nav, i) {
|
||||
// Calcul percent
|
||||
nav.percent = (i * 100) / Math.max((n - 1), 1);
|
||||
|
||||
+35
-8
@@ -87,6 +87,9 @@ function parseTitle(src, nums) {
|
||||
}
|
||||
|
||||
function parseChapter(nodes, nums) {
|
||||
// Convert single number to an array
|
||||
nums = _.isArray(nums) ? nums : [nums];
|
||||
|
||||
return _.extend(parseTitle(_.first(nodes).text, nums), {
|
||||
articles: _.map(listSplit(filterList(nodes), 'list_item_start', 'list_item_end'), function(nodes, i) {
|
||||
return parseChapter(nodes, nums.concat(i + 1));
|
||||
@@ -94,24 +97,48 @@ function parseChapter(nodes, nums) {
|
||||
});
|
||||
}
|
||||
|
||||
function parseSummary(src) {
|
||||
function defaultChapterList(chapterList) {
|
||||
var first = _.first(chapterList);
|
||||
|
||||
if (first) {
|
||||
var chapter = parseChapter(first, [0]);
|
||||
|
||||
// Already have README node, we're good to go
|
||||
if(chapter.path === 'README.md') {
|
||||
return chapterList;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
[ { type: 'text', text: '[Introduction](README.md)' } ]
|
||||
].concat(chapterList);
|
||||
}
|
||||
|
||||
function listGroups(src) {
|
||||
var nodes = marked.lexer(src);
|
||||
|
||||
// Get out list of chapters
|
||||
var chapterList = filterList(nodes);
|
||||
// Get out groups of lists
|
||||
return listSplit(
|
||||
filterList(nodes),
|
||||
'list_item_start', 'list_item_end'
|
||||
);
|
||||
}
|
||||
|
||||
function parseSummary(src) {
|
||||
// Split out chapter sections
|
||||
var chapters = _.chain(listSplit(chapterList, 'list_item_start', 'list_item_end'))
|
||||
.map(function(nodes, i) {
|
||||
return parseChapter(nodes, [i + 1]);
|
||||
})
|
||||
.value();
|
||||
var chapters = defaultChapterList(listGroups(src))
|
||||
.map(parseChapter);
|
||||
|
||||
return {
|
||||
chapters: chapters
|
||||
};
|
||||
}
|
||||
|
||||
function parseEntries (src) {
|
||||
return listGroups(src).map(parseChapter);
|
||||
}
|
||||
|
||||
|
||||
// Exports
|
||||
module.exports = parseSummary;
|
||||
module.exports.entries = parseEntries;
|
||||
|
||||
@@ -2,6 +2,7 @@ var MAP = {
|
||||
'py': 'python',
|
||||
'js': 'javascript',
|
||||
'rb': 'ruby',
|
||||
'csharp': 'cs',
|
||||
};
|
||||
|
||||
function normalize(lang) {
|
||||
|
||||
+31
-4
@@ -1,11 +1,24 @@
|
||||
var url = require('url');
|
||||
var path = require('path');
|
||||
|
||||
// Is the link an external link
|
||||
var isExternal = function(href) {
|
||||
try {
|
||||
return Boolean(url.parse(href).protocol);
|
||||
} catch(err) { }
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// Return true if the link is relative
|
||||
var isRelative = function(href) {
|
||||
var parsed = url.parse(href);
|
||||
try {
|
||||
var parsed = url.parse(href);
|
||||
|
||||
return !parsed.protocol && parsed.path && parsed.path[0] != '/';
|
||||
return !parsed.protocol && parsed.path && parsed.path[0] != '/';
|
||||
} catch(err) {}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// Relative to absolute path
|
||||
@@ -26,8 +39,22 @@ var toAbsolute = function(_href, dir, outdir) {
|
||||
return _href;
|
||||
};
|
||||
|
||||
// Join links
|
||||
|
||||
var join = function() {
|
||||
var _href = path.join.apply(path, arguments);
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
_href = _href.replace(/\\/g, '/');
|
||||
}
|
||||
|
||||
return _href;
|
||||
};
|
||||
|
||||
|
||||
module.exports = {
|
||||
isRelative: isRelative,
|
||||
toAbsolute: toAbsolute
|
||||
};
|
||||
isExternal: isExternal,
|
||||
toAbsolute: toAbsolute,
|
||||
join: join
|
||||
};
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gitbook",
|
||||
"version": "0.5.0",
|
||||
"version": "0.5.6",
|
||||
"homepage": "http://www.gitbook.io/",
|
||||
"description": "Library and cmd utility to generate GitBooks",
|
||||
"main": "lib/index.js",
|
||||
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
# Summary
|
||||
|
||||
* [Custom name for Introduction](README.md)
|
||||
* [Chapter 1](chapter-1/README.md)
|
||||
* [Article 1](chapter-1/ARTICLE1.md)
|
||||
* [Article 2](chapter-1/ARTICLE2.md)
|
||||
* [article 1.2.1](chapter-1/ARTICLE-1-2-1.md)
|
||||
* [article 1.2.2](chapter-1/ARTICLE-1-2-2.md)
|
||||
* [Chapter 2](chapter-2/README.md)
|
||||
* [Chapter 3](chapter-3/README.md)
|
||||
* [Chapter 4](chapter-4/README.md)
|
||||
* Unfinished article
|
||||
* Unfinished Chapter
|
||||
@@ -7,7 +7,9 @@ var navigation = require('../').parse.navigation;
|
||||
|
||||
|
||||
var CONTENT = fs.readFileSync(path.join(__dirname, './fixtures/SUMMARY.md'), 'utf8');
|
||||
var ALT_CONTENT = fs.readFileSync(path.join(__dirname, './fixtures/ALTERNATIVE_SUMMARY.md'), 'utf8');
|
||||
var LEXED = summary(CONTENT);
|
||||
var ALT_LEXED = summary(ALT_CONTENT);
|
||||
|
||||
|
||||
describe('Summary navigation', function() {
|
||||
@@ -76,6 +78,21 @@ describe('Summary navigation', function() {
|
||||
assert.equal(nav['chapter-3/README.md'].level, '3');
|
||||
});
|
||||
|
||||
it('should have a default README node', function() {
|
||||
var nav = navigation(LEXED);
|
||||
|
||||
assert.equal(nav['README.md'].level, '0');
|
||||
assert.equal(nav['README.md'].title, 'Introduction');
|
||||
});
|
||||
|
||||
it('Should allow README node to be customized', function() {
|
||||
var nav = navigation(ALT_LEXED);
|
||||
|
||||
assert(nav['README.md']);
|
||||
assert.equal(nav['README.md'].level, '0');
|
||||
assert.notEqual(nav['README.md'].title, 'Introduction');
|
||||
});
|
||||
|
||||
it('should not accept null paths', function() {
|
||||
var nav = navigation(LEXED);
|
||||
|
||||
|
||||
+17
-13
@@ -12,13 +12,13 @@ var LEXED = summary(CONTENT);
|
||||
describe('Summary parsing', function () {
|
||||
|
||||
it('should detect chapters', function() {
|
||||
assert.equal(LEXED.chapters.length, 5);
|
||||
assert.equal(LEXED.chapters.length, 6);
|
||||
});
|
||||
|
||||
it('should support articles', function() {
|
||||
assert.equal(LEXED.chapters[0].articles.length, 2);
|
||||
assert.equal(LEXED.chapters[1].articles.length, 0);
|
||||
assert.equal(LEXED.chapters[1].articles.length, 2);
|
||||
assert.equal(LEXED.chapters[2].articles.length, 0);
|
||||
assert.equal(LEXED.chapters[3].articles.length, 0);
|
||||
});
|
||||
|
||||
it('should detect paths and titles', function() {
|
||||
@@ -26,30 +26,34 @@ describe('Summary parsing', function () {
|
||||
assert(LEXED.chapters[1].path);
|
||||
assert(LEXED.chapters[2].path);
|
||||
assert(LEXED.chapters[3].path);
|
||||
assert.equal(LEXED.chapters[4].path, null);
|
||||
assert(LEXED.chapters[4].path);
|
||||
assert.equal(LEXED.chapters[5].path, null);
|
||||
|
||||
assert(LEXED.chapters[0].title);
|
||||
assert(LEXED.chapters[1].title);
|
||||
assert(LEXED.chapters[2].title);
|
||||
assert(LEXED.chapters[3].title);
|
||||
assert(LEXED.chapters[4].title);
|
||||
assert(LEXED.chapters[5].title);
|
||||
});
|
||||
|
||||
it('should normalize paths from .md to .html', function() {
|
||||
assert.equal(LEXED.chapters[0].path,'chapter-1/README.md');
|
||||
assert.equal(LEXED.chapters[1].path,'chapter-2/README.md');
|
||||
assert.equal(LEXED.chapters[2].path,'chapter-3/README.md');
|
||||
assert.equal(LEXED.chapters[0].path,'README.md');
|
||||
assert.equal(LEXED.chapters[1].path,'chapter-1/README.md');
|
||||
assert.equal(LEXED.chapters[2].path,'chapter-2/README.md');
|
||||
assert.equal(LEXED.chapters[3].path,'chapter-3/README.md');
|
||||
});
|
||||
|
||||
it('should detect levels correctly', function() {
|
||||
var c = LEXED.chapters;
|
||||
|
||||
assert.equal(c[0].level, '1');
|
||||
assert.equal(c[1].level, '2');
|
||||
assert.equal(c[2].level, '3');
|
||||
assert.equal(c[0].level, '0');
|
||||
assert.equal(c[1].level, '1');
|
||||
assert.equal(c[2].level, '2');
|
||||
assert.equal(c[3].level, '3');
|
||||
|
||||
assert.equal(c[0].articles[0].level, '1.1');
|
||||
assert.equal(c[0].articles[1].level, '1.2');
|
||||
assert.equal(c[0].articles[1].articles[0].level, '1.2.1');
|
||||
assert.equal(c[1].articles[0].level, '1.1');
|
||||
assert.equal(c[1].articles[1].level, '1.2');
|
||||
assert.equal(c[1].articles[1].articles[0].level, '1.2.1');
|
||||
});
|
||||
});
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,9 +1,13 @@
|
||||
define([
|
||||
"jQuery",
|
||||
"ace/ace",
|
||||
"ace/theme-tomorrow",
|
||||
"ace/mode-javascript",
|
||||
"utils/execute",
|
||||
"core/events",
|
||||
"core/state"
|
||||
], function($, execute, events, state){
|
||||
], function($, _ace, _aceTheme, _aceMode, execute, events, state){
|
||||
|
||||
// Bind an exercise
|
||||
var prepareExercise = function($exercise) {
|
||||
var codeSolution = $exercise.find(".code-solution").text();
|
||||
|
||||
@@ -91,7 +91,7 @@ define([
|
||||
|
||||
// Instantiate font state object
|
||||
fontState = storage.get("fontState", {
|
||||
size: config.size || 1,
|
||||
size: config.size || 2,
|
||||
family: FAMILY[config.family || "sans"],
|
||||
theme: THEMES[config.theme || "white"]
|
||||
});
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
@import "vendors/bootstrap/bootstrap.less";
|
||||
@import "mixins.less";
|
||||
|
||||
@import "ebook/variables.less";
|
||||
@@ -8,20 +7,12 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
article {
|
||||
page-break-after: always;
|
||||
}
|
||||
|
||||
h1 { font-size: floor(@font-size-base * 2.15); }
|
||||
h2 { font-size: floor(@font-size-base * 1.70); }
|
||||
h3 { font-size: ceil(@font-size-base * 1.25); }
|
||||
h4 { font-size: ceil(@font-size-base * 1); }
|
||||
h5 { font-size: ceil(@font-size-base * 0.85); }
|
||||
h6 { font-size: ceil(@font-size-base * 0.65); }
|
||||
|
||||
pre, blockquote {
|
||||
border: 1px solid #999;
|
||||
page-break-inside: avoid;
|
||||
background: #f1f1f1;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
img {
|
||||
@@ -30,7 +21,7 @@ img {
|
||||
margin: 0px auto;
|
||||
}
|
||||
|
||||
.exercise {
|
||||
.exercise, .quiz {
|
||||
margin: 1cm 0cm;
|
||||
padding: 0.4cm;
|
||||
page-break-inside: avoid;
|
||||
@@ -42,4 +33,8 @@ img {
|
||||
padding-bottom: 0.2cm;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.question {
|
||||
margin-top: 0.4cm;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@
|
||||
|
||||
background: @page-background;
|
||||
border-radius: 2px;
|
||||
line-height: 1.5em;
|
||||
line-height: @content-line-height;
|
||||
font-size: @default-font-size;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
|
||||
@@ -44,12 +44,16 @@
|
||||
padding-right: 200px;
|
||||
.transition(margin-left 0.5s ease);
|
||||
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
a, a:hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
@media (max-width: 1000px) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
flex-direction: column;
|
||||
|
||||
font-size: 40px;
|
||||
color: rgba(0,0,0,0.4);
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
|
||||
text-align: center;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
color: rgba(0,0,0,0.6);
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
&.navigation-next {
|
||||
|
||||
@@ -43,6 +43,9 @@
|
||||
@page-color: black;
|
||||
@page-background: @body-background;
|
||||
|
||||
// Content
|
||||
@content-line-height: 1.6em;
|
||||
|
||||
// Progress Bar
|
||||
@chapter-display: none;
|
||||
@chapter-size: 16px;
|
||||
@@ -86,11 +89,12 @@
|
||||
@FontPath: '@{staticPath}/fonts';
|
||||
@fa-font-path: "@{FontPath}/fontawesome";
|
||||
|
||||
@s-font-size: 1.2rem;
|
||||
@m-font-size: 1.4rem;
|
||||
@l-font-size: 1.6rem;
|
||||
@s-font-size: 1.2rem;
|
||||
@m-font-size: 1.4rem;
|
||||
@l-font-size: 1.6rem;
|
||||
@xl-font-size: 2.2rem;
|
||||
@xxl-font-size: 4.0rem;
|
||||
@default-font-size: @l-font-size;
|
||||
|
||||
/*
|
||||
,--------.,--.
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
{% macro articles(_articles) %}
|
||||
{% for item in _articles %}
|
||||
<li class="chapter {% if item._path == _input %}active{% endif %}" data-level="{{ item.level }}" {% if item.path %}data-path="{{ item.path|mdLink }}"{% endif %}>
|
||||
{% set externalLink = item.path|isExternalLink %}
|
||||
<li class="chapter {% if item._path == _input %}active{% endif %}" data-level="{{ item.level }}" {% if item.path && !externalLink %}data-path="{{ item.path|mdLink }}"{% endif %}>
|
||||
{% if item.path %}
|
||||
<a href="{{ basePath }}/{{ item.path|mdLink }}">
|
||||
<i class="fa fa-check"></i> <b>{{ item.level }}.</b> {{ item.title }}
|
||||
</a>
|
||||
{% if !externalLink %}
|
||||
<a href="{{ basePath }}/{{ item.path|mdLink }}">
|
||||
<i class="fa fa-check"></i>
|
||||
{% if item.level !== "0" %}
|
||||
<b>{{ item.level }}.</b>
|
||||
{% endif %}
|
||||
{{ item.title }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a target="_blank" href="{{ item.path }}">
|
||||
<i class="fa fa-check"></i>
|
||||
{% if item.level !== "0" %}
|
||||
<b>{{ item.level }}.</b>
|
||||
{% endif %}
|
||||
{{ item.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span><b>{{ item.level }}.</b> {{ item.title }}</span>
|
||||
{% endif %}
|
||||
@@ -48,9 +63,6 @@
|
||||
<li class="divider"></li>
|
||||
{% endif %}
|
||||
|
||||
<li data-level="0" data-path="index.html">
|
||||
<a href="{{ basePath }}/"><i class="fa fa-check"></i> Introduction</a>
|
||||
</li>
|
||||
{{ articles(summary.chapters) }}
|
||||
|
||||
{% if options.links.gitbook !== false %}
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
{% block style %}
|
||||
<link rel="stylesheet" href="{{ staticBase }}/style.css">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="book-langs-index">
|
||||
<div class="inner">
|
||||
|
||||
@@ -1,54 +1,26 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en-US" {% block htmlTag %}{% endblock %}>
|
||||
{{ htmlSnippet("html:start")|default("") }}
|
||||
<head prefix="og: http://ogp.me/ns# book: http://ogp.me/ns/book#">
|
||||
<head>
|
||||
{{ htmlSnippet("head:start")|default("") }}
|
||||
{% block head %}
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block title %} | {{ title }}{% endblock %}</title>
|
||||
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||||
<meta name="robots" content="index, follow">
|
||||
<meta name="author" content="{{ githubAuthor }}">
|
||||
<meta name="description" content="{{ description }}">
|
||||
<meta name="keywords" content="gitbook,github" >
|
||||
<meta name="generator" content="www.gitbook.io">
|
||||
|
||||
{% if progress.current.next and progress.current.next.path %}
|
||||
<link rel="next" href="{{ basePath }}/{{ progress.current.next.path|mdLink }}" />
|
||||
{% endif %}
|
||||
{% if progress.current.prev and progress.current.prev.path %}
|
||||
<link rel="prev" href="{{ basePath }}/{{ progress.current.prev.path|mdLink }}" />
|
||||
{% endif %}
|
||||
|
||||
<meta property="og:title" content="{% block title %} | {{ title }}{% endblock %}">
|
||||
<meta property="og:site_name" content="{{ title }}">
|
||||
<meta property="og:type" content="book">
|
||||
<meta property="og:locale" content="en_US">
|
||||
|
||||
<meta property="book:author" content="{{ githubHost }}{{ githubAuthor }}">
|
||||
<meta property="book:tag" content="GitBook">
|
||||
|
||||
<meta name="description" content="{% block description %}{% endblock %}">
|
||||
<meta name="generator" content="GitBook {{ gitbook.version }}">
|
||||
<meta name="HandheldFriendly" content="true"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
|
||||
<link rel="shortcut icon" href="{{ staticBase }}/images/favicon.ico" type="image/x-icon">
|
||||
{% endblock %}
|
||||
{% block head %}{% endblock %}
|
||||
{{ htmlSnippet("head:end")|default("") }}
|
||||
</head>
|
||||
<body>
|
||||
{{ htmlSnippet("body:start")|default("") }}
|
||||
{% block style %}
|
||||
<link rel="stylesheet" href="{{ staticBase }}/style.css">
|
||||
{% endblock %}
|
||||
{% block style %}{% endblock %}
|
||||
{% block content %}{% endblock %}
|
||||
{% block javascript %}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/ace.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/mode-javascript.js"></script>
|
||||
<script src="{{ staticBase }}/jsrepl/jsrepl.js" id="jsrepl-script"></script>
|
||||
<script src="{{ staticBase }}/app.js"></script>
|
||||
{% endblock %}
|
||||
{% block javascript %}{% endblock %}
|
||||
{{ htmlSnippet("body:end")|default("") }}
|
||||
</body>
|
||||
{{ htmlSnippet("html:end")|default("") }}
|
||||
|
||||
@@ -20,9 +20,14 @@
|
||||
</div>
|
||||
{% elif section.type == "quiz" %}
|
||||
<div class="quiz">
|
||||
<div class="exercise-header">Exercise #{{ exercise }}</div>
|
||||
<div class="exercise-header">Quiz #{{ exercise }}</div>
|
||||
{% autoescape false %}{{ section.content }}{% endautoescape %}
|
||||
{% autoescape false %}{{ section.quiz.base }}{% endautoescape %}
|
||||
{% for quiz in section.quiz %}
|
||||
<div class="question">
|
||||
<div class="question-header">Question {{ loop.index }} of {{ section.quiz.length }}</div>
|
||||
{% autoescape false %}{{ quiz.base }}{% endautoescape %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% set exercise = exercise + 1 %}
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -47,6 +52,7 @@
|
||||
{% set exercise = 1 %}
|
||||
<article>
|
||||
<h1 class="book-chapter book-chapter-1">Exercise Solutions</h1>
|
||||
<h1>Exercise Solutions</h1>
|
||||
|
||||
{% for item in progress.chapters %}
|
||||
{% if pages[item.path] %}
|
||||
@@ -60,9 +66,14 @@
|
||||
</div>
|
||||
{% elif section.type == "quiz" %}
|
||||
<div class="quiz">
|
||||
<div class="exercise-header">Exercise #{{ exercise }}</div>
|
||||
<div class="exercise-header">Quiz #{{ exercise }}</div>
|
||||
{% autoescape false %}{{ section.content }}{% endautoescape %}
|
||||
{% autoescape false %}{{ section.quiz.solution }}{% endautoescape %}
|
||||
{% for quiz in section.quiz %}
|
||||
<div class="question">
|
||||
<div class="question-header">Question {{ loop.index }} of {{ section.quiz.length }}</div>
|
||||
{% autoescape false %}{{ quiz.solution }}{% endautoescape %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% set exercise = exercise + 1 %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,7 +1,23 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block htmlTag %}{% if options.cache !== false %}manifest="{{ basePath }}/manifest.appcache"{% endif %}{% endblock %}
|
||||
{% block title %}{{ progress.current.title }}{% parent %}{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
{% parent %}
|
||||
{% if githubAuthor %}
|
||||
<meta name="author" content="{{ githubAuthor }}">
|
||||
{% endif %}
|
||||
{% if progress.current.next and progress.current.next.path %}
|
||||
<link rel="next" href="{{ basePath }}/{{ progress.current.next.path|mdLink }}" />
|
||||
{% endif %}
|
||||
{% if progress.current.prev and progress.current.prev.path %}
|
||||
<link rel="prev" href="{{ basePath }}/{{ progress.current.prev.path|mdLink }}" />
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}{{ progress.current.title }} | {{ title }}{% endblock %}
|
||||
{% block description %}{% if progress.current.level == "0" %}{{ description }}{% endif %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="book" {% if githubId %}data-github="{{ githubId }}"{% endif %} data-level="{{ progress.current.level }}" data-basepath="{{ basePath }}" data-revision="{{ revision }}">
|
||||
{% include "includes/book/header.html" %}
|
||||
@@ -38,7 +54,8 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block javascript %}
|
||||
{% parent %}
|
||||
<script src="{{ staticBase }}/jsrepl/jsrepl.js" id="jsrepl-script"></script>
|
||||
<script src="{{ staticBase }}/app.js"></script>
|
||||
{% for resource in plugins.resources.js %}
|
||||
{% if resource.url %}
|
||||
<script src="{{ resource.url }}"></script>
|
||||
@@ -55,7 +72,7 @@ require(["gitbook"], function(gitbook) {
|
||||
{% endblock %}
|
||||
|
||||
{% block style %}
|
||||
{% parent %}
|
||||
<link rel="stylesheet" href="{{ staticBase }}/style.css">
|
||||
{% for resource in plugins.resources.css %}
|
||||
{% if resource.url %}
|
||||
<link rel="stylesheet" href="{{ resource.url }}">
|
||||
|
||||
Reference in New Issue
Block a user