summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSamy Pessé <samypesse@gmail.com>2015-01-22 19:09:03 +0100
committerSamy Pessé <samypesse@gmail.com>2015-01-22 19:09:03 +0100
commit9e172549d162ce6ec2d0e454db997418a2b9795f (patch)
treee31811c32a9b3d418a7d70a66a84d5caeb6f7175 /lib
parent0ba36c6f4ed316cc157c701abe4728d64da231b4 (diff)
downloadgitbook-9e172549d162ce6ec2d0e454db997418a2b9795f.zip
gitbook-9e172549d162ce6ec2d0e454db997418a2b9795f.tar.gz
gitbook-9e172549d162ce6ec2d0e454db997418a2b9795f.tar.bz2
Mark glossary terms in html parsed
Diffstat (limited to 'lib')
-rw-r--r--lib/book.js3
-rw-r--r--lib/utils/page.js71
2 files changed, 72 insertions, 2 deletions
diff --git a/lib/book.js b/lib/book.js
index 639adef..036844f 100644
--- a/lib/book.js
+++ b/lib/book.js
@@ -327,7 +327,8 @@ Book.prototype.parsePage = function(filename) {
page.sections = pageUtil.normalize(page.sections, {
navigation: that.navigation,
base: path.dirname(filename) || './',
- output: path.dirname(filename) || './'
+ output: path.dirname(filename) || './',
+ glossary: that.glossary
});
return page;
diff --git a/lib/utils/page.js b/lib/utils/page.js
index 00e4757..8fa704d 100644
--- a/lib/utils/page.js
+++ b/lib/utils/page.js
@@ -4,6 +4,60 @@ var cheerio = require('cheerio');
var links = require('./links');
+function replaceText($, el, search, replace, text_only ) {
+ return $(el).each(function(){
+ var node = this.firstChild,
+ val,
+ new_val,
+
+ // Elements to be removed at the end.
+ remove = [];
+
+ // Only continue if firstChild exists.
+ if ( node ) {
+
+ // Loop over all childNodes.
+ do {
+ // Only process text nodes.
+ if ( node.nodeType === 3 ) {
+
+ // The original node value.
+ val = node.nodeValue;
+
+ // The new value.
+ new_val = val.replace( search, replace );
+
+ // Only replace text if the new value is actually different!
+ if ( new_val !== val ) {
+
+ if ( !text_only && /</.test( new_val ) ) {
+ // The new value contains HTML, set it in a slower but far more
+ // robust way.
+ $(node).before( new_val );
+
+ // Don't remove the node yet, or the loop will lose its place.
+ remove.push( node );
+ } else {
+ // The new value contains no HTML, so it can be set in this
+ // very fast, simple way.
+ node.nodeValue = new_val;
+ }
+ }
+ }
+
+ } while ( node = node.nextSibling );
+ }
+
+ // Time to remove those elements!
+ remove.length && $(remove).remove();
+ });
+};
+
+function pregQuote( str ) {
+ return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1");
+};
+
+
// Adapt an html snippet to be relative to a base folder
function normalizeHtml(src, options) {
var $ = cheerio.load(src);
@@ -38,9 +92,21 @@ function normalizeHtml(src, options) {
$(this).attr("href", href);
});
+ // Replace glossayr terms
+ _.each(options.glossary, function(term) {
+ var r = new RegExp( "\\b(" + pregQuote(term.name.toLowerCase()) + ")\\b" , 'gi' );
+
+ $("*").each(function() {
+ replaceText($, this, r, function(match) {
+ return "<span class='glossary-term' data-glossary-term='"+term.id+"' title='"+term.description+"'>"+match+"</span>";
+ });
+ });
+ });
+
return $.html();
};
+
// Adapt page content to be relative to a base folder
function normalizePage(sections, options) {
options = _.defaults(options || {}, {
@@ -51,7 +117,10 @@ function normalizePage(sections, options) {
base: "./",
// Directory parent from the html output
- output: "./"
+ output: "./",
+
+ // Glossary terms
+ glossary: []
});
return _.map(sections, function(section) {