diff options
-rw-r--r-- | CHANGES.md | 6 | ||||
-rw-r--r-- | lib/book.js | 8 | ||||
-rw-r--r-- | lib/configuration.js | 4 | ||||
-rw-r--r-- | lib/generator.js | 5 | ||||
-rw-r--r-- | lib/generators/ebook.js | 9 | ||||
-rw-r--r-- | lib/generators/json.js | 24 | ||||
-rw-r--r-- | lib/generators/website.js | 9 | ||||
-rw-r--r-- | lib/template.js | 35 | ||||
-rw-r--r-- | lib/utils/batch.js | 52 | ||||
-rw-r--r-- | lib/utils/i18n.js | 3 | ||||
-rw-r--r-- | lib/utils/images.js | 6 | ||||
-rw-r--r-- | lib/utils/page.js | 63 | ||||
-rw-r--r-- | package.json | 4 | ||||
-rw-r--r-- | test/ebook.js | 36 | ||||
-rw-r--r-- | test/fixtures/test4/README.md | 4 | ||||
-rw-r--r-- | test/fixtures/test4/sub/PAGE.md | 4 | ||||
-rw-r--r-- | test/json.js | 2 | ||||
-rwxr-xr-x | theme/assets/print.css | 2 | ||||
-rwxr-xr-x | theme/stylesheets/ebook.less | 61 | ||||
-rw-r--r-- | theme/templates/ebook/glossary.html | 7 | ||||
-rw-r--r-- | theme/templates/website/glossary.html | 1 |
21 files changed, 210 insertions, 135 deletions
@@ -1,5 +1,11 @@ # Release notes +## 2.0.0-alpha.7 +- Fix display of glossary in ebook formats +- Add default footer and header to pdf +- Fix generation of json format compatible with 1.x.x +- Add Simplifiled Chinese and Traditional Chinese translations + ## 2.0.0-alpha.6 - Add es and pt translations - Fix replacement of glossary terms diff --git a/lib/book.js b/lib/book.js index f5d52e9..650931f 100644 --- a/lib/book.js +++ b/lib/book.js @@ -261,9 +261,6 @@ Book.prototype.generateMultiLingual = function(generator) { return book.generate(that.options.generator); }); }, Q()); - }) - .then(function() { - return generator.langsIndex(that.langs); }); }; @@ -651,6 +648,11 @@ 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); diff --git a/lib/configuration.js b/lib/configuration.js index bedf266..7316dd8 100644 --- a/lib/configuration.js +++ b/lib/configuration.js @@ -220,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_. diff --git a/lib/generator.js b/lib/generator.js index f7f319d..c809de2 100644 --- a/lib/generator.js +++ b/lib/generator.js @@ -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")); diff --git a/lib/generators/ebook.js b/lib/generators/ebook.js index eb84df8..09215c4 100644 --- a/lib/generators/ebook.js +++ b/lib/generators/ebook.js @@ -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>" }); } diff --git a/lib/generators/json.js b/lib/generators/json.js index f1af395..6c9439d 100644 --- a/lib/generators/json.js +++ b/lib/generators/json.js @@ -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) { - var that = this; - - if (langs.length == 0) return Q.reject("Need at least one language"); +// Finish generation +Generator.prototype.finish = function() { + return this.writeReadme(); +}; - var mainLang = _.first(langs).lang; - var readme = links.changeExtension(that.book.readmeFile, ".json"); +// Write README.json +Generator.prototype.writeReadme = function() { + var that = this; + 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) { diff --git a/lib/generators/website.js b/lib/generators/website.js index 01df98c..d40ffa8 100644 --- a/lib/generators/website.js +++ b/lib/generators/website.js @@ -118,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 @@ -156,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")); }; diff --git a/lib/template.js b/lib/template.js index f1d9fc0..f43073b 100644 --- a/lib/template.js +++ b/lib/template.js @@ -6,6 +6,7 @@ var nunjucks = require("nunjucks"); var git = require("./utils/git"); var stringUtils = require("./utils/string"); var fs = require("./utils/fs"); +var batch = require("./utils/batch"); var pkg = require("../package.json"); @@ -87,18 +88,21 @@ TemplateEngine.prototype.processBlock = function(blk) { if (_.isString(blk)) blk = { body: blk }; blk = _.defaults(blk, { - parse: false + parse: false, + post: undefined }); blk.id = _.uniqueId("blk"); + var toAdd = (!blk.parse) || (blk.post != undefined); + + // Add to global map + if (toAdd) this.blocks[blk.id] = blk; + //Parsable block, just return it if (blk.parse) { return blk.body; } - // Add to global map - this.blocks[blk.id] = blk; - // Return it as a macro return "%+%"+blk.id+"%+%"; }; @@ -114,9 +118,6 @@ TemplateEngine.prototype.replaceBlocks = function(content) { var body = blk.body; - // Remove it from map - delete that.blocks[key]; - return body; }); }; @@ -367,8 +368,26 @@ TemplateEngine.prototype.renderPage = function(page) { // Post process content TemplateEngine.prototype.postProcess = function(content) { + var that = this; + return Q(content) - .then(this.replaceBlocks); + .then(that.replaceBlocks) + .then(function(_content) { + return batch.execEach(that.blocks, { + max: 20, + fn: function(blk, blkId) { + return Q() + .then(function() { + if (!blk.post) return Q(); + return blk.post(); + }) + .then(function() { + delete that.blocks[blkId]; + }); + } + }) + .thenResolve(_content); + }); }; module.exports = TemplateEngine; diff --git a/lib/utils/batch.js b/lib/utils/batch.js new file mode 100644 index 0000000..bd3b80f --- /dev/null +++ b/lib/utils/batch.js @@ -0,0 +1,52 @@ +var Q = require("q"); +var _ = require("lodash"); + +// Execute a method for all element +function execEach(items, options) { + if (_.size(items) == 0) return Q(); + var concurrents = 0, d = Q.defer(), pending = []; + + options = _.defaults(options || {}, { + max: 100, + fn: function(item) {} + }); + + + function startItem(item, i) { + if (concurrents >= options.max) { + pending.push([item, i]); + return; + } + + concurrents++; + Q() + .then(function() { + return options.fn(item, i); + }) + .then(function() { + concurrents--; + + // Next pending + var next = pending.shift(); + + if (concurrents == 0 && !next) { + d.resolve(); + } else if (next) { + startItem.apply(null, next); + } + }) + .fail(function(err) { + pending = []; + d.reject(err); + }) + } + + _.each(items, startItem); + + return d.promise; +} + +module.exports = { + execEach: execEach +}; + diff --git a/lib/utils/i18n.js b/lib/utils/i18n.js index 3ef1557..dcd9150 100644 --- a/lib/utils/i18n.js +++ b/lib/utils/i18n.js @@ -48,6 +48,9 @@ var normalizeLanguage = _.memoize(function(lang) { score: compareLocales(lang, locale) } }) + .filter(function(lang) { + return lang.score > 0; + }) .sortBy("score") .pluck("locale") .last() diff --git a/lib/utils/images.js b/lib/utils/images.js index 61a52dc..1e90317 100644 --- a/lib/utils/images.js +++ b/lib/utils/images.js @@ -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; diff --git a/lib/utils/page.js b/lib/utils/page.js index ccf5dfa..0714958 100644 --- a/lib/utils/page.js +++ b/lib/utils/page.js @@ -4,10 +4,12 @@ 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'); var fs = require('./fs'); +var batch = require('./batch'); // Render a cheerio dom as html var renderDom = function($, dom, options) { @@ -111,6 +113,7 @@ function normalizeHtml(src, options) { $("img").each(function() { var origin = undefined; var src = $(this).attr("src"); + if (!src) return; var isExternal = links.isExternal(src); // Transform as relative to the bases @@ -123,7 +126,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; } @@ -181,6 +184,7 @@ function normalizeHtml(src, options) { $("a").each(function() { var href = $(this).attr("href"); + if (!href) return; if (links.isRelative(href)) { var absolutePath = path.join(options.base, href); @@ -226,34 +230,39 @@ function normalizeHtml(src, options) { function convertImages(images, options) { if (!options.convertImages) return Q(); + 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); - - return prev - - // Write image if need to be download - .then(function() { - if (!image.origin) return; - options.book.log.debug("download image", image.origin, "..."); - return options.book.log.debug.promise(fs.writeStream(imgin, request(image.origin))); - }) - - // Write svg if content - .then(function() { - if (!image.content) return; - return fs.writeFile(imgin, image.content); - }) - - // Convert - .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, "..."); - return options.book.log.debug.promise(imgUtils.convertSVG(imgin, imgout)); - }); - }, Q()) + return batch.execEach(images, { + max: 100, + fn: function(image) { + var imgin = path.resolve(options.book.options.output, image.source); + + return Q() + + // Write image if need to be download + .then(function() { + 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 + .then(function() { + if (!image.content) return; + return fs.writeFile(imgin, image.content); + }) + + // Convert + .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, "..."); + return options.book.log.debug.promise(imgUtils.convertSVG(imgin, imgout)); + }); + } + }) .then(function() { options.book.log.debug.ok(images.length+" images converted with success"); }); diff --git a/package.json b/package.json index 474bdc7..23acfef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gitbook", - "version": "2.0.0-alpha.6", + "version": "2.0.0-alpha.7", "homepage": "https://www.gitbook.com", "description": "Library and cmd utility to generate GitBooks", "main": "lib/index.js", @@ -30,7 +30,7 @@ "URIjs": "1.14.1", "request": "2.51.0", "npm": "2.4.1", - "dom-serializer": "git+https://github.com/SamyPesse/dom-serializer.git#57ed9a2c3dfa964022ce7d71859c558ba7721785" + "dom-serializer": "0.1.0" }, "devDependencies": { "mocha": "1.18.2", diff --git a/test/ebook.js b/test/ebook.js index 9432afa..d02e7cd 100644 --- a/test/ebook.js +++ b/test/ebook.js @@ -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"}); - - // 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); + // 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); + + $("img").each(function() { + var src = $(this).attr("src"); + assert(fs.existsSync(path.resolve(pageFolder, src)), src+" not found for page "+pageName); + }) + }); }, done); }); }); diff --git a/test/fixtures/test4/README.md b/test/fixtures/test4/README.md index 19892a5..d73be69 100644 --- a/test/fixtures/test4/README.md +++ b/test/fixtures/test4/README.md @@ -5,3 +5,7 @@ A description    + +# Test with youtube videos that have the same filename: + + diff --git a/test/fixtures/test4/sub/PAGE.md b/test/fixtures/test4/sub/PAGE.md index 6de478e..a98a942 100644 --- a/test/fixtures/test4/sub/PAGE.md +++ b/test/fixtures/test4/sub/PAGE.md @@ -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 %} diff --git a/test/json.js b/test/json.js index b7cdefa..e0ad14f 100644 --- a/test/json.js +++ b/test/json.js @@ -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"))); diff --git a/theme/assets/print.css b/theme/assets/print.css index 200094e..6a75ad9 100755 --- a/theme/assets/print.css +++ b/theme/assets/print.css @@ -1 +1 @@ -.link-inherit{color:inherit}.link-inherit:hover,.link-inherit:focus{color:inherit}.hidden{display:none}.hljs-comment,.hljs-title{color:#8e908c}.hljs-variable,.hljs-attribute,.hljs-tag,.hljs-regexp,.ruby .hljs-constant,.xml .hljs-tag .hljs-title,.xml .hljs-pi,.xml .hljs-doctype,.html .hljs-doctype,.css .hljs-id,.css .hljs-class,.css .hljs-pseudo{color:#c82829}.hljs-number,.hljs-preprocessor,.hljs-pragma,.hljs-built_in,.hljs-literal,.hljs-params,.hljs-constant{color:#f5871f}.ruby .hljs-class .hljs-title,.css .hljs-rules .hljs-attribute{color:#eab700}.hljs-string,.hljs-value,.hljs-inheritance,.hljs-header,.ruby .hljs-symbol,.xml .hljs-cdata{color:#718c00}.css .hljs-hexcolor{color:#3e999f}.hljs-function,.python .hljs-decorator,.python .hljs-title,.ruby .hljs-function .hljs-title,.ruby .hljs-title .hljs-keyword,.perl .hljs-sub,.javascript .hljs-title,.coffeescript .hljs-title{color:#4271ae}.hljs-keyword,.javascript .hljs-function{color:#8959a8}.hljs{display:block;background:white;color:#4d4d4c;padding:.5em}.coffeescript .javascript,.javascript .xml,.tex .hljs-formula,.xml .javascript,.xml .vbscript,.xml .css,.xml .hljs-cdata{opacity:.5}.page.page-toc ol{margin:0}.page .book-chapter{display:none}.page .exercise,.page .quiz{margin:1cm 0;border:2px solid #ddd}.page .exercise .exercise-header,.page .quiz .exercise-header{padding:.1cm .3cm;background:#f5f5f5;border-bottom:1px solid #ddd;font-weight:bold;page-break-inside:avoid}.page .exercise .exercise-inner,.page .quiz .exercise-inner{padding:.15cm .3cm}.page .exercise .exercise-inner p:last-child,.page .quiz .exercise-inner p:last-child{margin:0}.page .exercise hr,.page .quiz hr{height:2px}.page .exercise .question,.page .quiz .question{margin-top:.1cm;border-top:1px solid #ddd}body .page{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;line-height:1.4;color:#333;overflow:hidden;line-height:1.6;word-wrap:break-word;display:block}body .page>*:first-child{margin-top:0!important}body .page>*:last-child{margin-bottom:0!important}body .page a{background:transparent}body .page a:active,body .page a:hover{outline:0}body .page strong{font-weight:bold}body .page h1{font-size:2em;margin:.67em 0}body .page img{border:0}body .page hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}body .page pre{overflow:auto}body .page code,body .page pre{font-family:monospace,monospace;font-size:1em}body .page table{border-collapse:collapse;border-spacing:0}body .page td,body .page th{padding:0}body .page *{-moz-box-sizing:border-box;box-sizing:border-box}body .page a{color:#4183c4;text-decoration:none}body .page a:hover,body .page a:focus,body .page a:active{text-decoration:underline}body .page hr{height:0;margin:15px 0;overflow:hidden;background:transparent;border:0;border-bottom:1px solid #ddd}body .page hr:before,body .page hr:after{display:table;content:" "}body .page hr:after{clear:both}body .page h1,body .page h2,body .page h3,body .page h4,body .page h5,body .page h6{margin-top:15px;margin-bottom:15px;line-height:1.1}body .page h1{font-size:30px}body .page h2{font-size:21px}body .page h3{font-size:16px}body .page h4{font-size:14px}body .page h5{font-size:12px}body .page h6{font-size:11px}body .page blockquote{margin:0}body .page ul,body .page ol{padding:0;margin-top:0;margin-bottom:0}body .page ol ol{list-style-type:lower-roman}body .page dd{margin-left:0}body .page code,body .page pre{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px}body .page pre{margin-top:0;margin-bottom:0}body .page .markdown-body>*:first-child{margin-top:0!important}body .page .markdown-body>*:last-child{margin-bottom:0!important}body .page .anchor{position:absolute;top:0;bottom:0;left:0;display:block;padding-right:6px;padding-left:30px;margin-left:-30px}body .page .anchor:focus{outline:0}body .page h1,body .page h2,body .page h3,body .page h4,body .page h5,body .page h6{position:relative;margin-top:1em;margin-bottom:16px;font-weight:bold;line-height:1.4}body .page h1{padding-bottom:.3em;font-size:2.25em;line-height:1.2;border-bottom:1px solid #eee}body .page h2{padding-bottom:.3em;font-size:1.75em;line-height:1.225;border-bottom:1px solid #eee}body .page h3{font-size:1.5em;line-height:1.43}body .page h4{font-size:1.25em}body .page h5{font-size:1em}body .page h6{font-size:1em;color:#777}body .page p,body .page blockquote,body .page ul,body .page ol,body .page dl,body .page table,body .page pre{margin-top:0;margin-bottom:16px}body .page hr{height:4px;padding:0;margin:16px 0;background-color:#e7e7e7;border:0 none}body .page ul,body .page ol{padding-left:2em}body .page ol ol,body .page ol ul,body .page ul ul{margin-top:0;margin-bottom:0}body .page dl{padding:0}body .page dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:bold}body .page dl dd{padding:0 16px;margin-bottom:16px}body .page blockquote{padding:0 15px;color:#777;border-left:4px solid #ddd}body .page blockquote>:first-child{margin-top:0}body .page blockquote>:last-child{margin-bottom:0}body .page table{display:block;width:100%;overflow:auto}body .page table th{font-weight:bold}body .page table th,body .page table td{padding:6px 13px;border:1px solid #ddd}body .page table tr{background-color:#fff;border-top:1px solid #ccc}body .page table tr:nth-child(2n){background-color:#f8f8f8}body .page img{max-width:100%;-moz-box-sizing:border-box;box-sizing:border-box;page-break-inside:avoid}body .page code{padding:0;padding-top:.2em;padding-bottom:.2em;margin:0;font-size:85%;background-color:#f7f7f7;border-radius:3px}body .page code:before,body .page code:after{letter-spacing:-0.2em;content:"\00a0"}body .page pre>code{padding:0;margin:0;font-size:100%;white-space:pre;background:transparent;border:0}body .page .highlight pre,body .page pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f7f7f7;border:0;border-radius:3px}body .page pre{word-wrap:normal}body .page pre code{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}body .page pre code:before,body .page pre code:after{content:normal}body .page .highlight{background:#fff}
\ No newline at end of file +.link-inherit{color:inherit}.link-inherit:hover,.link-inherit:focus{color:inherit}.hidden{display:none}.hljs-comment,.hljs-title{color:#8e908c}.hljs-variable,.hljs-attribute,.hljs-tag,.hljs-regexp,.ruby .hljs-constant,.xml .hljs-tag .hljs-title,.xml .hljs-pi,.xml .hljs-doctype,.html .hljs-doctype,.css .hljs-id,.css .hljs-class,.css .hljs-pseudo{color:#c82829}.hljs-number,.hljs-preprocessor,.hljs-pragma,.hljs-built_in,.hljs-literal,.hljs-params,.hljs-constant{color:#f5871f}.ruby .hljs-class .hljs-title,.css .hljs-rules .hljs-attribute{color:#eab700}.hljs-string,.hljs-value,.hljs-inheritance,.hljs-header,.ruby .hljs-symbol,.xml .hljs-cdata{color:#718c00}.css .hljs-hexcolor{color:#3e999f}.hljs-function,.python .hljs-decorator,.python .hljs-title,.ruby .hljs-function .hljs-title,.ruby .hljs-title .hljs-keyword,.perl .hljs-sub,.javascript .hljs-title,.coffeescript .hljs-title{color:#4271ae}.hljs-keyword,.javascript .hljs-function{color:#8959a8}.hljs{display:block;background:white;color:#4d4d4c;padding:.5em}.coffeescript .javascript,.javascript .xml,.tex .hljs-formula,.xml .javascript,.xml .vbscript,.xml .css,.xml .hljs-cdata{opacity:.5}.page.page-toc .glossary{margin-bottom:40px}.page.page-toc .glossary h2 a,.page.page-toc .glossary h2 a:hover{color:inherit;text-decoration:none}.page.page-toc .glossary .glossary-index{list-style:none;margin:0;padding:0}.page.page-toc .glossary .glossary-index li{display:inline;margin:0 8px;white-space:nowrap}.page .book-chapter{display:none}body .page{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;line-height:1.4;color:#333;overflow:hidden;line-height:1.6;word-wrap:break-word;display:block}body .page>*:first-child{margin-top:0!important}body .page>*:last-child{margin-bottom:0!important}body .page a{background:transparent}body .page a:active,body .page a:hover{outline:0}body .page strong{font-weight:bold}body .page h1{font-size:2em;margin:.67em 0}body .page img{border:0}body .page hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}body .page pre{overflow:auto}body .page code,body .page pre{font-family:monospace,monospace;font-size:1em}body .page table{border-collapse:collapse;border-spacing:0}body .page td,body .page th{padding:0}body .page *{-moz-box-sizing:border-box;box-sizing:border-box}body .page a{color:#4183c4;text-decoration:none}body .page a:hover,body .page a:focus,body .page a:active{text-decoration:underline}body .page hr{height:0;margin:15px 0;overflow:hidden;background:transparent;border:0;border-bottom:1px solid #ddd}body .page hr:before,body .page hr:after{display:table;content:" "}body .page hr:after{clear:both}body .page h1,body .page h2,body .page h3,body .page h4,body .page h5,body .page h6{margin-top:15px;margin-bottom:15px;line-height:1.1}body .page h1{font-size:30px}body .page h2{font-size:21px}body .page h3{font-size:16px}body .page h4{font-size:14px}body .page h5{font-size:12px}body .page h6{font-size:11px}body .page blockquote{margin:0}body .page ul,body .page ol{padding:0;margin-top:0;margin-bottom:0}body .page ol ol{list-style-type:lower-roman}body .page dd{margin-left:0}body .page code,body .page pre{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px}body .page pre{margin-top:0;margin-bottom:0}body .page .markdown-body>*:first-child{margin-top:0!important}body .page .markdown-body>*:last-child{margin-bottom:0!important}body .page .anchor{position:absolute;top:0;bottom:0;left:0;display:block;padding-right:6px;padding-left:30px;margin-left:-30px}body .page .anchor:focus{outline:0}body .page h1,body .page h2,body .page h3,body .page h4,body .page h5,body .page h6{position:relative;margin-top:1em;margin-bottom:16px;font-weight:bold;line-height:1.4}body .page h1{padding-bottom:.3em;font-size:2.25em;line-height:1.2;border-bottom:1px solid #eee}body .page h2{padding-bottom:.3em;font-size:1.75em;line-height:1.225;border-bottom:1px solid #eee}body .page h3{font-size:1.5em;line-height:1.43}body .page h4{font-size:1.25em}body .page h5{font-size:1em}body .page h6{font-size:1em;color:#777}body .page p,body .page blockquote,body .page ul,body .page ol,body .page dl,body .page table,body .page pre{margin-top:0;margin-bottom:16px}body .page hr{height:4px;padding:0;margin:16px 0;background-color:#e7e7e7;border:0 none}body .page ul,body .page ol{padding-left:2em}body .page ol ol,body .page ol ul,body .page ul ul{margin-top:0;margin-bottom:0}body .page dl{padding:0}body .page dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:bold}body .page dl dd{padding:0 16px;margin-bottom:16px}body .page blockquote{padding:0 15px;color:#777;border-left:4px solid #ddd}body .page blockquote>:first-child{margin-top:0}body .page blockquote>:last-child{margin-bottom:0}body .page table{display:block;width:100%;overflow:auto}body .page table th{font-weight:bold}body .page table th,body .page table td{padding:6px 13px;border:1px solid #ddd}body .page table tr{background-color:#fff;border-top:1px solid #ccc}body .page table tr:nth-child(2n){background-color:#f8f8f8}body .page img{max-width:100%;-moz-box-sizing:border-box;box-sizing:border-box;page-break-inside:avoid}body .page code{padding:0;padding-top:.2em;padding-bottom:.2em;margin:0;font-size:85%;background-color:#f7f7f7;border-radius:3px}body .page code:before,body .page code:after{letter-spacing:-0.2em;content:"\00a0"}body .page pre>code{padding:0;margin:0;font-size:100%;white-space:pre;background:transparent;border:0}body .page .highlight pre,body .page pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f7f7f7;border:0;border-radius:3px}body .page pre{word-wrap:normal}body .page pre code{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}body .page pre code:before,body .page pre code:after{content:normal}body .page .highlight{background:#fff}
\ No newline at end of file diff --git a/theme/stylesheets/ebook.less b/theme/stylesheets/ebook.less index 46fe4bd..f4b6c2e 100755 --- a/theme/stylesheets/ebook.less +++ b/theme/stylesheets/ebook.less @@ -5,52 +5,33 @@ .page { &.page-toc { - ol { - margin: 0px; - } - } - - .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 { - + .glossary { + margin-bottom: 40px; + + h2 { + a, a:hover { + color: inherit; + text-decoration: none; + } } - .question-solution { + .glossary-index { + list-style: none; + margin: 0px; + padding: 0px; + li { + display: inline; + margin: 0px 8px; + white-space: nowrap; + } } } } + + .book-chapter { + display: none; + } } diff --git a/theme/templates/ebook/glossary.html b/theme/templates/ebook/glossary.html index 0bd7ab6..49e3c13 100644 --- a/theme/templates/ebook/glossary.html +++ b/theme/templates/ebook/glossary.html @@ -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> diff --git a/theme/templates/website/glossary.html b/theme/templates/website/glossary.html index e319367..aab4f40 100644 --- a/theme/templates/website/glossary.html +++ b/theme/templates/website/glossary.html @@ -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> |