summaryrefslogtreecommitdiffstats
path: root/lib/page/html.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/page/html.js')
-rw-r--r--lib/page/html.js92
1 files changed, 63 insertions, 29 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.$);
});