mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-26 20:27:00 +00:00
Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dd250e0339 | |||
| 741b158631 | |||
| 843889303e | |||
| 4ad2b040b4 | |||
| f5916b5c59 | |||
| d9da4e9a08 | |||
| 1d0f6370ad | |||
| e4127d961e | |||
| 8e97655040 | |||
| 9b61b87873 | |||
| 4a99e37b2f | |||
| 752b5e9b7c | |||
| b318f2fe94 | |||
| 01c46030b6 | |||
| 9803b05d8a | |||
| 1337858fe6 | |||
| 925b9e88ad | |||
| 7305011a8b | |||
| 489f23f74e | |||
| 370799ac55 | |||
| 4a9adb9440 | |||
| d8898b7a1f | |||
| bb7e081a37 | |||
| c3ffa5e0ef | |||
| 724bc2b59c | |||
| 178d2e2a48 | |||
| 4d710c129c | |||
| e4dbf62c0f | |||
| b0cd23fd34 | |||
| af5764bc3b | |||
| 6309da1214 | |||
| 38c9bfa357 | |||
| f194cb513c | |||
| 03ff892727 | |||
| 8cc0f64f54 | |||
| 532e8b0388 | |||
| 35b3d50012 | |||
| 72ff9996ce | |||
| 0759c4dd78 | |||
| 82a1a151e4 | |||
| ff6e8387fb | |||
| f71601e8d3 | |||
| 234a37726f | |||
| 65a7979874 | |||
| 6a00bf0fc0 | |||
| 853f3d6482 | |||
| 27de7cd914 | |||
| 2318cae1e6 |
+26
-4
@@ -7,12 +7,34 @@ Names below are ordered by first contribution.
|
||||
Author
|
||||
------
|
||||
|
||||
- Samy Pessé <samypesse@gmail.com>
|
||||
- Aaron O'Mullan <aaron.omullan@gmail.com>
|
||||
- Samy Pessé <samypesse@gmail.com> (@SamyPesse)
|
||||
- Aaron O'Mullan <aaron.omullan@gmail.com> (@AaronO)
|
||||
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
- Nijiko Yonskai
|
||||
- Herman Starikov
|
||||
- Nijiko Yonskai (@Nijikokun)
|
||||
- Herman Starikov (@Hermanya)
|
||||
|
||||
Translators
|
||||
------------
|
||||
|
||||
- German
|
||||
- Winnie (@winniehell)
|
||||
- Italian
|
||||
- Giulio Bonanome (@gbonanome)
|
||||
- Russian
|
||||
- Andrey Akinshin (@AndreyAkinshin)
|
||||
- Norwegian
|
||||
- Knut Melvær (@kmelve)
|
||||
- Portuguese
|
||||
- Ryan O'Mullan (@RyanOM)
|
||||
- Spanish
|
||||
- Ryan O'Mullan (@RyanOM)
|
||||
- Simplifiled Chinese
|
||||
- Hu Hao (@howiehu)
|
||||
- Traditional Chinese
|
||||
- Hu Hao (@howiehu)
|
||||
- French
|
||||
- Samy Pessé (@SamyPesse)
|
||||
|
||||
+35
@@ -1,5 +1,40 @@
|
||||
# Release notes
|
||||
|
||||
## 2.0.0-alpha.6
|
||||
- Add es and pt translations
|
||||
- Fix replacement of glossary terms
|
||||
|
||||
## 2.0.0-alpha.5
|
||||
- Fix copy of files/covers
|
||||
- Add back `finish:before` hook
|
||||
|
||||
## 2.0.0-alpha.4
|
||||
- Fix copy of cover for multilingal books
|
||||
|
||||
## 2.0.0-alpha.3
|
||||
- Norwegian translation
|
||||
- Load plugins from book in priority
|
||||
|
||||
## 2.0.0-alpha.3
|
||||
- Fix init command
|
||||
- Update parsers to fix spaces in summary (`gitbook-parsers@0.3.1`)
|
||||
|
||||
## 2.0.0-alpha.1
|
||||
- Externalize parsing into `gitbook-parsers` module
|
||||
- Supports AsciiDoc and reStructuredText
|
||||
- Hooks for page (`page:*`) are now deprecated, plugins should extend filters and blocks instead
|
||||
- Hooks `summary` and `glossary` (after and before) have been removed
|
||||
- Exercises and Quizzes are no longer parsed in the markdown parser
|
||||
- Support for more markdown extensions: `.markdown`, `.mdown`
|
||||
- Templates are rendered with nunjucks instead of swig, syntax is almost compatible, there is some changes with contexts and filters. `{{ super() }}` should be use instead of `{% parent %}`
|
||||
- Clean output folder on build without removing `.git` and `.svn`
|
||||
- MathJAX is no longer a default plugin
|
||||
- SVG images are converted to PNG during generation of ebooks
|
||||
- i18n in website and ebook (ru, it, de, fr)
|
||||
- New templating syntax
|
||||
- Content references (both internal and external)
|
||||
- Glossary terms are handled during generation (also in ebook format)
|
||||
|
||||
## 1.5.0
|
||||
- Fix `serve` command, broken by `1.4.2`
|
||||
- Add nicer `dark` theme :)
|
||||
|
||||
@@ -199,36 +199,8 @@ The platform [GitBook.com](https://www.gitbook.com/) is like an "Heroku for book
|
||||
|
||||
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.
|
||||
|
||||
Plugins needed to build a book can be installed using: `gitbook install ./`.
|
||||
Plugins needed to build a book can be installed using: `gitbook install ./`. You can find plugins at [plugins.gitbook.com](plugins.gitbook.com).
|
||||
|
||||
##### Official plugins:
|
||||
|
||||
| Name | Description |
|
||||
| ----- | ---- |
|
||||
| [exercises](https://github.com/GitbookIO/plugin-exercises) | Add interactive exercises to your book. |
|
||||
| [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:
|
||||
|
||||
| Name | Description |
|
||||
| ----- | ---- |
|
||||
| [Google Analytics](https://github.com/GitbookIO/plugin-ga) | Google Analytics tracking for your book |
|
||||
| [Disqus](https://github.com/GitbookIO/plugin-disqus) | Disqus comments integration in your book |
|
||||
| [Autocover](https://github.com/GitbookIO/plugin-autocover) | Generate a cover for your book |
|
||||
| [Transform annoted quotes to notes](https://github.com/erixtekila/gitbook-plugin-richquotes) | Allow extra markdown markup to render blockquotes as nice notes |
|
||||
| [Send code to console](https://github.com/erixtekila/gitbook-plugin-toconsole) | Evaluate javascript block in the browser inspector's console |
|
||||
| [Revealable sections](https://github.com/mrpotes/gitbook-plugin-reveal) | Reveal sections of the page using buttons made from the first title in each section |
|
||||
| [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 |
|
||||
| [Heading Anchors](https://github.com/rlmv/gitbook-plugin-anchors) | Add linkable Github-style anchors to headings |
|
||||
| [JSBin](https://github.com/jcouyang/gitbook-plugin-jsbin) | Embedded jsbin frame into your book |
|
||||
| [GrVis](https://github.com/romanlytkin/gitbook-grvis) | Gitbook GrViz plugin is used to select from markdown dot and converting it into a picture format svg |
|
||||
| [PlantUml](https://github.com/romanlytkin/gitbook-plantuml) | Gitbook PlantUml plugin is used to select from markdown uml and converting it into a picture format svg |
|
||||
| [Mermaid](https://github.com/JozoVilcek/gitbook-plugin-mermaid) | Adds diagrams and flowcharts rendered by [mermaid](https://github.com/knsv/mermaid) |
|
||||
|
||||
## Debugging
|
||||
|
||||
|
||||
+32
-19
@@ -117,7 +117,7 @@ Book.prototype.parse = function() {
|
||||
path.join(that.root, lang.path),
|
||||
_.merge({}, that.context, {
|
||||
config: _.extend({}, that.options, {
|
||||
'output': path.join(that.options.output, lang.path),
|
||||
'output': path.join(that.options.output, lang.lang),
|
||||
'language': lang.lang
|
||||
})
|
||||
}),
|
||||
@@ -185,8 +185,6 @@ Book.prototype.generate = function(generator) {
|
||||
return generator.prepare();
|
||||
})
|
||||
|
||||
|
||||
|
||||
// Generate content
|
||||
.then(function() {
|
||||
if (that.isMultilingual()) {
|
||||
@@ -263,9 +261,6 @@ Book.prototype.generateMultiLingual = function(generator) {
|
||||
return book.generate(that.options.generator);
|
||||
});
|
||||
}, Q());
|
||||
})
|
||||
.then(function() {
|
||||
return generator.langsIndex(that.langs);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -280,9 +275,7 @@ Book.prototype.generateFile = function(output, options) {
|
||||
|
||||
return fs.tmp.dir()
|
||||
.then(function(tmpDir) {
|
||||
book.config.extend({
|
||||
output: tmpDir
|
||||
});
|
||||
book.setOutput(tmpDir);
|
||||
|
||||
return book.generate(options.ebookFormat)
|
||||
.then(function(_options) {
|
||||
@@ -295,14 +288,11 @@ Book.prototype.generateFile = function(output, options) {
|
||||
_tmpDir = path.join(_tmpDir, lang);
|
||||
}
|
||||
|
||||
book.log.info("copy ebook to", output, "...");
|
||||
book.log.debug.ln("copy ebook to", _outputFile);
|
||||
return fs.copy(
|
||||
path.join(_tmpDir, "index."+options.ebookFormat),
|
||||
_outputFile
|
||||
)
|
||||
.then(function() {
|
||||
book.log.info.ok();
|
||||
});
|
||||
);
|
||||
};
|
||||
|
||||
// Multi-langs book
|
||||
@@ -313,12 +303,15 @@ Book.prototype.generateFile = function(output, options) {
|
||||
_.map(book.langs, function(lang) {
|
||||
return copyFile(lang.lang);
|
||||
})
|
||||
);
|
||||
)
|
||||
.thenResolve(book.langs.length);
|
||||
} else {
|
||||
return copyFile();
|
||||
return copyFile().thenResolve(1);
|
||||
}
|
||||
})
|
||||
.then(function() {
|
||||
.then(function(n) {
|
||||
book.log.info.ok(n+" file(s) generated");
|
||||
|
||||
return fs.remove(tmpDir);
|
||||
});
|
||||
});
|
||||
@@ -521,7 +514,7 @@ Book.prototype.parsePage = function(filename, options) {
|
||||
page.content = content;
|
||||
|
||||
that.log.debug.ln("use file parser", filetype.name, "for", filename);
|
||||
return filetype.parser.page(page.content);
|
||||
return filetype.page(page.content);
|
||||
})
|
||||
|
||||
// Post process sections
|
||||
@@ -577,7 +570,7 @@ Book.prototype.findFile = function(filename) {
|
||||
.then(function(exists) {
|
||||
if (!exists) return null;
|
||||
return {
|
||||
parser: parsers.get(ext).parser,
|
||||
parser: parsers.get(ext),
|
||||
path: filepath
|
||||
};
|
||||
})
|
||||
@@ -650,6 +643,16 @@ Book.prototype.parentRoot = function() {
|
||||
return this.root;
|
||||
};
|
||||
|
||||
// Return true if it's a sub-book
|
||||
Book.prototype.isSubBook = function() {
|
||||
return !!this.parent;
|
||||
};
|
||||
|
||||
// Test if the file is the entry point
|
||||
Book.prototype.isEntryPoint = function(fp) {
|
||||
return fp == this.readmeFile;
|
||||
};
|
||||
|
||||
// Resolve a path in book
|
||||
Book.prototype.resolve = function(p) {
|
||||
return path.resolve(this.root, p);
|
||||
@@ -692,6 +695,16 @@ Book.prototype._defaultsStructure = function(filename) {
|
||||
that.langsFile = that.langsFile || that.config.getStructure("langs")+extension;
|
||||
}
|
||||
|
||||
// Change output path
|
||||
Book.prototype.setOutput = function(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));
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Init and return a book
|
||||
Book.init = function(root) {
|
||||
|
||||
@@ -5,6 +5,7 @@ var semver = require('semver');
|
||||
|
||||
var pkg = require('../package.json');
|
||||
var fs = require("./utils/fs");
|
||||
var i18n = require("./utils/i18n");
|
||||
|
||||
// Default plugins added to each books
|
||||
var defaultsPlugins = [];
|
||||
@@ -107,6 +108,8 @@ Configuration.prototype.load = function() {
|
||||
if (that.options.gitbook == "*") {
|
||||
that.book.log.warn.ln("you should specify a gitbook version to use in your book.json, for example: "+(_.first(pkg.version.split("."))+".x.x"));
|
||||
}
|
||||
|
||||
that.options.gitbook = pkg.version;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -122,7 +125,7 @@ Configuration.prototype.getStructure = function(name) {
|
||||
|
||||
// Return normalized language
|
||||
Configuration.prototype.normalizeLanguage = function() {
|
||||
return _.first(this.options.language.split("-")).toLowerCase();
|
||||
return i18n.normalizeLanguage(this.options.language);
|
||||
};
|
||||
|
||||
|
||||
@@ -217,8 +220,8 @@ Configuration.DEFAULT = {
|
||||
"margin": {
|
||||
"right": 62,
|
||||
"left": 62,
|
||||
"top": 36,
|
||||
"bottom": 36
|
||||
"top": 56,
|
||||
"bottom": 56
|
||||
},
|
||||
|
||||
//Header HTML template. Available variables: _PAGENUM_, _TITLE_, _AUTHOR_ and _SECTION_.
|
||||
|
||||
+1
-6
@@ -58,7 +58,7 @@ BaseGenerator.prototype.copyCover = function() {
|
||||
])
|
||||
.fail(function() {
|
||||
// If orignaly from multi-lang, try copy from parent
|
||||
if (!that.isMultilingual()) return;
|
||||
if (!that.book.isSubBook()) return;
|
||||
|
||||
return Q.all([
|
||||
fs.copy(path.join(that.book.parentRoot(), "cover.jpg"), path.join(that.options.output, "cover.jpg")),
|
||||
@@ -70,11 +70,6 @@ BaseGenerator.prototype.copyCover = function() {
|
||||
});
|
||||
};
|
||||
|
||||
// Generate the langs index
|
||||
BaseGenerator.prototype.langsIndex = function(langs) {
|
||||
return Q.reject(new Error("Langs index is not supported in this generator"));
|
||||
};
|
||||
|
||||
// At teh end of the generation
|
||||
BaseGenerator.prototype.finish = function() {
|
||||
return Q.reject(new Error("Could not finish generation"));
|
||||
|
||||
@@ -41,11 +41,6 @@ Generator.prototype.writeSummary = function() {
|
||||
return this._writeTemplate(this.templates["summary"], {}, path.join(this.options.output, "SUMMARY.html"));
|
||||
};
|
||||
|
||||
|
||||
Generator.prototype.langsIndex = function(langs) {
|
||||
return Q();
|
||||
};
|
||||
|
||||
Generator.prototype.finish = function() {
|
||||
var that = this;
|
||||
|
||||
@@ -92,8 +87,8 @@ Generator.prototype.finish = function() {
|
||||
"--pdf-mono-font-size": String(pdfOptions.fontSize),
|
||||
"--paper-size": String(pdfOptions.paperSize),
|
||||
"--pdf-page-numbers": Boolean(pdfOptions.pageNumbers),
|
||||
"--pdf-header-template": String(pdfOptions.headerTemplate),
|
||||
"--pdf-footer-template": String(pdfOptions.footerTemplate)
|
||||
"--pdf-header-template": String(pdfOptions.headerTemplate) || "<p class='header'><span>"+that.options.title+"</span></p>",
|
||||
"--pdf-footer-template": String(pdfOptions.footerTemplate) || "<p class='footer'><span>_SECTION_</span> <span style='float:right;'>_PAGENUM_</span></p>"
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+14
-10
@@ -14,7 +14,6 @@ util.inherits(Generator, BaseGenerator);
|
||||
|
||||
// Ignore some methods
|
||||
Generator.prototype.transferFile = function(input) { };
|
||||
Generator.prototype.finish = function() { };
|
||||
|
||||
// Convert an input file
|
||||
Generator.prototype.convertFile = function(input) {
|
||||
@@ -37,21 +36,26 @@ Generator.prototype.convertFile = function(input) {
|
||||
});
|
||||
};
|
||||
|
||||
// Generate languages index
|
||||
// Contains the first languages readme and langs infos
|
||||
Generator.prototype.langsIndex = function(langs) {
|
||||
// Finish generation
|
||||
Generator.prototype.finish = function() {
|
||||
return this.writeReadme();
|
||||
};
|
||||
|
||||
// Write README.json
|
||||
Generator.prototype.writeReadme = function() {
|
||||
var that = this;
|
||||
|
||||
if (langs.length == 0) return Q.reject("Need at least one language");
|
||||
|
||||
var mainLang = _.first(langs).lang;
|
||||
var readme = links.changeExtension(that.book.readmeFile, ".json");
|
||||
var mainlang, langs;
|
||||
|
||||
return Q()
|
||||
.then(function() {
|
||||
langs = that.book.langs;
|
||||
mainLang = langs.length > 0? _.first(langs).lang : null;
|
||||
|
||||
readme = links.changeExtension(that.book.readmeFile, ".json");
|
||||
|
||||
// Read readme from main language
|
||||
return fs.readFile(
|
||||
path.join(that.options.output, mainLang, readme)
|
||||
mainLang? path.join(that.options.output, mainLang, readme) : path.join(that.options.output, readme)
|
||||
);
|
||||
})
|
||||
.then(function(content) {
|
||||
|
||||
+11
-17
@@ -12,6 +12,7 @@ var fs = require("../utils/fs");
|
||||
var BaseGenerator = require("../generator");
|
||||
var links = require("../utils/links");
|
||||
var pageUtil = require("../utils/page");
|
||||
var i18n = require("../utils/i18n");
|
||||
|
||||
var pkg = require("../../package.json");
|
||||
|
||||
@@ -74,20 +75,12 @@ Generator.prototype.prepareTemplates = function() {
|
||||
Generator.prototype.prepareTemplateEngine = function() {
|
||||
var that = this;
|
||||
|
||||
return fs.readdir(path.resolve(__dirname, "../../theme/i18n"))
|
||||
.then(function(locales) {
|
||||
return Q()
|
||||
.then(function() {
|
||||
var language = that.book.config.normalizeLanguage();
|
||||
|
||||
locales = _.chain(locales)
|
||||
.map(function(local) {
|
||||
local = path.basename(local, ".json");
|
||||
return [local, require("../../theme/i18n/"+local)];
|
||||
})
|
||||
.object()
|
||||
.value();
|
||||
|
||||
if (!_.contains(_.keys(locales), language) && language != "en") {
|
||||
that.book.log.warn.ln("Language '"+language+"' is not available as a layout locales (en, "+_.keys(locales).join(", ")+")");
|
||||
if (!i18n.getByLanguage(language) && language != "en") {
|
||||
that.book.log.warn.ln("Language '"+language+"' is not available as a layout locales (en, "+i18n.getLanguages().join(", ")+")");
|
||||
}
|
||||
|
||||
var folders = _.chain(that.templates)
|
||||
@@ -114,7 +107,7 @@ Generator.prototype.prepareTemplateEngine = function() {
|
||||
that.env.addExtension('FilterExtension', new FilterExtension(that.env));
|
||||
that.env.addExtension('I18nExtension', new I18nExtension({
|
||||
env: that.env,
|
||||
translations: locales,
|
||||
translations: i18n.getLocales(),
|
||||
locale: "language"
|
||||
}));
|
||||
});
|
||||
@@ -125,7 +118,8 @@ Generator.prototype.finish = function() {
|
||||
return this.copyAssets()
|
||||
.then(this.copyCover)
|
||||
.then(this.writeGlossary)
|
||||
.then(this.writeSearchIndex);
|
||||
.then(this.writeSearchIndex)
|
||||
.then(this.writeLangsIndex)
|
||||
};
|
||||
|
||||
// Convert an input file
|
||||
@@ -163,11 +157,11 @@ Generator.prototype.convertFile = function(input) {
|
||||
};
|
||||
|
||||
// Write the index for langs
|
||||
Generator.prototype.langsIndex = function(langs) {
|
||||
Generator.prototype.writeLangsIndex = function() {
|
||||
var that = this;
|
||||
|
||||
if (!this.book.langs.length) return Q();
|
||||
return this._writeTemplate(this.templates["langs"], {
|
||||
langs: langs
|
||||
langs: this.book.langs
|
||||
}, path.join(this.options.output, "index.html"));
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
var Q = require("q");
|
||||
var _ = require("lodash");
|
||||
var path = require("path");
|
||||
var tinylr = require('tiny-lr-fork');
|
||||
var tinylr = require('tiny-lr');
|
||||
var color = require('bash-color');
|
||||
|
||||
var Book = require("./book");
|
||||
|
||||
+5
-2
@@ -22,15 +22,18 @@ var Plugin = function(book, name) {
|
||||
"gitbook-"+name,
|
||||
name,
|
||||
], function(_name) {
|
||||
if (this.load(_name, __dirname)) return false;
|
||||
// Load from the book
|
||||
if (this.load(_name, book.root)) return false;
|
||||
|
||||
// Load from default plugins
|
||||
if (this.load(_name, __dirname)) return false;
|
||||
}, this);
|
||||
};
|
||||
|
||||
// Type of plugins resources
|
||||
Plugin.RESOURCES = ["js", "css"];
|
||||
Plugin.HOOKS = [
|
||||
"init", "finish"
|
||||
"init", "finish", "finish:before"
|
||||
]
|
||||
|
||||
// Load from a name
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
var _ = require("lodash");
|
||||
var path = require("path");
|
||||
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)
|
||||
.map(function(local) {
|
||||
local = path.basename(local, ".json");
|
||||
return [local, _.extend(require(path.join(I18N_PATH, local)), {
|
||||
id: local
|
||||
})];
|
||||
})
|
||||
.object()
|
||||
.value();
|
||||
});
|
||||
|
||||
var getLanguages = function() {
|
||||
return _.keys(getLocales());
|
||||
};
|
||||
|
||||
var getByLanguage = function(lang) {
|
||||
lang = normalizeLanguage(lang);
|
||||
var locales = getLocales();
|
||||
return locales[lang];
|
||||
};
|
||||
|
||||
var compareLocales = function(lang, locale) {
|
||||
var langMain = _.first(lang.split("-"));
|
||||
var localeMain = _.first(locale.split("-"));
|
||||
|
||||
if (locale == lang) return 100;
|
||||
if (localeMain == langMain) return 50;
|
||||
return 0;
|
||||
};
|
||||
|
||||
var normalizeLanguage = _.memoize(function(lang) {
|
||||
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;
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
getLocales: getLocales,
|
||||
getLanguages: getLanguages,
|
||||
getByLanguage: getByLanguage,
|
||||
normalizeLanguage: normalizeLanguage
|
||||
};
|
||||
+5
-1
@@ -22,7 +22,11 @@ var convertSVG = function(source, dest, options) {
|
||||
if (error.code == 127) error = new Error("Need to install 'svgexport' using 'npm install svgexport -g'");
|
||||
return d.reject(error);
|
||||
}
|
||||
d.resolve();
|
||||
if (fs.existsSync(dest)) {
|
||||
d.resolve();
|
||||
} else {
|
||||
d.reject(new Error("Error converting "+source));
|
||||
}
|
||||
});
|
||||
|
||||
return d.promise;
|
||||
|
||||
+20
-9
@@ -4,6 +4,7 @@ var path = require('path');
|
||||
var cheerio = require('cheerio');
|
||||
var domSerializer = require('dom-serializer');
|
||||
var request = require('request');
|
||||
var crc = require("crc");
|
||||
|
||||
var links = require('./links');
|
||||
var imgUtils = require('./images');
|
||||
@@ -78,7 +79,14 @@ function pregQuote( str ) {
|
||||
|
||||
// Adapt an html snippet to be relative to a base folder
|
||||
function normalizeHtml(src, options) {
|
||||
var $ = cheerio.load(src, { xmlMode: false});
|
||||
var $ = cheerio.load(src, {
|
||||
// We should parse html without trying to normalize too much
|
||||
xmlMode: false,
|
||||
|
||||
// SVG need some attributes to use uppercases
|
||||
lowerCaseAttributeNames: false,
|
||||
lowerCaseTags: false
|
||||
});
|
||||
var toConvert = [];
|
||||
var svgContent = {};
|
||||
var outputRoot = options.book.options.output;
|
||||
@@ -116,7 +124,7 @@ function normalizeHtml(src, options) {
|
||||
// If image is external and ebook, then downlaod the images
|
||||
if (isExternal) {
|
||||
origin = src;
|
||||
src = "/"+fs.getUniqueFilename(outputRoot, path.basename(src));
|
||||
src = "/"+crc.crc32(origin).toString(16)+path.extname(origin);
|
||||
src = links.toAbsolute(src, options.base, options.output);
|
||||
isExternal = false;
|
||||
}
|
||||
@@ -198,12 +206,13 @@ function normalizeHtml(src, options) {
|
||||
|
||||
$("*").each(function() {
|
||||
replaceText($, this, r, function(match) {
|
||||
// Add to files index in glossary
|
||||
if (!includedInFiles) {
|
||||
includedInFiles = true;
|
||||
term.files = term.files || [];
|
||||
term.files.push(options.navigation[options.input]);
|
||||
}
|
||||
return "<a href='"+links.toAbsolute("GLOSSARY.html", options.base, options.output)+"#"+term.id+"' class='glossary-term' title='"+term.description+"'>"+match+"</span>";
|
||||
return "<a href='"+links.toAbsolute("/GLOSSARY.html", options.base, options.output)+"#"+term.id+"' class='glossary-term' title='"+term.description+"'>"+match+"</a>";
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -218,7 +227,8 @@ function normalizeHtml(src, options) {
|
||||
function convertImages(images, options) {
|
||||
if (!options.convertImages) return Q();
|
||||
|
||||
options.book.log.info.ln("convert ", images.length, "images to png");
|
||||
var downloaded = [];
|
||||
options.book.log.debug.ln("convert ", images.length, "images to png");
|
||||
|
||||
return _.reduce(images, function(prev, image) {
|
||||
var imgin = path.resolve(options.book.options.output, image.source);
|
||||
@@ -227,9 +237,10 @@ function convertImages(images, options) {
|
||||
|
||||
// Write image if need to be download
|
||||
.then(function() {
|
||||
if (!image.origin) return;
|
||||
options.book.log.info("download image", image.origin);
|
||||
return options.book.log.info.promise(fs.writeStream(imgin, request(image.origin)));
|
||||
if (!image.origin && !_.contains(downloaded, image.origin)) return;
|
||||
options.book.log.debug("download image", image.origin, "...");
|
||||
downloaded.push(image.origin);
|
||||
return options.book.log.debug.promise(fs.writeStream(imgin, request(image.origin)));
|
||||
})
|
||||
|
||||
// Write svg if content
|
||||
@@ -239,7 +250,7 @@ function convertImages(images, options) {
|
||||
})
|
||||
|
||||
// Convert
|
||||
.then(function(){
|
||||
.then(function() {
|
||||
if (!image.dest) return;
|
||||
var imgout = path.resolve(options.book.options.output, image.dest);
|
||||
options.book.log.debug("convert image", image.source, "to", image.dest, "...");
|
||||
@@ -247,7 +258,7 @@ function convertImages(images, options) {
|
||||
});
|
||||
}, Q())
|
||||
.then(function() {
|
||||
options.book.log.info.ok(images.length+" images converted with success");
|
||||
options.book.log.debug.ok(images.length+" images converted with success");
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gitbook",
|
||||
"version": "2.0.0-alpha.2",
|
||||
"version": "2.0.0-alpha.7",
|
||||
"homepage": "https://www.gitbook.com",
|
||||
"description": "Library and cmd utility to generate GitBooks",
|
||||
"main": "lib/index.js",
|
||||
@@ -10,9 +10,9 @@
|
||||
"lodash": "2.4.1",
|
||||
"graceful-fs": "3.0.5",
|
||||
"resolve": "0.6.3",
|
||||
"fs-extra": "0.14.0",
|
||||
"fs-extra": "0.16.3",
|
||||
"fstream-ignore": "1.0.2",
|
||||
"gitbook-parsers": "0.3.1",
|
||||
"gitbook-parsers": "0.4.0",
|
||||
"nunjucks": "git+https://github.com/SamyPesse/nunjucks.git#4019d1b7379372336b86ce1b0bf84352a2029747",
|
||||
"nunjucks-autoescape": "0.1.0",
|
||||
"nunjucks-filter": "0.1.0",
|
||||
@@ -23,14 +23,14 @@
|
||||
"gitbook-plugin-livereload": "0.0.1",
|
||||
"gaze": "~0.5.1",
|
||||
"send": "0.2.0",
|
||||
"tiny-lr-fork": "0.0.5",
|
||||
"tiny-lr": "0.1.5",
|
||||
"tmp": "0.0.24",
|
||||
"crc": "3.2.1",
|
||||
"bash-color": "0.0.3",
|
||||
"URIjs": "1.14.1",
|
||||
"request": "2.51.0",
|
||||
"npm": "2.4.1",
|
||||
"dom-serializer": "git+https://github.com/SamyPesse/dom-serializer.git#58d8ea24b9b7b4137ee5f30a41abce4d7c4a922a"
|
||||
"dom-serializer": "0.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "1.18.2",
|
||||
|
||||
+15
-19
@@ -1,6 +1,7 @@
|
||||
var path = require('path');
|
||||
var _ = require('lodash');
|
||||
var assert = require('assert');
|
||||
var cheerio = require('cheerio');
|
||||
|
||||
var fs = require("fs");
|
||||
var fsUtil = require("../lib/utils/fs");
|
||||
@@ -15,26 +16,21 @@ describe('eBook Generator', function () {
|
||||
|
||||
it('should correctly convert svg images to png', function(done) {
|
||||
testGeneration(books[4], "ebook", function(output) {
|
||||
var readmeContent = fs.readFileSync(path.join(output, "index.html"), {encoding: "utf8"});
|
||||
var pageContent = fs.readFileSync(path.join(output, "sub/PAGE.html"), {encoding: "utf8"});
|
||||
// Check that all images exists
|
||||
_.each([
|
||||
"index.html",
|
||||
"sub/PAGE.html"
|
||||
], function(pageName) {
|
||||
var pageFile = path.join(output, pageName);
|
||||
var pageFolder = path.dirname(pageFile);
|
||||
var pageContent = fs.readFileSync(pageFile, {encoding: "utf8"});
|
||||
var $ = cheerio.load(pageContent);
|
||||
|
||||
// Remote image
|
||||
assert(pageContent.indexOf('src="../Tux.png"') >= 0);
|
||||
assert(fs.existsSync(path.join(output, "Tux.png")));
|
||||
|
||||
assert(fs.existsSync(path.join(output, "test.png")));
|
||||
assert(fs.existsSync(path.join(output, "NewTux.png")));
|
||||
|
||||
assert(!fs.existsSync(path.join(output, "test_0.png")));
|
||||
assert(!fs.existsSync(path.join(output, "sub/test.png")));
|
||||
assert(!fs.existsSync(path.join(output, "sub/NewTux.png")));
|
||||
|
||||
assert(pageContent.indexOf('src="../test.png"') >= 0);
|
||||
assert(pageContent.indexOf('src="../NewTux.png"') >= 0);
|
||||
assert(pageContent.indexOf('<svg') < 0);
|
||||
|
||||
assert(readmeContent.indexOf('src="test.png"') >= 0);
|
||||
assert(readmeContent.indexOf('src="NewTux.png"') >= 0);
|
||||
$("img").each(function() {
|
||||
var src = $(this).attr("src");
|
||||
assert(fs.existsSync(path.resolve(pageFolder, src)), src+" not found for page "+pageName);
|
||||
})
|
||||
});
|
||||
}, done);
|
||||
});
|
||||
});
|
||||
|
||||
Vendored
+1
-1
@@ -1,3 +1,3 @@
|
||||
# Other Title
|
||||
|
||||
A description
|
||||
This is a description, it's simple, no ?
|
||||
|
||||
Vendored
+2
@@ -4,3 +4,5 @@ This is a relative link [test](../intro.md).
|
||||
|
||||

|
||||
|
||||
This is a glossary link.
|
||||
|
||||
|
||||
Vendored
+4
@@ -5,3 +5,7 @@ A description
|
||||

|
||||

|
||||

|
||||
|
||||
# Test with youtube videos that have the same filename:
|
||||

|
||||

|
||||
|
||||
Vendored
+2
-2
@@ -8,8 +8,8 @@
|
||||
## Inline svg
|
||||
|
||||
{% html %}
|
||||
<svg width="400" height="110">
|
||||
<rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M97.008198003228,6.103238498249268A97.2,97.2 0 0,1 87.9491894996971,41.385747140125076L54.289623147961166,25.546757493904366A60,60 0 0,0 59.88160370569629,3.7674311717588074Z"></path>
|
||||
</svg>
|
||||
{% endhtml %}
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
var path = require('path');
|
||||
var _ = require('lodash');
|
||||
var assert = require('assert');
|
||||
var cheerio = require('cheerio');
|
||||
|
||||
var fs = require("fs");
|
||||
var fsUtil = require("../lib/utils/fs");
|
||||
|
||||
|
||||
describe('Glossary Generation', function () {
|
||||
it('should correctly replace glossary terms', function(done) {
|
||||
testGeneration(books[0], "website", function(output) {
|
||||
var content = fs.readFileSync(path.join(output, "index.html"), { encoding: "utf8" });
|
||||
var $ = cheerio.load(content);
|
||||
|
||||
var $body = $(".page-inner");
|
||||
var $a = $("a[href='GLOSSARY.html#description']");
|
||||
assert($a.length == 1);
|
||||
assert($a.text() == "description");
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('should correctly replace glossary terms in sub pages', function(done) {
|
||||
testGeneration(books[1], "website", function(output) {
|
||||
var content = fs.readFileSync(path.join(output, "sub/test1.html"), { encoding: "utf8" });
|
||||
var $ = cheerio.load(content);
|
||||
|
||||
var $body = $(".page-inner");
|
||||
var $a = $("a[href='../GLOSSARY.html#test']");
|
||||
assert($a.length == 1);
|
||||
assert($a.text() == "test");
|
||||
assert($a.attr("title") == "a test text");
|
||||
}, done);
|
||||
});
|
||||
});
|
||||
+1
-1
@@ -16,7 +16,7 @@ describe('JSON generator', function () {
|
||||
|
||||
it('should correctly generate a book to json with sub folders', function(done) {
|
||||
testGeneration(books[1], "json", function(output) {
|
||||
assert(!fs.existsSync(path.join(output, "README.json")));
|
||||
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")));
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
+4
-2
@@ -11,8 +11,10 @@
|
||||
"SEARCH_PLACEHOLDER": "Suchbegriff eingeben",
|
||||
"FONTSETTINGS_TOGGLE": "Schrifteinstellungen",
|
||||
"SHARE_TOGGLE": "Teilen",
|
||||
"SHARE_ON": "auf __platform__ teilen",
|
||||
"SHARE_ON": "Auf __platform__ teilen",
|
||||
"FONTSETTINGS_WHITE": "Hell",
|
||||
"FONTSETTINGS_SEPIA": "Sepia",
|
||||
"FONTSETTINGS_NIGHT": "Nacht"
|
||||
"FONTSETTINGS_NIGHT": "Nacht",
|
||||
"FONTSETTINGS_SANS": "Sans",
|
||||
"FONTSETTINGS_SERIF": "Serif"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"LANGS_CHOOSE": "Seleccione un idioma",
|
||||
"GLOSSARY": "Glosario",
|
||||
"GLOSSARY_INDEX": "Índice",
|
||||
"GLOSSARY_OPEN": "Glosario",
|
||||
"GITBOOK_LINK": "Publicado con GitBook",
|
||||
"SUMMARY": "Tabla de contenido",
|
||||
"SUMMARY_INTRODUCTION": "Introducción",
|
||||
"SUMMARY_TOGGLE": "Tabla de contenido",
|
||||
"SEARCH_TOGGLE": "Busca",
|
||||
"SEARCH_PLACEHOLDER": "Escribe para buscar",
|
||||
"FONTSETTINGS_TOGGLE": "Configuración de fuente",
|
||||
"SHARE_TOGGLE": "Comparte",
|
||||
"SHARE_ON": "Comparte en __platform__",
|
||||
"FONTSETTINGS_WHITE": "Claro",
|
||||
"FONTSETTINGS_SEPIA": "Sépia",
|
||||
"FONTSETTINGS_NIGHT": "Noche",
|
||||
"FONTSETTINGS_SANS": "Sans",
|
||||
"FONTSETTINGS_SERIF": "Serif"
|
||||
}
|
||||
+3
-1
@@ -14,5 +14,7 @@
|
||||
"SHARE_ON": "Partager sur __platform__",
|
||||
"FONTSETTINGS_WHITE": "Clair",
|
||||
"FONTSETTINGS_SEPIA": "Sépia",
|
||||
"FONTSETTINGS_NIGHT": "Nuit"
|
||||
"FONTSETTINGS_NIGHT": "Nuit",
|
||||
"FONTSETTINGS_SANS": "Sans",
|
||||
"FONTSETTINGS_SERIF": "Serif"
|
||||
}
|
||||
+3
-1
@@ -14,5 +14,7 @@
|
||||
"SHARE_ON": "Condividi su __platform__",
|
||||
"FONTSETTINGS_WHITE": "Bianco",
|
||||
"FONTSETTINGS_SEPIA": "Seppia",
|
||||
"FONTSETTINGS_NIGHT": "Notte"
|
||||
"FONTSETTINGS_NIGHT": "Notte",
|
||||
"FONTSETTINGS_SANS": "Sans",
|
||||
"FONTSETTINGS_SERIF": "Serif"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"LANGS_CHOOSE": "Velg språk",
|
||||
"GLOSSARY": "Register",
|
||||
"GLOSSARY_INDEX": "Indeks",
|
||||
"GLOSSARY_OPEN": "Register",
|
||||
"GITBOOK_LINK": "Publisert med GitBook",
|
||||
"SUMMARY": "Innholdsfortegnelse",
|
||||
"SUMMARY_INTRODUCTION": "Innledning",
|
||||
"SUMMARY_TOGGLE": "Innholdsfortegnelse",
|
||||
"SEARCH_TOGGLE": "Søk",
|
||||
"SEARCH_PLACEHOLDER": "Skriv inn søkeord",
|
||||
"FONTSETTINGS_TOGGLE": "Tekstinnstillinger",
|
||||
"SHARE_TOGGLE": "Del",
|
||||
"SHARE_ON": "Del på __platform__",
|
||||
"FONTSETTINGS_WHITE": "Lys",
|
||||
"FONTSETTINGS_SEPIA": "Sepia",
|
||||
"FONTSETTINGS_NIGHT": "Mørk",
|
||||
"FONTSETTINGS_SANS": "Sans",
|
||||
"FONTSETTINGS_SERIF": "Serif"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"LANGS_CHOOSE": "Escolher sua língua",
|
||||
"GLOSSARY": "Glossário",
|
||||
"GLOSSARY_INDEX": "Índice",
|
||||
"GLOSSARY_OPEN": "Glossário",
|
||||
"GITBOOK_LINK": "Publicado com GitBook",
|
||||
"SUMMARY": "Tabela de conteúdos",
|
||||
"SUMMARY_INTRODUCTION": "Introdução",
|
||||
"SUMMARY_TOGGLE": "Tabela de conteúdos",
|
||||
"SEARCH_TOGGLE": "Pesquise",
|
||||
"SEARCH_PLACEHOLDER": "Escreva para pesquisar",
|
||||
"FONTSETTINGS_TOGGLE": "Configurações de fonte",
|
||||
"SHARE_TOGGLE": "Compartilhar",
|
||||
"SHARE_ON": "Compartilhar no __platform__",
|
||||
"FONTSETTINGS_WHITE": "Claro",
|
||||
"FONTSETTINGS_SEPIA": "Sépia",
|
||||
"FONTSETTINGS_NIGHT": "Noite",
|
||||
"FONTSETTINGS_SANS": "Sans",
|
||||
"FONTSETTINGS_SERIF": "Serif"
|
||||
}
|
||||
+3
-1
@@ -14,5 +14,7 @@
|
||||
"SHARE_ON": "Поделиться в __platform__",
|
||||
"FONTSETTINGS_WHITE": "Светлый",
|
||||
"FONTSETTINGS_SEPIA": "Сепия",
|
||||
"FONTSETTINGS_NIGHT": "Тёмный"
|
||||
"FONTSETTINGS_NIGHT": "Тёмный",
|
||||
"FONTSETTINGS_SANS": "Sans",
|
||||
"FONTSETTINGS_SERIF": "Serif"
|
||||
}
|
||||
@@ -0,0 +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": "无衬线体",
|
||||
"FONTSETTINGS_SERIF": "衬线体"
|
||||
}
|
||||
@@ -0,0 +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": "無襯線體",
|
||||
"FONTSETTINGS_SERIF": "襯線體"
|
||||
}
|
||||
@@ -5,52 +5,33 @@
|
||||
|
||||
.page {
|
||||
&.page-toc {
|
||||
ol {
|
||||
margin: 0px;
|
||||
.glossary {
|
||||
margin-bottom: 40px;
|
||||
|
||||
h2 {
|
||||
a, a:hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.glossary-index {
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
|
||||
li {
|
||||
display: inline;
|
||||
margin: 0px 8px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.book-chapter {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.exercise, .quiz {
|
||||
margin: 1cm 0cm;
|
||||
border: 2px solid #ddd;
|
||||
|
||||
.exercise-header {
|
||||
padding: 0.1cm 0.3cm;
|
||||
background: #f5f5f5;
|
||||
border-bottom: 1px solid #ddd;
|
||||
font-weight: bold;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
.exercise-inner {
|
||||
padding: 0.15cm 0.3cm;
|
||||
|
||||
p:last-child {
|
||||
margin: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
.question {
|
||||
margin-top: 0.1cm;
|
||||
border-top: 1px solid #ddd;
|
||||
|
||||
.question-base {
|
||||
|
||||
}
|
||||
|
||||
.question-solution {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,10 +5,15 @@
|
||||
{% block content %}
|
||||
<div class="page page-toc">
|
||||
<h1>Glossary</h1>
|
||||
{% for item in glossaryIndex %}
|
||||
{% for item in glossary %}
|
||||
<section class="normal glossary" id="{{ item.id }}">
|
||||
<h2><a href="#{{ item.id }}">{{ item.name }}</a></h2>
|
||||
<p>{{ item.description }}</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 %}
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
<section class="normal glossary" id="{{ item.id }}">
|
||||
<h2><a href="#{{ item.id }}">{{ item.name }}</a></h2>
|
||||
<p>{{ item.description }}</p>
|
||||
<h4>{% i18n "GLOSSARY_INDEX" %}Index{% endi18n %}</h4>
|
||||
<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>
|
||||
|
||||
Reference in New Issue
Block a user