diff options
author | Samy Pessé <samypesse@gmail.com> | 2015-01-22 19:09:03 +0100 |
---|---|---|
committer | Samy Pessé <samypesse@gmail.com> | 2015-01-22 19:09:03 +0100 |
commit | 9e172549d162ce6ec2d0e454db997418a2b9795f (patch) | |
tree | e31811c32a9b3d418a7d70a66a84d5caeb6f7175 /lib/utils/page.js | |
parent | 0ba36c6f4ed316cc157c701abe4728d64da231b4 (diff) | |
download | gitbook-9e172549d162ce6ec2d0e454db997418a2b9795f.zip gitbook-9e172549d162ce6ec2d0e454db997418a2b9795f.tar.gz gitbook-9e172549d162ce6ec2d0e454db997418a2b9795f.tar.bz2 |
Mark glossary terms in html parsed
Diffstat (limited to 'lib/utils/page.js')
-rw-r--r-- | lib/utils/page.js | 71 |
1 files changed, 70 insertions, 1 deletions
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) { |