Merge pull request #411 from GitbookIO/glossary-search

Glossary search
This commit is contained in:
Samy Pessé
2014-08-18 19:14:14 -07:00
6 changed files with 121 additions and 5 deletions
+103
View File
@@ -0,0 +1,103 @@
var _ = require("lodash");
var kramed = require('kramed');
var textRenderer = require('kramed-text-renderer');
var entryId = require('../../parse/glossary').entryId;
function Indexer(glossary) {
if(!(this instanceof Indexer)) {
return new Indexer(glossary);
}
_.bindAll(this);
this.glossary = glossary || [];
this.glossaryTerms = _.pluck(this.glossary, "id");
// Regex for searching for terms through body
this.termsRegex = new RegExp(
// Match any of the terms
"("+
this.glossaryTerms.map(regexEscape).join('|') +
")",
// Flags
"gi"
);
// debug
console.log('term regex =', this.termsRegex);
// page url => terms
this.idx = {
/*
"a/b.html": ["one word", "second word"]
*/
};
// term => page urls
this.invertedIdx = {
/*
"word1": ["page1.html", "page2.html"]
*/
};
// Use text renderer
this.renderer = textRenderer();
}
Indexer.prototype.text = function(nodes) {
// Copy section
var section = _.toArray(nodes);
// kramed's Render expects this, we don't use it yet
section.links = {};
var options = _.extend({}, kramed.defaults, {
renderer: this.renderer
});
return kramed.parser(section, options);
};
// Add page to glossary index
Indexer.prototype.add = function(sections, url) {
if(!(this.glossary && this.glossary.length > 0)) {
console.log('Glossary =', this.glossary);
console.log('No glossary to match');
return;
}
var textblob =
_.where(sections, { type: 'normal' })
.map(this.text)
.join('\n');
var matches = _(textblob.match(this.termsRegex) || [])
.map(entryId)
.uniq()
.value();
// Add idx for book
this.idx[url] = matches;
// Add to inverted idx
matches.forEach(function(match) {
if(!this.invertedIdx[match]) {
this.invertedIdx[match] = [];
}
this.invertedIdx[match].push(url);
}.bind(this));
};
function regexEscape(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
// Exports
module.exports = Indexer;
+7 -1
View File
@@ -9,7 +9,7 @@ var parse = require("../../parse");
var BaseGenerator = require("../generator");
var links = require("../../utils/links");
var indexer = require('./search_indexer');
var glossaryIndexer = require('./glossary_indexer');
var Generator = function() {
@@ -85,7 +85,13 @@ Generator.prototype._writeTemplate = function(tpl, options, output, interpolate)
};
Generator.prototype.indexPage = function(lexed, pagePath) {
// Setup glossary indexer if not yet setup
if(!this.glossaryIndexer) {
this.glossaryIndexer = glossaryIndexer(this.options.glossary);
}
this.indexer.add(lexed, pagePath);
this.glossaryIndexer.add(lexed, pagePath);
return Q();
};
+1 -1
View File
@@ -3,7 +3,7 @@ var _ = require("lodash");
var lunr = require('lunr');
var kramed = require('kramed');
var textRenderer = require('marked-text-renderer');
var textRenderer = require('kramed-text-renderer');
function Indexer() {
+7
View File
@@ -33,9 +33,16 @@ function parseGlossary(src) {
// Simplify each group to a simple object with name/description
return {
name: pair[0].text,
id: entryId(pair[0].text),
description: pair[1].text,
};
});
}
// Normalizes a glossary entry's name to create an ID
function entryId(name) {
return name.toLowerCase();
}
module.exports = parseGlossary;
module.exports.entryId = entryId;
+1 -1
View File
@@ -1,6 +1,6 @@
var _ = require('lodash');
var kramed = require('kramed');
var textRenderer = require('marked-text-renderer');
var textRenderer = require('kramed-text-renderer');
function extractFirstNode(nodes, nType) {
return _.chain(nodes)
+2 -2
View File
@@ -7,8 +7,8 @@
"dependencies": {
"q": "1.0.1",
"lodash": "2.4.1",
"kramed": "0.4.0",
"marked-text-renderer": "0.1.0",
"kramed": "0.4.1",
"kramed-text-renderer": "0.2.1",
"lunr": "0.5.2",
"swig": "1.3.2",
"send": "0.2.0",