summaryrefslogtreecommitdiffstats
path: root/lib/generate
diff options
context:
space:
mode:
authorSamy Pessé <samypesse@gmail.com>2014-04-06 15:03:27 -0700
committerSamy Pessé <samypesse@gmail.com>2014-04-06 15:03:27 -0700
commit74edc4f279c8748f072efe3b090a2414b351d697 (patch)
tree8e06317bc24bbfef142a01d6eadb9ef32d333c2f /lib/generate
parent52ccc2b46dbcec3fac7dd412ca05ccb8c2e26dc5 (diff)
parent696cbdc3b13905498e2832d43790567ac48799d0 (diff)
downloadgitbook-74edc4f279c8748f072efe3b090a2414b351d697.zip
gitbook-74edc4f279c8748f072efe3b090a2414b351d697.tar.gz
gitbook-74edc4f279c8748f072efe3b090a2414b351d697.tar.bz2
Merge pull request #39 from GitbookIO/feature/search
Feature/search
Diffstat (limited to 'lib/generate')
-rw-r--r--lib/generate/site/index.js38
-rw-r--r--lib/generate/site/search_indexer.js71
2 files changed, 107 insertions, 2 deletions
diff --git a/lib/generate/site/index.js b/lib/generate/site/index.js
index 9c3c10c..474de2a 100644
--- a/lib/generate/site/index.js
+++ b/lib/generate/site/index.js
@@ -8,6 +8,8 @@ var fs = require("../fs");
var parse = require("../../parse");
var BaseGenerator = require("../generator");
+var indexer = require('./search_indexer');
+
// Swig filter for returning the count of lines in a code section
swig.setFilter('lines', function(content) {
return content.split('\n').length;
@@ -21,6 +23,11 @@ swig.setFilter('mdLink', function(link) {
var Generator = function() {
BaseGenerator.apply(this, arguments);
+ // Attach methods to instance
+ _.bindAll(this);
+
+ this.indexer = indexer();
+
// Load base template
this.template = swig.compileFile(path.resolve(this.options.theme, 'templates/site.html'));
this.langsTemplate = swig.compileFile(path.resolve(this.options.theme, 'templates/langs.html'));
@@ -53,6 +60,11 @@ Generator.prototype._writeTemplate = function(tpl, options, output) {
});
};
+Generator.prototype.indexPage = function(lexed, pagePath) {
+ this.indexer.add(lexed, pagePath);
+ return Q();
+};
+
// Convert a markdown file to html
Generator.prototype.convertFile = function(content, _input) {
var that = this;
@@ -67,7 +79,17 @@ Generator.prototype.convertFile = function(content, _input) {
return Q()
.then(function() {
- return parse.page(content, {
+ // Lex page
+ return parse.lex(content);
+ })
+ .then(function(lexed) {
+ // Index page in search
+ return that.indexPage(lexed, _output)
+ .then(_.constant(lexed));
+ })
+ .then(function(lexed) {
+ // Get HTML generated sections
+ return parse.page(lexed, {
repo: that.options.githubId,
dir: path.dirname(input) || '/'
});
@@ -111,6 +133,18 @@ Generator.prototype.copyAssets = function() {
path.join(that.options.output, "gitbook")
);
};
-Generator.prototype.finish = Generator.prototype.copyAssets;
+
+// Dump search index to disk
+Generator.prototype.writeSearchIndex = function() {
+ return fs.writeFile(
+ path.join(this.options.output, 'search_index.json'),
+ this.indexer.dump()
+ );
+};
+
+Generator.prototype.finish = function() {
+ return this.copyAssets()
+ .then(this.writeSearchIndex);
+};
module.exports = Generator; \ No newline at end of file
diff --git a/lib/generate/site/search_indexer.js b/lib/generate/site/search_indexer.js
new file mode 100644
index 0000000..b239b8b
--- /dev/null
+++ b/lib/generate/site/search_indexer.js
@@ -0,0 +1,71 @@
+var Q = require("q");
+var _ = require("lodash");
+
+var lunr = require('lunr');
+var marked = require('marked');
+var textRenderer = require('marked-text-renderer');
+
+
+function Indexer() {
+ if(!(this instanceof Indexer)) {
+ return new Indexer();
+ }
+
+ _.bindAll(this);
+
+ // Setup lunr index
+ this.idx = lunr(function () {
+ this.ref('url');
+
+ this.field('title', { boost: 10 });
+ this.field('body');
+ });
+
+ this.renderer = textRenderer();
+}
+
+Indexer.prototype.text = function(nodes) {
+ // Copy section
+ var section = _.toArray(nodes);
+
+ // marked's Render expects this, we don't use it yet
+ section.links = {};
+
+ var options = _.extend({}, marked.defaults, {
+ renderer: this.renderer
+ });
+
+ return marked.parser(section, options);
+};
+
+Indexer.prototype.addSection = function(path, section) {
+ var url = [path, section.id].join('#');
+
+ var title = this.text(
+ _.filter(section, {'type': 'heading'})
+ );
+
+ var body = this.text(
+ _.omit(section, {'type': 'heading'})
+ );
+
+ // Add to lunr index
+ this.idx.add({
+ url: url,
+ title: title,
+ body: body,
+ });
+};
+
+Indexer.prototype.add = function(lexedPage, url) {
+ var sections = lexedPage;
+
+ _.map(sections, _.partial(this.addSection, url));
+};
+
+Indexer.prototype.dump = function() {
+ return JSON.stringify(this.idx);
+};
+
+// Exports
+module.exports = Indexer;