diff options
author | Samy Pessé <samypesse@gmail.com> | 2016-02-14 15:26:15 +0100 |
---|---|---|
committer | Samy Pessé <samypesse@gmail.com> | 2016-02-14 15:26:15 +0100 |
commit | 0e86cdeb4a3af445700e8e3ebbdb245e16581c17 (patch) | |
tree | 41b5e10b7bb5120f3e43920370aeafda755a5322 | |
parent | a65f888a77c48968087d23750e5fa4d55f2a8686 (diff) | |
download | gitbook-0e86cdeb4a3af445700e8e3ebbdb245e16581c17.zip gitbook-0e86cdeb4a3af445700e8e3ebbdb245e16581c17.tar.gz gitbook-0e86cdeb4a3af445700e8e3ebbdb245e16581c17.tar.bz2 |
Add code blocks normalization
-rw-r--r-- | lib/page/html.js | 92 | ||||
-rw-r--r-- | lib/page/index.js | 12 |
2 files changed, 74 insertions, 30 deletions
diff --git a/lib/page/html.js b/lib/page/html.js index 255bf48..ea31a06 100644 --- a/lib/page/html.js +++ b/lib/page/html.js @@ -25,6 +25,9 @@ function HTMLPipeline(htmlString, opts) { // Output an image onImage: _.identity, + // Syntax highlighting + onCodeBlock: _.identity, + // Output a svg, if returns null the svg is kept inlined onOutputSVG: _.constant(null) }); @@ -39,20 +42,28 @@ function HTMLPipeline(htmlString, opts) { }); } -// Normalize links -HTMLPipeline.prototype.normalizeLinks = function() { +// Transform a query of elements in the page +HTMLPipeline.prototype._transform = function(query, fn) { var that = this; - this.$('a').each(function() { - var $a = that.$(this); + var $elements = this.$(query); + + return Promise.serie($elements, function(el) { + var $el = that.$(el); + return fn.call(that, $el); + }); +}; +// Normalize links +HTMLPipeline.prototype.transformLinks = function() { + return this._transform('a', function($a) { var href = $a.attr('href'); if (!href) return; if (location.isAnchor(href)) { // Don't "change" anchor links } else if (location.isRelative(href)) { - $a.attr('href', that.opts.onRelativeLink(href)); + $a.attr('href', this.opts.onRelativeLink(href)); } else { // External links $a.attr('target', '_blank'); @@ -61,23 +72,50 @@ HTMLPipeline.prototype.normalizeLinks = function() { }; // Normalize images -HTMLPipeline.prototype.normalizeImages = function() { - var that = this; - - var $imgs = this.$('img'); - - return Promise.serie($imgs, function(img) { - var $img = that.$(img); - - return Promise(that.opts.onImage($img.attr('src'))) +HTMLPipeline.prototype.transformImages = function() { + return this._transform('img', function($img) { + return Promise(this.opts.onImage($img.attr('src'))) .then(function(filename) { $img.attr('src', filename); }); }); }; +// Normalize code blocks +HTMLPipeline.prototype.transformCodeBlocks = function() { + return this._transform('code', function($code) { + // Extract language + var lang = _.chain( + ($code.attr('class') || '').split(' ') + ) + .map(function(cl) { + // Markdown + if (cl.search('lang-') === 0) return cl.slice('lang-'.length); + + // Asciidoc + if (cl.search('language-') === 0) return cl.slice('language-'.length); + + return null; + }) + .compact() + .first() + .value(); + + var source = $code.text(); + + return Promise(this.opts.onCodeBlock(source, lang)) + .then(function(blk) { + if (blk.html === false) { + $code.text(blk.body); + } else { + $code.html(blk.body); + } + }); + }); +}; + // Add ID to headings -HTMLPipeline.prototype.addHeadingIDs = function() { +HTMLPipeline.prototype.transformHeadings = function() { var that = this; this.$('h1,h2,h3,h4,h5,h6').each(function() { @@ -90,23 +128,18 @@ HTMLPipeline.prototype.addHeadingIDs = function() { }; // Outline SVG from the HML -HTMLPipeline.prototype.outlineSVG = function() { - var that = this; - - var $svgs = this.$('svg'); - - return Promise.serie($svgs, function(svg) { - var $svg = that.$(svg); +HTMLPipeline.prototype.transformSvgs = function() { + return this._transform('svg', function($svg) { var content = [ '<?xml version="1.0" encoding="UTF-8"?>', - renderDOM(that.$, $svg) + renderDOM(this.$, $svg) ].join('\n'); - return Promise(that.opts.onOutputSVG(content)) + return Promise(this.opts.onOutputSVG(content)) .then(function(filename) { if (!filename) return; - $svg.replaceWith(that.$('<img>').attr('src', filename)); + $svg.replaceWith(this.$('<img>').attr('src', filename)); }); }); }; @@ -116,10 +149,11 @@ HTMLPipeline.prototype.output = function() { var that = this; return Promise() - .then(this.normalizeLinks) - .then(this.normalizeImages) - .then(this.addHeadingIDs) - .then(this.outlineSVG) + .then(this.transformLinks) + .then(this.transformImages) + .then(this.transformHeadings) + .then(this.transformCodeBlocks) + .then(this.transformSvgs) .then(function() { return renderDOM(that.$); }); diff --git a/lib/page/index.js b/lib/page/index.js index 77b9950..2a4553f 100644 --- a/lib/page/index.js +++ b/lib/page/index.js @@ -144,7 +144,17 @@ Page.prototype.parse = function(output) { var pipelineOpts = { onRelativeLink: _.partial(output.onRelativeLink, that), onImage: _.partial(output.onOutputImage, that), - onOutputSVG: _.partial(output.onOutputSVG, that) + onOutputSVG: _.partial(output.onOutputSVG, that), + + // Use 'code' template block + onCodeBlock: function(source, lang) { + return output.template.applyBlock('code', { + body: source, + kwargs: { + language: lang + } + }); + } }; var pipeline = new HTMLPipeline(that.content, pipelineOpts); |