mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-26 20:27:00 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0feb672d70 | |||
| 2a4ef5bbf4 | |||
| c4540332a7 | |||
| 2104404cb3 | |||
| 002d685ebb | |||
| 1e4632080b | |||
| 5191106396 | |||
| 6ab5cafaf3 | |||
| d1c0cb9c71 | |||
| 38c750101c | |||
| ba0f379a89 | |||
| 1d9509b3b6 | |||
| 3c8de4a8ab | |||
| 591d8fc9ee | |||
| d480e9cea4 | |||
| 32a71869da | |||
| fdbfda64a6 | |||
| a6f48be39e | |||
| ce50b893e9 | |||
| 225ff27dd1 | |||
| 52e8361846 |
+10
@@ -1,5 +1,15 @@
|
||||
# Release notes
|
||||
|
||||
## 1.3.0
|
||||
- Bundle gitbook parsing library as a client side library in `gitbook.js` and `gitbook.min.js`
|
||||
|
||||
## 1.2.0
|
||||
- Improvements on ebook generation
|
||||
- Fix incorrect follow of links in ebook generation
|
||||
- Move Table of Contents at the beginning of the ebook
|
||||
- Update to last highlight.js (includes Swift)
|
||||
- Includes of templates and variables (from book.json)
|
||||
|
||||
## 1.1.1
|
||||
- Rewrite quiz logic to be more robust
|
||||
- Improve integration of glossary
|
||||
|
||||
+34
-1
@@ -6,6 +6,8 @@ module.exports = function (grunt) {
|
||||
grunt.loadNpmTasks('grunt-contrib-less');
|
||||
grunt.loadNpmTasks('grunt-contrib-requirejs');
|
||||
grunt.loadNpmTasks("grunt-bower-install-simple");
|
||||
grunt.loadNpmTasks('grunt-browserify');
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
|
||||
// Init GRUNT configuraton
|
||||
grunt.initConfig({
|
||||
@@ -77,6 +79,30 @@ module.exports = function (grunt) {
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
browserify: {
|
||||
dist: {
|
||||
files: {
|
||||
'gitbook.js': [
|
||||
'./lib/parse/index.js'
|
||||
],
|
||||
},
|
||||
options: {
|
||||
postBundleCB: function (err, src, next) {
|
||||
return next(null, '(function () { var define = undefined; '+src+'; })();')
|
||||
},
|
||||
browserifyOptions: {
|
||||
'standalone': "gitbook"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
uglify: {
|
||||
dist: {
|
||||
files: {
|
||||
'gitbook.min.js': ['gitbook.js']
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -90,7 +116,14 @@ module.exports = function (grunt) {
|
||||
'copy:vendors'
|
||||
]);
|
||||
|
||||
// Bundle the library
|
||||
grunt.registerTask('bundle', [
|
||||
'bower-install',
|
||||
'uglify'
|
||||
]);
|
||||
|
||||
grunt.registerTask('default', [
|
||||
'build'
|
||||
'build',
|
||||
'bundle'
|
||||
]);
|
||||
};
|
||||
@@ -74,6 +74,9 @@ Here are the options that can be stored in this file:
|
||||
}
|
||||
},
|
||||
|
||||
// Variables for templating
|
||||
"variables": {},
|
||||
|
||||
// Links in template (null: default, false: remove, string: new value)
|
||||
"links": {
|
||||
// Custom links at top of sidebar
|
||||
@@ -94,9 +97,6 @@ Here are the options that can be stored in this file:
|
||||
|
||||
// Options for PDF generation
|
||||
"pdf": {
|
||||
// Add toc at the end of the file
|
||||
"toc": true,
|
||||
|
||||
// Add page numbers to the bottom of every page
|
||||
"pageNumbers": false,
|
||||
|
||||
@@ -209,7 +209,7 @@ The platform [GitBook.io](https://www.gitbook.io/) is like an "Heroku for books"
|
||||
|
||||
#### Plugins
|
||||
|
||||
Plugins can used to extend your book's functionality. Read [GitbookIO/plugin](https://github.com/GitbookIO/plugin) for more information about how to build a plugin for GitBook.
|
||||
Plugins can be used to extend your book's functionality. Read [GitbookIO/plugin](https://github.com/GitbookIO/plugin) for more information about how to build a plugin for GitBook.
|
||||
|
||||
##### Official plugins:
|
||||
|
||||
@@ -219,6 +219,7 @@ Plugins can used to extend your book's functionality. Read [GitbookIO/plugin](ht
|
||||
| [quizzes](https://github.com/GitbookIO/plugin-quizzes) | Add interactive quizzes to your book. |
|
||||
| [mathjax](https://github.com/GitbookIO/plugin-mathjax) | Displays mathematical notation in the book. |
|
||||
| [mixpanel](https://github.com/GitbookIO/plugin-mixpanel) | Mixpanel tracking for your book |
|
||||
| [infinitescroll](https://github.com/GitbookIO/gitbook-plugin-infinitescroll) | Infinite Scrolling |
|
||||
|
||||
##### Other plugins:
|
||||
|
||||
|
||||
+20719
File diff suppressed because one or more lines are too long
Vendored
+10
File diff suppressed because one or more lines are too long
@@ -38,6 +38,9 @@ var CONFIG = {
|
||||
}
|
||||
},
|
||||
|
||||
// Variables for templating
|
||||
"variables": {},
|
||||
|
||||
// Set another theme with your own layout
|
||||
// It's recommended to use plugins or add more options for default theme, though
|
||||
// See https://github.com/GitbookIO/gitbook/issues/209
|
||||
|
||||
@@ -39,7 +39,8 @@ Generator.prototype.finish = function() {
|
||||
"--level2-toc": "descendant-or-self::*[contains(concat(' ', normalize-space(@class), ' '), ' book-chapter-2 ')]",
|
||||
"--level3-toc": "descendant-or-self::*[contains(concat(' ', normalize-space(@class), ' '), ' book-chapter-3 ')]",
|
||||
"--no-chapters-in-toc": true,
|
||||
"--max-levels": "1000"
|
||||
"--max-levels": "1",
|
||||
"--breadth-first": true
|
||||
};
|
||||
|
||||
if (format == "pdf") {
|
||||
@@ -50,7 +51,6 @@ Generator.prototype.finish = function() {
|
||||
"--margin-right": String(pdfOptions.margin.right),
|
||||
"--margin-top": String(pdfOptions.margin.top),
|
||||
"--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),
|
||||
@@ -62,7 +62,7 @@ Generator.prototype.finish = function() {
|
||||
|
||||
var command = [
|
||||
"ebook-convert",
|
||||
path.join(that.options.output, "index.html"),
|
||||
path.join(that.options.output, "SUMMARY.html"),
|
||||
path.join(that.options.output, "index."+format),
|
||||
stringUtils.optionsToShellArgs(_options)
|
||||
].join(" ");
|
||||
|
||||
@@ -74,4 +74,5 @@ module.exports = {
|
||||
fs.exists(path, d.resolve);
|
||||
return d.promise;
|
||||
},
|
||||
readFileSync: fs.readFileSync.bind(fs)
|
||||
};
|
||||
|
||||
@@ -20,6 +20,11 @@ BaseGenerator.prototype.callHook = function(name, data) {
|
||||
return this.plugins.hook(name, data);
|
||||
};
|
||||
|
||||
// Sets up generator
|
||||
BaseGenerator.prototype.load = function() {
|
||||
return this.loadPlugins();
|
||||
};
|
||||
|
||||
BaseGenerator.prototype.loadPlugins = function() {
|
||||
var that = this;
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ var loadGenerator = function(options) {
|
||||
.then(function() {
|
||||
var generator = new generators[options.generator](options);
|
||||
|
||||
return generator.loadPlugins()
|
||||
return generator.load()
|
||||
.then(_.constant(generator));
|
||||
});
|
||||
};
|
||||
|
||||
@@ -21,8 +21,23 @@ util.inherits(Generator, BaseGenerator);
|
||||
|
||||
Generator.prototype.loadTemplates = function() {
|
||||
this.template = swig.compileFile(
|
||||
this.plugins.template("page") || path.resolve(this.options.theme, 'templates/page.html')
|
||||
this.plugins.template("ebook:page") || path.resolve(this.options.theme, 'templates/ebook/page.html')
|
||||
);
|
||||
this.summaryTemplate = swig.compileFile(
|
||||
this.plugins.template("ebook:sumary") || path.resolve(this.options.theme, 'templates/ebook/summary.html')
|
||||
);
|
||||
};
|
||||
|
||||
// Generate table of contents
|
||||
Generator.prototype.writeToc = function() {
|
||||
var that = this;
|
||||
var basePath = ".";
|
||||
|
||||
return this._writeTemplate(this.summaryTemplate, {
|
||||
toc: parse.progress(this.options.navigation, "README.md").chapters,
|
||||
basePath: basePath,
|
||||
staticBase: path.join(basePath, "gitbook"),
|
||||
}, path.join(this.options.output, "SUMMARY.html"));
|
||||
};
|
||||
|
||||
Generator.prototype.finish = function() {
|
||||
@@ -34,6 +49,11 @@ Generator.prototype.finish = function() {
|
||||
|
||||
return Q()
|
||||
|
||||
// Write table of contents
|
||||
.then(function() {
|
||||
return that.writeToc();
|
||||
})
|
||||
|
||||
// Copy cover
|
||||
.then(function() {
|
||||
return that.copyCover();
|
||||
|
||||
+27
-23
@@ -23,29 +23,29 @@ var Generator = function() {
|
||||
};
|
||||
util.inherits(Generator, BaseGenerator);
|
||||
|
||||
// Load all templates
|
||||
Generator.prototype.loadTemplates = function() {
|
||||
this.template = swig.compileFile(
|
||||
this.plugins.template("site") || path.resolve(this.options.theme, 'templates/site.html')
|
||||
);
|
||||
this.langsTemplate = swig.compileFile(
|
||||
this.plugins.template("langs") || path.resolve(this.options.theme, 'templates/langs.html')
|
||||
);
|
||||
this.glossaryTemplate = swig.compileFile(
|
||||
this.plugins.template("glossary") || path.resolve(this.options.theme, 'templates/glossary.html')
|
||||
);
|
||||
};
|
||||
|
||||
// Load plugins
|
||||
Generator.prototype.loadPlugins = function() {
|
||||
// Add template loading to load
|
||||
Generator.prototype.load = function() {
|
||||
var that = this;
|
||||
|
||||
return BaseGenerator.prototype.loadPlugins.apply(this)
|
||||
return BaseGenerator.prototype.load.apply(this)
|
||||
.then(function() {
|
||||
return that.loadTemplates();
|
||||
});
|
||||
};
|
||||
|
||||
// Load all templates
|
||||
Generator.prototype.loadTemplates = function() {
|
||||
this.template = swig.compileFile(
|
||||
this.plugins.template("site:page") || path.resolve(this.options.theme, 'templates/book/page.html')
|
||||
);
|
||||
this.langsTemplate = swig.compileFile(
|
||||
this.plugins.template("site:langs") || path.resolve(this.options.theme, 'templates/book/langs.html')
|
||||
);
|
||||
this.glossaryTemplate = swig.compileFile(
|
||||
this.plugins.template("site:glossary") || path.resolve(this.options.theme, 'templates/book/glossary.html')
|
||||
);
|
||||
};
|
||||
|
||||
// Generate a template
|
||||
Generator.prototype._writeTemplate = function(tpl, options, output, interpolate) {
|
||||
var that = this;
|
||||
@@ -118,16 +118,20 @@ Generator.prototype.prepareFile = function(content, _input) {
|
||||
return _callHook("page:before");
|
||||
})
|
||||
.then(function() {
|
||||
// Lex page
|
||||
return parse.lex(page.content);
|
||||
})
|
||||
.then(function(lexed) {
|
||||
page.lexed = lexed;
|
||||
|
||||
// Lex, parse includes and get
|
||||
// Get HTML generated sections
|
||||
return parse.page(lexed, {
|
||||
return parse.page(page.content, {
|
||||
// Local files path
|
||||
dir: path.dirname(_input) || '/',
|
||||
|
||||
// Output directory
|
||||
outdir: path.dirname(_input) || '/',
|
||||
|
||||
// Includer for templating
|
||||
includer: parse.includer(that.options.variables, [
|
||||
path.dirname(_input) || '/',
|
||||
path.join(that.options.input, '_includes'),
|
||||
], path.join, fs.readFileSync)
|
||||
});
|
||||
})
|
||||
.then(function(sections) {
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
var fs = require('graceful-fs');
|
||||
var path = require('path');
|
||||
|
||||
module.exports = function(code, folder) {
|
||||
folder = folder || '';
|
||||
|
||||
return code.replace(/{{([\s\S]+?)}}/g, function(match, filename) {
|
||||
// Normalize filename
|
||||
var fname = path.join(folder, filename.trim());
|
||||
|
||||
// Try including snippet from FS
|
||||
try {
|
||||
// Trim trailing newlines/space of imported snippets
|
||||
return fs.readFileSync(fname, 'utf8').trimRight();
|
||||
} catch(err) {}
|
||||
|
||||
// If fails leave content as is
|
||||
return match;
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
var _ = require('lodash');
|
||||
|
||||
module.exports = function(markdown, includer) {
|
||||
// Memoized include function (to cache lookups)
|
||||
var _include = _.memoize(includer);
|
||||
|
||||
return markdown.replace(/{{([\s\S]+?)}}/g, function(match, key) {
|
||||
// If fails leave content as is
|
||||
key = key.trim();
|
||||
return _include(key) || match;
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
// Return a fs inclduer
|
||||
module.exports = function(ctx, folders, resolveFile, readFile) {
|
||||
return function(name) {
|
||||
return ctx[name] ||
|
||||
folders.map(function(folder) {
|
||||
// Try including snippet from FS
|
||||
try {
|
||||
var fname = resolveFile(folder, name);
|
||||
// Trim trailing newlines/space of imported snippets
|
||||
return readFile(fname, 'utf8').trimRight();
|
||||
} catch(err) {}
|
||||
})
|
||||
.filter(Boolean)[0];
|
||||
}
|
||||
};
|
||||
+2
-1
@@ -6,5 +6,6 @@ module.exports = {
|
||||
lex: require('./lex'),
|
||||
progress: require('./progress'),
|
||||
navigation: require('./navigation'),
|
||||
readme: require('./readme')
|
||||
readme: require('./readme'),
|
||||
includer: require('./includer')
|
||||
};
|
||||
|
||||
+5
-10
@@ -5,7 +5,7 @@ var hljs = require('highlight.js');
|
||||
var lex = require('./lex');
|
||||
var renderer = require('./renderer');
|
||||
|
||||
var codeInclude = require('./code_include');
|
||||
var include = require('./include');
|
||||
var lnormalize = require('../utils/lang').normalize;
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ function parsePage(src, options) {
|
||||
options = options || {};
|
||||
|
||||
// Lex if not already lexed
|
||||
return (_.isArray(src) ? src : lex(src))
|
||||
return (_.isArray(src) ? src : lex(include(src, options.includer || function() { return undefined; })))
|
||||
.map(function(section) {
|
||||
// Transform given type
|
||||
if(section.type === 'exercise') {
|
||||
@@ -74,20 +74,15 @@ function parsePage(src, options) {
|
||||
// Main language
|
||||
var lang = validLangs ? langs[0] : null;
|
||||
|
||||
// codeInclude shortcut
|
||||
var ci = function(code) {
|
||||
return codeInclude(code, options.dir);
|
||||
};
|
||||
|
||||
return {
|
||||
id: section.id,
|
||||
type: section.type,
|
||||
content: render(nonCodeNodes, options),
|
||||
lang: lang,
|
||||
code: {
|
||||
base: ci(codeNodes[0].text),
|
||||
solution: ci(codeNodes[1].text),
|
||||
validation: ci(codeNodes[2].text),
|
||||
base: codeNodes[0].text,
|
||||
solution: codeNodes[1].text,
|
||||
validation: codeNodes[2].text,
|
||||
// Context is optional
|
||||
context: codeNodes[3] ? codeNodes[3].text : null,
|
||||
}
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
var url = require('url');
|
||||
var _ = require('lodash');
|
||||
var inherits = require('util').inherits;
|
||||
var links = require('../utils').links;
|
||||
var codeInclude = require('./code_include');
|
||||
|
||||
|
||||
var path = require('path');
|
||||
|
||||
var kramed = require('kramed');
|
||||
|
||||
var rendererId = 0;
|
||||
@@ -52,11 +48,11 @@ GitBookRenderer.prototype.link = function(href, title, text) {
|
||||
|
||||
// Parsed version of the url
|
||||
var parsed = url.parse(href);
|
||||
|
||||
var o = this._extra_options;
|
||||
var extname = _.last(parsed.path.split("."));
|
||||
|
||||
// Relative link, rewrite it to point to github repo
|
||||
if(links.isRelative(_href) && path.extname(parsed.path) == ".md") {
|
||||
if(links.isRelative(_href) && extname == "md") {
|
||||
_href = links.toAbsolute(_href, o.dir || "./", o.outdir || "./");
|
||||
_href = _href.replace(".md", ".html");
|
||||
}
|
||||
@@ -130,8 +126,7 @@ GitBookRenderer.prototype.listitem = function(text) {
|
||||
GitBookRenderer.prototype.code = function(code, lang, escaped) {
|
||||
return GitBookRenderer.super_.prototype.code.call(
|
||||
this,
|
||||
// Import code snippets
|
||||
codeInclude(code, this._extra_options.dir),
|
||||
code,
|
||||
lang,
|
||||
escaped
|
||||
);
|
||||
|
||||
+2
-2
@@ -11,8 +11,8 @@ function escapeShellArg(arg) {
|
||||
function optionsToShellArgs(options) {
|
||||
return _.chain(options)
|
||||
.map(function(value, key) {
|
||||
if (value == null || value == false) return null;
|
||||
if (value == true) return key;
|
||||
if (value == null || value === false) return null;
|
||||
if (value === true) return key;
|
||||
return key+"="+escapeShellArg(value);
|
||||
})
|
||||
.compact()
|
||||
|
||||
+5
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gitbook",
|
||||
"version": "1.1.1",
|
||||
"version": "1.3.0",
|
||||
"homepage": "http://www.gitbook.io/",
|
||||
"description": "Library and cmd utility to generate GitBooks",
|
||||
"main": "lib/index.js",
|
||||
@@ -16,7 +16,7 @@
|
||||
"commander": "2.2.0",
|
||||
"graceful-fs": "3.0.2",
|
||||
"fs-extra": "0.10.0",
|
||||
"highlight.js": "8.2.0",
|
||||
"highlight.js": "8.3.0",
|
||||
"tmp": "0.0.23",
|
||||
"semver": "2.2.1",
|
||||
"gaze": "~0.5.1",
|
||||
@@ -35,7 +35,9 @@
|
||||
"grunt-contrib-copy": "0.5.0",
|
||||
"grunt-contrib-less": "~0.5.0",
|
||||
"grunt-contrib-requirejs": "0.4.1",
|
||||
"grunt-bower-install-simple": "0.9.2"
|
||||
"grunt-bower-install-simple": "0.9.2",
|
||||
"grunt-browserify": "3.1.0",
|
||||
"grunt-contrib-uglify": "0.6.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "export TESTING=true; mocha --reporter list"
|
||||
|
||||
@@ -3,6 +3,7 @@ var path = require('path');
|
||||
var assert = require('assert');
|
||||
|
||||
var page = require('../').parse.page;
|
||||
var includer = require('../').parse.includer;
|
||||
|
||||
var FIXTURES_DIR = path.join(__dirname, './fixtures/');
|
||||
|
||||
@@ -16,6 +17,9 @@ describe('Code includes', function() {
|
||||
|
||||
var LEXED = loadPage('INCLUDES', {
|
||||
'dir': FIXTURES_DIR,
|
||||
'includer': includer({}, [
|
||||
FIXTURES_DIR
|
||||
], path.join, fs.readFileSync)
|
||||
});
|
||||
|
||||
var INCLUDED_C = fs.readFileSync(path.join(FIXTURES_DIR, 'included.c'), 'utf8');
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -256,7 +256,8 @@
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ol ul {
|
||||
ol ul,
|
||||
ul ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
@import "ebook/highlight.less";
|
||||
|
||||
.page {
|
||||
&.page-toc {
|
||||
ol {
|
||||
margin: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.book-chapter {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% extends "site.html" %}
|
||||
{% extends "page.html" %}
|
||||
|
||||
{% block title %}Glossary | {{ title }}{% endblock %}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% extends "layout.html" %}
|
||||
{% extends "../layout.html" %}
|
||||
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% extends "layout.html" %}
|
||||
{% extends "../layout.html" %}
|
||||
|
||||
{% block head %}
|
||||
{% parent %}
|
||||
@@ -15,10 +15,10 @@
|
||||
|
||||
{% block content %}
|
||||
<div class="book" data-level="{{ progress.current.level }}" data-basepath="{{ basePath }}" data-revision="{{ revision }}">
|
||||
{% include "includes/book/summary.html" %}
|
||||
{% include "includes/summary.html" %}
|
||||
<div class="book-body">
|
||||
<div class="body-inner">
|
||||
{% include "includes/book/header.html" %}
|
||||
{% include "includes/header.html" %}
|
||||
<div class="page-wrapper" tabindex="-1">
|
||||
<div class="page-inner">
|
||||
{% block page_inner %}
|
||||
@@ -27,9 +27,9 @@
|
||||
{% if section.type == "normal" %}
|
||||
{% autoescape false %}{{ section.content }}{% endautoescape %}
|
||||
{% elif section.type == "exercise" %}
|
||||
{% include "./includes/book/exercise.html" with {section: section} %}
|
||||
{% include "./includes/exercise.html" with {section: section} %}
|
||||
{% elif section.type == "quiz" %}
|
||||
{% include "./includes/book/quiz.html" with {section: section} %}
|
||||
{% include "./includes/quiz.html" with {section: section} %}
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endfor %}
|
||||
@@ -1,4 +1,4 @@
|
||||
{% extends "layout.html" %}
|
||||
{% extends "../layout.html" %}
|
||||
|
||||
{% block title %}{{ progress.current.title }} | {{ title }}{% endblock %}
|
||||
|
||||
@@ -21,16 +21,12 @@
|
||||
{% if section.type == "normal" %}
|
||||
{% autoescape false %}{{ section.content }}{% endautoescape %}
|
||||
{% elif section.type == "exercise" %}
|
||||
{% include "./includes/page/exercise.html" with {section: section} %}
|
||||
{% include "./includes/exercise.html" with {section: section} %}
|
||||
{% elif section.type == "quiz" %}
|
||||
{% include "./includes/page/quiz.html" with {section: section} %}
|
||||
{% include "./includes/quiz.html" with {section: section} %}
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endfor %}
|
||||
|
||||
{% if progress.current.next and progress.current.next.path %}
|
||||
<a href="{{ basePath }}/{{ progress.current.next.path|mdLink }}" />
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
{% extends "../layout.html" %}
|
||||
|
||||
{% block title %}Table of Contents | {{ title }}{% endblock %}
|
||||
|
||||
{% block style %}
|
||||
<link rel="stylesheet" href="{{ staticBase }}/print.css">
|
||||
{% for resource in plugins.resources.css %}
|
||||
{% if resource.url %}
|
||||
<link rel="stylesheet" href="{{ resource.url }}">
|
||||
{% else %}
|
||||
<link rel="stylesheet" href="{{ staticBase }}/plugins/{{ resource.path }}">
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% macro articles(_articles) %}
|
||||
{% for item in _articles %}
|
||||
{% set externalLink = item.path|isExternalLink %}
|
||||
<li>
|
||||
{% if item.path %}
|
||||
{% if !externalLink %}
|
||||
<a href="{{ basePath }}/{{ item.path|mdLink }}">{{ item.title }}</a>
|
||||
{% else %}
|
||||
<a target="_blank" href="{{ item.path }}">{{ item.title }}</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{{ item.title }}
|
||||
{% endif %}
|
||||
{% if item.articles.length > 0 %}
|
||||
<ol>
|
||||
{{ articles(item.articles) }}
|
||||
</ol>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
{% block content %}
|
||||
<div class="page page-toc">
|
||||
<h1>Table of Contents</h1>
|
||||
<ol>
|
||||
{{ articles(summary.chapters) }}
|
||||
</ol>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user