Commit b1e0ff5d authored by Rouven Weßling's avatar Rouven Weßling Committed by Robert Lord

Update lunr.js to version 0.5.7

parent 3a236aa8
/** /**
* lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.2 * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.7
* Copyright (C) 2014 Oliver Nightingale * Copyright (C) 2014 Oliver Nightingale
* MIT Licensed * MIT Licensed
* @license * @license
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
(function(){ (function(){
/** /**
* Convenience function for instantiating a new lunr index and configuring it * Convenience function for instantiating a new lunr index and configuring it
* with the default pipeline functions and the passed config function. * with the default pipeline functions and the passed config function.
* *
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
* @returns {lunr.Index} * @returns {lunr.Index}
* *
*/ */
var lunr = function (config) { var lunr = function (config) {
var idx = new lunr.Index var idx = new lunr.Index
idx.pipeline.add( idx.pipeline.add(
...@@ -54,48 +54,48 @@ var lunr = function (config) { ...@@ -54,48 +54,48 @@ var lunr = function (config) {
if (config) config.call(idx, idx) if (config) config.call(idx, idx)
return idx return idx
} }
lunr.version = "0.5.2" lunr.version = "0.5.7"
/*! /*!
* lunr.utils * lunr.utils
* Copyright (C) 2014 Oliver Nightingale * Copyright (C) 2014 Oliver Nightingale
*/ */
/** /**
* A namespace containing utils for the rest of the lunr library * A namespace containing utils for the rest of the lunr library
*/ */
lunr.utils = {} lunr.utils = {}
/** /**
* Print a warning message to the console. * Print a warning message to the console.
* *
* @param {String} message The message to be printed. * @param {String} message The message to be printed.
* @memberOf Utils * @memberOf Utils
*/ */
lunr.utils.warn = (function (global) { lunr.utils.warn = (function (global) {
return function (message) { return function (message) {
if (global.console && console.warn) { if (global.console && console.warn) {
console.warn(message) console.warn(message)
} }
} }
})(this) })(this)
/*! /*!
* lunr.EventEmitter * lunr.EventEmitter
* Copyright (C) 2014 Oliver Nightingale * Copyright (C) 2014 Oliver Nightingale
*/ */
/** /**
* lunr.EventEmitter is an event emitter for lunr. It manages adding and removing event handlers and triggering events and their handlers. * lunr.EventEmitter is an event emitter for lunr. It manages adding and removing event handlers and triggering events and their handlers.
* *
* @constructor * @constructor
*/ */
lunr.EventEmitter = function () { lunr.EventEmitter = function () {
this.events = {} this.events = {}
} }
/** /**
* Binds a handler function to a specific event(s). * Binds a handler function to a specific event(s).
* *
* Can bind a single function to many different events in one call. * Can bind a single function to many different events in one call.
...@@ -104,7 +104,7 @@ lunr.EventEmitter = function () { ...@@ -104,7 +104,7 @@ lunr.EventEmitter = function () {
* @param {Function} handler The function to call when an event is fired. * @param {Function} handler The function to call when an event is fired.
* @memberOf EventEmitter * @memberOf EventEmitter
*/ */
lunr.EventEmitter.prototype.addListener = function () { lunr.EventEmitter.prototype.addListener = function () {
var args = Array.prototype.slice.call(arguments), var args = Array.prototype.slice.call(arguments),
fn = args.pop(), fn = args.pop(),
names = args names = args
...@@ -115,25 +115,25 @@ lunr.EventEmitter.prototype.addListener = function () { ...@@ -115,25 +115,25 @@ lunr.EventEmitter.prototype.addListener = function () {
if (!this.hasHandler(name)) this.events[name] = [] if (!this.hasHandler(name)) this.events[name] = []
this.events[name].push(fn) this.events[name].push(fn)
}, this) }, this)
} }
/** /**
* Removes a handler function from a specific event. * Removes a handler function from a specific event.
* *
* @param {String} eventName The name of the event to remove this function from. * @param {String} eventName The name of the event to remove this function from.
* @param {Function} handler The function to remove from an event. * @param {Function} handler The function to remove from an event.
* @memberOf EventEmitter * @memberOf EventEmitter
*/ */
lunr.EventEmitter.prototype.removeListener = function (name, fn) { lunr.EventEmitter.prototype.removeListener = function (name, fn) {
if (!this.hasHandler(name)) return if (!this.hasHandler(name)) return
var fnIndex = this.events[name].indexOf(fn) var fnIndex = this.events[name].indexOf(fn)
this.events[name].splice(fnIndex, 1) this.events[name].splice(fnIndex, 1)
if (!this.events[name].length) delete this.events[name] if (!this.events[name].length) delete this.events[name]
} }
/** /**
* Calls all functions bound to the given event. * Calls all functions bound to the given event.
* *
* Additional data can be passed to the event handler as arguments to `emit` * Additional data can be passed to the event handler as arguments to `emit`
...@@ -142,7 +142,7 @@ lunr.EventEmitter.prototype.removeListener = function (name, fn) { ...@@ -142,7 +142,7 @@ lunr.EventEmitter.prototype.removeListener = function (name, fn) {
* @param {String} eventName The name of the event to emit. * @param {String} eventName The name of the event to emit.
* @memberOf EventEmitter * @memberOf EventEmitter
*/ */
lunr.EventEmitter.prototype.emit = function (name) { lunr.EventEmitter.prototype.emit = function (name) {
if (!this.hasHandler(name)) return if (!this.hasHandler(name)) return
var args = Array.prototype.slice.call(arguments, 1) var args = Array.prototype.slice.call(arguments, 1)
...@@ -150,25 +150,25 @@ lunr.EventEmitter.prototype.emit = function (name) { ...@@ -150,25 +150,25 @@ lunr.EventEmitter.prototype.emit = function (name) {
this.events[name].forEach(function (fn) { this.events[name].forEach(function (fn) {
fn.apply(undefined, args) fn.apply(undefined, args)
}) })
} }
/** /**
* Checks whether a handler has ever been stored against an event. * Checks whether a handler has ever been stored against an event.
* *
* @param {String} eventName The name of the event to check. * @param {String} eventName The name of the event to check.
* @private * @private
* @memberOf EventEmitter * @memberOf EventEmitter
*/ */
lunr.EventEmitter.prototype.hasHandler = function (name) { lunr.EventEmitter.prototype.hasHandler = function (name) {
return name in this.events return name in this.events
} }
/*! /*!
* lunr.tokenizer * lunr.tokenizer
* Copyright (C) 2014 Oliver Nightingale * Copyright (C) 2014 Oliver Nightingale
*/ */
/** /**
* A function for splitting a string into tokens ready to be inserted into * A function for splitting a string into tokens ready to be inserted into
* the search index. * the search index.
* *
...@@ -176,7 +176,7 @@ lunr.EventEmitter.prototype.hasHandler = function (name) { ...@@ -176,7 +176,7 @@ lunr.EventEmitter.prototype.hasHandler = function (name) {
* @param {String} obj The string to convert into tokens * @param {String} obj The string to convert into tokens
* @returns {Array} * @returns {Array}
*/ */
lunr.tokenizer = function (obj) { lunr.tokenizer = function (obj) {
if (!arguments.length || obj == null || obj == undefined) return [] if (!arguments.length || obj == null || obj == undefined) return []
if (Array.isArray(obj)) return obj.map(function (t) { return t.toLowerCase() }) if (Array.isArray(obj)) return obj.map(function (t) { return t.toLowerCase() })
...@@ -190,17 +190,20 @@ lunr.tokenizer = function (obj) { ...@@ -190,17 +190,20 @@ lunr.tokenizer = function (obj) {
} }
return str return str
.split(/\s+/) .split(/(?:\s+|\-)/)
.filter(function (token) {
return !!token
})
.map(function (token) { .map(function (token) {
return token.toLowerCase() return token.toLowerCase()
}) })
} }
/*! /*!
* lunr.Pipeline * lunr.Pipeline
* Copyright (C) 2014 Oliver Nightingale * Copyright (C) 2014 Oliver Nightingale
*/ */
/** /**
* lunr.Pipelines maintain an ordered list of functions to be applied to all * lunr.Pipelines maintain an ordered list of functions to be applied to all
* tokens in documents entering the search index and queries being ran against * tokens in documents entering the search index and queries being ran against
* the index. * the index.
...@@ -229,13 +232,13 @@ lunr.tokenizer = function (obj) { ...@@ -229,13 +232,13 @@ lunr.tokenizer = function (obj) {
* *
* @constructor * @constructor
*/ */
lunr.Pipeline = function () { lunr.Pipeline = function () {
this._stack = [] this._stack = []
} }
lunr.Pipeline.registeredFunctions = {} lunr.Pipeline.registeredFunctions = {}
/** /**
* Register a function with the pipeline. * Register a function with the pipeline.
* *
* Functions that are used in the pipeline should be registered if the pipeline * Functions that are used in the pipeline should be registered if the pipeline
...@@ -248,31 +251,31 @@ lunr.Pipeline.registeredFunctions = {} ...@@ -248,31 +251,31 @@ lunr.Pipeline.registeredFunctions = {}
* @param {String} label The label to register this function with * @param {String} label The label to register this function with
* @memberOf Pipeline * @memberOf Pipeline
*/ */
lunr.Pipeline.registerFunction = function (fn, label) { lunr.Pipeline.registerFunction = function (fn, label) {
if (label in this.registeredFunctions) { if (label in this.registeredFunctions) {
lunr.utils.warn('Overwriting existing registered function: ' + label) lunr.utils.warn('Overwriting existing registered function: ' + label)
} }
fn.label = label fn.label = label
lunr.Pipeline.registeredFunctions[fn.label] = fn lunr.Pipeline.registeredFunctions[fn.label] = fn
} }
/** /**
* Warns if the function is not registered as a Pipeline function. * Warns if the function is not registered as a Pipeline function.
* *
* @param {Function} fn The function to check for. * @param {Function} fn The function to check for.
* @private * @private
* @memberOf Pipeline * @memberOf Pipeline
*/ */
lunr.Pipeline.warnIfFunctionNotRegistered = function (fn) { lunr.Pipeline.warnIfFunctionNotRegistered = function (fn) {
var isRegistered = fn.label && (fn.label in this.registeredFunctions) var isRegistered = fn.label && (fn.label in this.registeredFunctions)
if (!isRegistered) { if (!isRegistered) {
lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\n', fn) lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\n', fn)
} }
} }
/** /**
* Loads a previously serialised pipeline. * Loads a previously serialised pipeline.
* *
* All functions to be loaded must already be registered with lunr.Pipeline. * All functions to be loaded must already be registered with lunr.Pipeline.
...@@ -283,7 +286,7 @@ lunr.Pipeline.warnIfFunctionNotRegistered = function (fn) { ...@@ -283,7 +286,7 @@ lunr.Pipeline.warnIfFunctionNotRegistered = function (fn) {
* @returns {lunr.Pipeline} * @returns {lunr.Pipeline}
* @memberOf Pipeline * @memberOf Pipeline
*/ */
lunr.Pipeline.load = function (serialised) { lunr.Pipeline.load = function (serialised) {
var pipeline = new lunr.Pipeline var pipeline = new lunr.Pipeline
serialised.forEach(function (fnName) { serialised.forEach(function (fnName) {
...@@ -297,9 +300,9 @@ lunr.Pipeline.load = function (serialised) { ...@@ -297,9 +300,9 @@ lunr.Pipeline.load = function (serialised) {
}) })
return pipeline return pipeline
} }
/** /**
* Adds new functions to the end of the pipeline. * Adds new functions to the end of the pipeline.
* *
* Logs a warning if the function has not been registered. * Logs a warning if the function has not been registered.
...@@ -307,16 +310,16 @@ lunr.Pipeline.load = function (serialised) { ...@@ -307,16 +310,16 @@ lunr.Pipeline.load = function (serialised) {
* @param {Function} functions Any number of functions to add to the pipeline. * @param {Function} functions Any number of functions to add to the pipeline.
* @memberOf Pipeline * @memberOf Pipeline
*/ */
lunr.Pipeline.prototype.add = function () { lunr.Pipeline.prototype.add = function () {
var fns = Array.prototype.slice.call(arguments) var fns = Array.prototype.slice.call(arguments)
fns.forEach(function (fn) { fns.forEach(function (fn) {
lunr.Pipeline.warnIfFunctionNotRegistered(fn) lunr.Pipeline.warnIfFunctionNotRegistered(fn)
this._stack.push(fn) this._stack.push(fn)
}, this) }, this)
} }
/** /**
* Adds a single function after a function that already exists in the * Adds a single function after a function that already exists in the
* pipeline. * pipeline.
* *
...@@ -326,14 +329,14 @@ lunr.Pipeline.prototype.add = function () { ...@@ -326,14 +329,14 @@ lunr.Pipeline.prototype.add = function () {
* @param {Function} newFn The new function to add to the pipeline. * @param {Function} newFn The new function to add to the pipeline.
* @memberOf Pipeline * @memberOf Pipeline
*/ */
lunr.Pipeline.prototype.after = function (existingFn, newFn) { lunr.Pipeline.prototype.after = function (existingFn, newFn) {
lunr.Pipeline.warnIfFunctionNotRegistered(newFn) lunr.Pipeline.warnIfFunctionNotRegistered(newFn)
var pos = this._stack.indexOf(existingFn) + 1 var pos = this._stack.indexOf(existingFn) + 1
this._stack.splice(pos, 0, newFn) this._stack.splice(pos, 0, newFn)
} }
/** /**
* Adds a single function before a function that already exists in the * Adds a single function before a function that already exists in the
* pipeline. * pipeline.
* *
...@@ -343,25 +346,25 @@ lunr.Pipeline.prototype.after = function (existingFn, newFn) { ...@@ -343,25 +346,25 @@ lunr.Pipeline.prototype.after = function (existingFn, newFn) {
* @param {Function} newFn The new function to add to the pipeline. * @param {Function} newFn The new function to add to the pipeline.
* @memberOf Pipeline * @memberOf Pipeline
*/ */
lunr.Pipeline.prototype.before = function (existingFn, newFn) { lunr.Pipeline.prototype.before = function (existingFn, newFn) {
lunr.Pipeline.warnIfFunctionNotRegistered(newFn) lunr.Pipeline.warnIfFunctionNotRegistered(newFn)
var pos = this._stack.indexOf(existingFn) var pos = this._stack.indexOf(existingFn)
this._stack.splice(pos, 0, newFn) this._stack.splice(pos, 0, newFn)
} }
/** /**
* Removes a function from the pipeline. * Removes a function from the pipeline.
* *
* @param {Function} fn The function to remove from the pipeline. * @param {Function} fn The function to remove from the pipeline.
* @memberOf Pipeline * @memberOf Pipeline
*/ */
lunr.Pipeline.prototype.remove = function (fn) { lunr.Pipeline.prototype.remove = function (fn) {
var pos = this._stack.indexOf(fn) var pos = this._stack.indexOf(fn)
this._stack.splice(pos, 1) this._stack.splice(pos, 1)
} }
/** /**
* Runs the current list of functions that make up the pipeline against the * Runs the current list of functions that make up the pipeline against the
* passed tokens. * passed tokens.
* *
...@@ -369,7 +372,7 @@ lunr.Pipeline.prototype.remove = function (fn) { ...@@ -369,7 +372,7 @@ lunr.Pipeline.prototype.remove = function (fn) {
* @returns {Array} * @returns {Array}
* @memberOf Pipeline * @memberOf Pipeline
*/ */
lunr.Pipeline.prototype.run = function (tokens) { lunr.Pipeline.prototype.run = function (tokens) {
var out = [], var out = [],
tokenLength = tokens.length, tokenLength = tokens.length,
stackLength = this._stack.length stackLength = this._stack.length
...@@ -386,18 +389,18 @@ lunr.Pipeline.prototype.run = function (tokens) { ...@@ -386,18 +389,18 @@ lunr.Pipeline.prototype.run = function (tokens) {
}; };
return out return out
} }
/** /**
* Resets the pipeline by removing any existing processors. * Resets the pipeline by removing any existing processors.
* *
* @memberOf Pipeline * @memberOf Pipeline
*/ */
lunr.Pipeline.prototype.reset = function () { lunr.Pipeline.prototype.reset = function () {
this._stack = [] this._stack = []
} }
/** /**
* Returns a representation of the pipeline ready for serialisation. * Returns a representation of the pipeline ready for serialisation.
* *
* Logs a warning if the function has not been registered. * Logs a warning if the function has not been registered.
...@@ -405,31 +408,31 @@ lunr.Pipeline.prototype.reset = function () { ...@@ -405,31 +408,31 @@ lunr.Pipeline.prototype.reset = function () {
* @returns {Array} * @returns {Array}
* @memberOf Pipeline * @memberOf Pipeline
*/ */
lunr.Pipeline.prototype.toJSON = function () { lunr.Pipeline.prototype.toJSON = function () {
return this._stack.map(function (fn) { return this._stack.map(function (fn) {
lunr.Pipeline.warnIfFunctionNotRegistered(fn) lunr.Pipeline.warnIfFunctionNotRegistered(fn)
return fn.label return fn.label
}) })
} }
/*! /*!
* lunr.Vector * lunr.Vector
* Copyright (C) 2014 Oliver Nightingale * Copyright (C) 2014 Oliver Nightingale
*/ */
/** /**
* lunr.Vectors implement vector related operations for * lunr.Vectors implement vector related operations for
* a series of elements. * a series of elements.
* *
* @constructor * @constructor
*/ */
lunr.Vector = function () { lunr.Vector = function () {
this._magnitude = null this._magnitude = null
this.list = undefined this.list = undefined
this.length = 0 this.length = 0
} }
/** /**
* lunr.Vector.Node is a simple struct for each node * lunr.Vector.Node is a simple struct for each node
* in a lunr.Vector. * in a lunr.Vector.
* *
...@@ -440,20 +443,20 @@ lunr.Vector = function () { ...@@ -440,20 +443,20 @@ lunr.Vector = function () {
* @constructor * @constructor
* @memberOf Vector * @memberOf Vector
*/ */
lunr.Vector.Node = function (idx, val, next) { lunr.Vector.Node = function (idx, val, next) {
this.idx = idx this.idx = idx
this.val = val this.val = val
this.next = next this.next = next
} }
/** /**
* Inserts a new value at a position in a vector. * Inserts a new value at a position in a vector.
* *
* @param {Number} The index at which to insert a value. * @param {Number} The index at which to insert a value.
* @param {Object} The object to insert in the vector. * @param {Object} The object to insert in the vector.
* @memberOf Vector. * @memberOf Vector.
*/ */
lunr.Vector.prototype.insert = function (idx, val) { lunr.Vector.prototype.insert = function (idx, val) {
var list = this.list var list = this.list
if (!list) { if (!list) {
...@@ -475,15 +478,15 @@ lunr.Vector.prototype.insert = function (idx, val) { ...@@ -475,15 +478,15 @@ lunr.Vector.prototype.insert = function (idx, val) {
prev.next = new lunr.Vector.Node (idx, val, next) prev.next = new lunr.Vector.Node (idx, val, next)
return this.length++ return this.length++
} }
/** /**
* Calculates the magnitude of this vector. * Calculates the magnitude of this vector.
* *
* @returns {Number} * @returns {Number}
* @memberOf Vector * @memberOf Vector
*/ */
lunr.Vector.prototype.magnitude = function () { lunr.Vector.prototype.magnitude = function () {
if (this._magniture) return this._magnitude if (this._magniture) return this._magnitude
var node = this.list, var node = this.list,
sumOfSquares = 0, sumOfSquares = 0,
...@@ -496,16 +499,16 @@ lunr.Vector.prototype.magnitude = function () { ...@@ -496,16 +499,16 @@ lunr.Vector.prototype.magnitude = function () {
} }
return this._magnitude = Math.sqrt(sumOfSquares) return this._magnitude = Math.sqrt(sumOfSquares)
} }
/** /**
* Calculates the dot product of this vector and another vector. * Calculates the dot product of this vector and another vector.
* *
* @param {lunr.Vector} otherVector The vector to compute the dot product with. * @param {lunr.Vector} otherVector The vector to compute the dot product with.
* @returns {Number} * @returns {Number}
* @memberOf Vector * @memberOf Vector
*/ */
lunr.Vector.prototype.dot = function (otherVector) { lunr.Vector.prototype.dot = function (otherVector) {
var node = this.list, var node = this.list,
otherNode = otherVector.list, otherNode = otherVector.list,
dotProduct = 0 dotProduct = 0
...@@ -523,9 +526,9 @@ lunr.Vector.prototype.dot = function (otherVector) { ...@@ -523,9 +526,9 @@ lunr.Vector.prototype.dot = function (otherVector) {
} }
return dotProduct return dotProduct
} }
/** /**
* Calculates the cosine similarity between this vector and another * Calculates the cosine similarity between this vector and another
* vector. * vector.
* *
...@@ -534,68 +537,68 @@ lunr.Vector.prototype.dot = function (otherVector) { ...@@ -534,68 +537,68 @@ lunr.Vector.prototype.dot = function (otherVector) {
* @returns {Number} * @returns {Number}
* @memberOf Vector * @memberOf Vector
*/ */
lunr.Vector.prototype.similarity = function (otherVector) { lunr.Vector.prototype.similarity = function (otherVector) {
return this.dot(otherVector) / (this.magnitude() * otherVector.magnitude()) return this.dot(otherVector) / (this.magnitude() * otherVector.magnitude())
} }
/*! /*!
* lunr.SortedSet * lunr.SortedSet
* Copyright (C) 2014 Oliver Nightingale * Copyright (C) 2014 Oliver Nightingale
*/ */
/** /**
* lunr.SortedSets are used to maintain an array of uniq values in a sorted * lunr.SortedSets are used to maintain an array of uniq values in a sorted
* order. * order.
* *
* @constructor * @constructor
*/ */
lunr.SortedSet = function () { lunr.SortedSet = function () {
this.length = 0 this.length = 0
this.elements = [] this.elements = []
} }
/** /**
* Loads a previously serialised sorted set. * Loads a previously serialised sorted set.
* *
* @param {Array} serialisedData The serialised set to load. * @param {Array} serialisedData The serialised set to load.
* @returns {lunr.SortedSet} * @returns {lunr.SortedSet}
* @memberOf SortedSet * @memberOf SortedSet
*/ */
lunr.SortedSet.load = function (serialisedData) { lunr.SortedSet.load = function (serialisedData) {
var set = new this var set = new this
set.elements = serialisedData set.elements = serialisedData
set.length = serialisedData.length set.length = serialisedData.length
return set return set
} }
/** /**
* Inserts new items into the set in the correct position to maintain the * Inserts new items into the set in the correct position to maintain the
* order. * order.
* *
* @param {Object} The objects to add to this set. * @param {Object} The objects to add to this set.
* @memberOf SortedSet * @memberOf SortedSet
*/ */
lunr.SortedSet.prototype.add = function () { lunr.SortedSet.prototype.add = function () {
Array.prototype.slice.call(arguments).forEach(function (element) { Array.prototype.slice.call(arguments).forEach(function (element) {
if (~this.indexOf(element)) return if (~this.indexOf(element)) return
this.elements.splice(this.locationFor(element), 0, element) this.elements.splice(this.locationFor(element), 0, element)
}, this) }, this)
this.length = this.elements.length this.length = this.elements.length
} }
/** /**
* Converts this sorted set into an array. * Converts this sorted set into an array.
* *
* @returns {Array} * @returns {Array}
* @memberOf SortedSet * @memberOf SortedSet
*/ */
lunr.SortedSet.prototype.toArray = function () { lunr.SortedSet.prototype.toArray = function () {
return this.elements.slice() return this.elements.slice()
} }
/** /**
* Creates a new array with the results of calling a provided function on every * Creates a new array with the results of calling a provided function on every
* element in this sorted set. * element in this sorted set.
* *
...@@ -608,11 +611,11 @@ lunr.SortedSet.prototype.toArray = function () { ...@@ -608,11 +611,11 @@ lunr.SortedSet.prototype.toArray = function () {
* @returns {Array} * @returns {Array}
* @memberOf SortedSet * @memberOf SortedSet
*/ */
lunr.SortedSet.prototype.map = function (fn, ctx) { lunr.SortedSet.prototype.map = function (fn, ctx) {
return this.elements.map(fn, ctx) return this.elements.map(fn, ctx)
} }
/** /**
* Executes a provided function once per sorted set element. * Executes a provided function once per sorted set element.
* *
* Delegates to Array.prototype.forEach and has the same signature. * Delegates to Array.prototype.forEach and has the same signature.
...@@ -623,11 +626,11 @@ lunr.SortedSet.prototype.map = function (fn, ctx) { ...@@ -623,11 +626,11 @@ lunr.SortedSet.prototype.map = function (fn, ctx) {
* @memberOf SortedSet * @memberOf SortedSet
* for the function fn. * for the function fn.
*/ */
lunr.SortedSet.prototype.forEach = function (fn, ctx) { lunr.SortedSet.prototype.forEach = function (fn, ctx) {
return this.elements.forEach(fn, ctx) return this.elements.forEach(fn, ctx)
} }
/** /**
* Returns the index at which a given element can be found in the * Returns the index at which a given element can be found in the
* sorted set, or -1 if it is not present. * sorted set, or -1 if it is not present.
* *
...@@ -639,7 +642,7 @@ lunr.SortedSet.prototype.forEach = function (fn, ctx) { ...@@ -639,7 +642,7 @@ lunr.SortedSet.prototype.forEach = function (fn, ctx) {
* @returns {Number} * @returns {Number}
* @memberOf SortedSet * @memberOf SortedSet
*/ */
lunr.SortedSet.prototype.indexOf = function (elem, start, end) { lunr.SortedSet.prototype.indexOf = function (elem, start, end) {
var start = start || 0, var start = start || 0,
end = end || this.elements.length, end = end || this.elements.length,
sectionLength = end - start, sectionLength = end - start,
...@@ -657,9 +660,9 @@ lunr.SortedSet.prototype.indexOf = function (elem, start, end) { ...@@ -657,9 +660,9 @@ lunr.SortedSet.prototype.indexOf = function (elem, start, end) {
if (pivotElem < elem) return this.indexOf(elem, pivot, end) if (pivotElem < elem) return this.indexOf(elem, pivot, end)
if (pivotElem > elem) return this.indexOf(elem, start, pivot) if (pivotElem > elem) return this.indexOf(elem, start, pivot)
if (pivotElem === elem) return pivot if (pivotElem === elem) return pivot
} }
/** /**
* Returns the position within the sorted set that an element should be * Returns the position within the sorted set that an element should be
* inserted at to maintain the current order of the set. * inserted at to maintain the current order of the set.
* *
...@@ -674,7 +677,7 @@ lunr.SortedSet.prototype.indexOf = function (elem, start, end) { ...@@ -674,7 +677,7 @@ lunr.SortedSet.prototype.indexOf = function (elem, start, end) {
* @returns {Number} * @returns {Number}
* @memberOf SortedSet * @memberOf SortedSet
*/ */
lunr.SortedSet.prototype.locationFor = function (elem, start, end) { lunr.SortedSet.prototype.locationFor = function (elem, start, end) {
var start = start || 0, var start = start || 0,
end = end || this.elements.length, end = end || this.elements.length,
sectionLength = end - start, sectionLength = end - start,
...@@ -688,9 +691,9 @@ lunr.SortedSet.prototype.locationFor = function (elem, start, end) { ...@@ -688,9 +691,9 @@ lunr.SortedSet.prototype.locationFor = function (elem, start, end) {
if (pivotElem < elem) return this.locationFor(elem, pivot, end) if (pivotElem < elem) return this.locationFor(elem, pivot, end)
if (pivotElem > elem) return this.locationFor(elem, start, pivot) if (pivotElem > elem) return this.locationFor(elem, start, pivot)
} }
/** /**
* Creates a new lunr.SortedSet that contains the elements in the intersection * Creates a new lunr.SortedSet that contains the elements in the intersection
* of this set and the passed set. * of this set and the passed set.
* *
...@@ -698,7 +701,7 @@ lunr.SortedSet.prototype.locationFor = function (elem, start, end) { ...@@ -698,7 +701,7 @@ lunr.SortedSet.prototype.locationFor = function (elem, start, end) {
* @returns {lunr.SortedSet} * @returns {lunr.SortedSet}
* @memberOf SortedSet * @memberOf SortedSet
*/ */
lunr.SortedSet.prototype.intersect = function (otherSet) { lunr.SortedSet.prototype.intersect = function (otherSet) {
var intersectSet = new lunr.SortedSet, var intersectSet = new lunr.SortedSet,
i = 0, j = 0, i = 0, j = 0,
a_len = this.length, b_len = otherSet.length, a_len = this.length, b_len = otherSet.length,
...@@ -725,24 +728,24 @@ lunr.SortedSet.prototype.intersect = function (otherSet) { ...@@ -725,24 +728,24 @@ lunr.SortedSet.prototype.intersect = function (otherSet) {
}; };
return intersectSet return intersectSet
} }
/** /**
* Makes a copy of this set * Makes a copy of this set
* *
* @returns {lunr.SortedSet} * @returns {lunr.SortedSet}
* @memberOf SortedSet * @memberOf SortedSet
*/ */
lunr.SortedSet.prototype.clone = function () { lunr.SortedSet.prototype.clone = function () {
var clone = new lunr.SortedSet var clone = new lunr.SortedSet
clone.elements = this.toArray() clone.elements = this.toArray()
clone.length = clone.elements.length clone.length = clone.elements.length
return clone return clone
} }
/** /**
* Creates a new lunr.SortedSet that contains the elements in the union * Creates a new lunr.SortedSet that contains the elements in the union
* of this set and the passed set. * of this set and the passed set.
* *
...@@ -750,7 +753,7 @@ lunr.SortedSet.prototype.clone = function () { ...@@ -750,7 +753,7 @@ lunr.SortedSet.prototype.clone = function () {
* @returns {lunr.SortedSet} * @returns {lunr.SortedSet}
* @memberOf SortedSet * @memberOf SortedSet
*/ */
lunr.SortedSet.prototype.union = function (otherSet) { lunr.SortedSet.prototype.union = function (otherSet) {
var longSet, shortSet, unionSet var longSet, shortSet, unionSet
if (this.length >= otherSet.length) { if (this.length >= otherSet.length) {
...@@ -764,30 +767,30 @@ lunr.SortedSet.prototype.union = function (otherSet) { ...@@ -764,30 +767,30 @@ lunr.SortedSet.prototype.union = function (otherSet) {
unionSet.add.apply(unionSet, shortSet.toArray()) unionSet.add.apply(unionSet, shortSet.toArray())
return unionSet return unionSet
} }
/** /**
* Returns a representation of the sorted set ready for serialisation. * Returns a representation of the sorted set ready for serialisation.
* *
* @returns {Array} * @returns {Array}
* @memberOf SortedSet * @memberOf SortedSet
*/ */
lunr.SortedSet.prototype.toJSON = function () { lunr.SortedSet.prototype.toJSON = function () {
return this.toArray() return this.toArray()
} }
/*! /*!
* lunr.Index * lunr.Index
* Copyright (C) 2014 Oliver Nightingale * Copyright (C) 2014 Oliver Nightingale
*/ */
/** /**
* lunr.Index is object that manages a search index. It contains the indexes * lunr.Index is object that manages a search index. It contains the indexes
* and stores all the tokens and document lookups. It also provides the main * and stores all the tokens and document lookups. It also provides the main
* user facing API for the library. * user facing API for the library.
* *
* @constructor * @constructor
*/ */
lunr.Index = function () { lunr.Index = function () {
this._fields = [] this._fields = []
this._ref = 'id' this._ref = 'id'
this.pipeline = new lunr.Pipeline this.pipeline = new lunr.Pipeline
...@@ -801,9 +804,9 @@ lunr.Index = function () { ...@@ -801,9 +804,9 @@ lunr.Index = function () {
this.on('add', 'remove', 'update', (function () { this.on('add', 'remove', 'update', (function () {
this._idfCache = {} this._idfCache = {}
}).bind(this)) }).bind(this))
} }
/** /**
* Bind a handler to events being emitted by the index. * Bind a handler to events being emitted by the index.
* *
* The handler can be bound to many events at the same time. * The handler can be bound to many events at the same time.
...@@ -812,23 +815,23 @@ lunr.Index = function () { ...@@ -812,23 +815,23 @@ lunr.Index = function () {
* @param {Function} handler The serialised set to load. * @param {Function} handler The serialised set to load.
* @memberOf Index * @memberOf Index
*/ */
lunr.Index.prototype.on = function () { lunr.Index.prototype.on = function () {
var args = Array.prototype.slice.call(arguments) var args = Array.prototype.slice.call(arguments)
return this.eventEmitter.addListener.apply(this.eventEmitter, args) return this.eventEmitter.addListener.apply(this.eventEmitter, args)
} }
/** /**
* Removes a handler from an event being emitted by the index. * Removes a handler from an event being emitted by the index.
* *
* @param {String} eventName The name of events to remove the function from. * @param {String} eventName The name of events to remove the function from.
* @param {Function} handler The serialised set to load. * @param {Function} handler The serialised set to load.
* @memberOf Index * @memberOf Index
*/ */
lunr.Index.prototype.off = function (name, fn) { lunr.Index.prototype.off = function (name, fn) {
return this.eventEmitter.removeListener(name, fn) return this.eventEmitter.removeListener(name, fn)
} }
/** /**
* Loads a previously serialised index. * Loads a previously serialised index.
* *
* Issues a warning if the index being imported was serialised * Issues a warning if the index being imported was serialised
...@@ -838,7 +841,7 @@ lunr.Index.prototype.off = function (name, fn) { ...@@ -838,7 +841,7 @@ lunr.Index.prototype.off = function (name, fn) {
* @returns {lunr.Index} * @returns {lunr.Index}
* @memberOf Index * @memberOf Index
*/ */
lunr.Index.load = function (serialisedData) { lunr.Index.load = function (serialisedData) {
if (serialisedData.version !== lunr.version) { if (serialisedData.version !== lunr.version) {
lunr.utils.warn('version mismatch: current ' + lunr.version + ' importing ' + serialisedData.version) lunr.utils.warn('version mismatch: current ' + lunr.version + ' importing ' + serialisedData.version)
} }
...@@ -854,9 +857,9 @@ lunr.Index.load = function (serialisedData) { ...@@ -854,9 +857,9 @@ lunr.Index.load = function (serialisedData) {
idx.pipeline = lunr.Pipeline.load(serialisedData.pipeline) idx.pipeline = lunr.Pipeline.load(serialisedData.pipeline)
return idx return idx
} }
/** /**
* Adds a field to the list of fields that will be searchable within documents * Adds a field to the list of fields that will be searchable within documents
* in the index. * in the index.
* *
...@@ -874,15 +877,15 @@ lunr.Index.load = function (serialisedData) { ...@@ -874,15 +877,15 @@ lunr.Index.load = function (serialisedData) {
* @returns {lunr.Index} * @returns {lunr.Index}
* @memberOf Index * @memberOf Index
*/ */
lunr.Index.prototype.field = function (fieldName, opts) { lunr.Index.prototype.field = function (fieldName, opts) {
var opts = opts || {}, var opts = opts || {},
field = { name: fieldName, boost: opts.boost || 1 } field = { name: fieldName, boost: opts.boost || 1 }
this._fields.push(field) this._fields.push(field)
return this return this
} }
/** /**
* Sets the property used to uniquely identify documents added to the index, * Sets the property used to uniquely identify documents added to the index,
* by default this property is 'id'. * by default this property is 'id'.
* *
...@@ -895,12 +898,12 @@ lunr.Index.prototype.field = function (fieldName, opts) { ...@@ -895,12 +898,12 @@ lunr.Index.prototype.field = function (fieldName, opts) {
* @returns {lunr.Index} * @returns {lunr.Index}
* @memberOf Index * @memberOf Index
*/ */
lunr.Index.prototype.ref = function (refName) { lunr.Index.prototype.ref = function (refName) {
this._ref = refName this._ref = refName
return this return this
} }
/** /**
* Add a document to the index. * Add a document to the index.
* *
* This is the way new documents enter the index, this function will run the * This is the way new documents enter the index, this function will run the
...@@ -915,7 +918,7 @@ lunr.Index.prototype.ref = function (refName) { ...@@ -915,7 +918,7 @@ lunr.Index.prototype.ref = function (refName) {
* @param {Boolean} emitEvent Whether or not to emit events, default true. * @param {Boolean} emitEvent Whether or not to emit events, default true.
* @memberOf Index * @memberOf Index
*/ */
lunr.Index.prototype.add = function (doc, emitEvent) { lunr.Index.prototype.add = function (doc, emitEvent) {
var docTokens = {}, var docTokens = {},
allDocumentTokens = new lunr.SortedSet, allDocumentTokens = new lunr.SortedSet,
docRef = doc[this._ref], docRef = doc[this._ref],
...@@ -947,9 +950,9 @@ lunr.Index.prototype.add = function (doc, emitEvent) { ...@@ -947,9 +950,9 @@ lunr.Index.prototype.add = function (doc, emitEvent) {
}; };
if (emitEvent) this.eventEmitter.emit('add', doc, this) if (emitEvent) this.eventEmitter.emit('add', doc, this)
} }
/** /**
* Removes a document from the index. * Removes a document from the index.
* *
* To make sure documents no longer show up in search results they can be * To make sure documents no longer show up in search results they can be
...@@ -967,7 +970,7 @@ lunr.Index.prototype.add = function (doc, emitEvent) { ...@@ -967,7 +970,7 @@ lunr.Index.prototype.add = function (doc, emitEvent) {
* @param {Boolean} emitEvent Whether to emit remove events, defaults to true * @param {Boolean} emitEvent Whether to emit remove events, defaults to true
* @memberOf Index * @memberOf Index
*/ */
lunr.Index.prototype.remove = function (doc, emitEvent) { lunr.Index.prototype.remove = function (doc, emitEvent) {
var docRef = doc[this._ref], var docRef = doc[this._ref],
emitEvent = emitEvent === undefined ? true : emitEvent emitEvent = emitEvent === undefined ? true : emitEvent
...@@ -982,9 +985,9 @@ lunr.Index.prototype.remove = function (doc, emitEvent) { ...@@ -982,9 +985,9 @@ lunr.Index.prototype.remove = function (doc, emitEvent) {
}, this) }, this)
if (emitEvent) this.eventEmitter.emit('remove', doc, this) if (emitEvent) this.eventEmitter.emit('remove', doc, this)
} }
/** /**
* Updates a document in the index. * Updates a document in the index.
* *
* When a document contained within the index gets updated, fields changed, * When a document contained within the index gets updated, fields changed,
...@@ -1004,16 +1007,16 @@ lunr.Index.prototype.remove = function (doc, emitEvent) { ...@@ -1004,16 +1007,16 @@ lunr.Index.prototype.remove = function (doc, emitEvent) {
* @see Index.prototype.add * @see Index.prototype.add
* @memberOf Index * @memberOf Index
*/ */
lunr.Index.prototype.update = function (doc, emitEvent) { lunr.Index.prototype.update = function (doc, emitEvent) {
var emitEvent = emitEvent === undefined ? true : emitEvent var emitEvent = emitEvent === undefined ? true : emitEvent
this.remove(doc, false) this.remove(doc, false)
this.add(doc, false) this.add(doc, false)
if (emitEvent) this.eventEmitter.emit('update', doc, this) if (emitEvent) this.eventEmitter.emit('update', doc, this)
} }
/** /**
* Calculates the inverse document frequency for a token within the index. * Calculates the inverse document frequency for a token within the index.
* *
* @param {String} token The token to calculate the idf of. * @param {String} token The token to calculate the idf of.
...@@ -1021,7 +1024,7 @@ lunr.Index.prototype.update = function (doc, emitEvent) { ...@@ -1021,7 +1024,7 @@ lunr.Index.prototype.update = function (doc, emitEvent) {
* @private * @private
* @memberOf Index * @memberOf Index
*/ */
lunr.Index.prototype.idf = function (term) { lunr.Index.prototype.idf = function (term) {
var cacheKey = "@" + term var cacheKey = "@" + term
if (Object.prototype.hasOwnProperty.call(this._idfCache, cacheKey)) return this._idfCache[cacheKey] if (Object.prototype.hasOwnProperty.call(this._idfCache, cacheKey)) return this._idfCache[cacheKey]
...@@ -1033,9 +1036,9 @@ lunr.Index.prototype.idf = function (term) { ...@@ -1033,9 +1036,9 @@ lunr.Index.prototype.idf = function (term) {
} }
return this._idfCache[cacheKey] = idf return this._idfCache[cacheKey] = idf
} }
/** /**
* Searches the index using the passed query. * Searches the index using the passed query.
* *
* Queries should be a string, multiple words are allowed and will lead to an * Queries should be a string, multiple words are allowed and will lead to an
...@@ -1059,7 +1062,7 @@ lunr.Index.prototype.idf = function (term) { ...@@ -1059,7 +1062,7 @@ lunr.Index.prototype.idf = function (term) {
* @see Index.prototype.documentVector * @see Index.prototype.documentVector
* @memberOf Index * @memberOf Index
*/ */
lunr.Index.prototype.search = function (query) { lunr.Index.prototype.search = function (query) {
var queryTokens = this.pipeline.run(lunr.tokenizer(query)), var queryTokens = this.pipeline.run(lunr.tokenizer(query)),
queryVector = new lunr.Vector, queryVector = new lunr.Vector,
documentSets = [], documentSets = [],
...@@ -1115,9 +1118,9 @@ lunr.Index.prototype.search = function (query) { ...@@ -1115,9 +1118,9 @@ lunr.Index.prototype.search = function (query) {
.sort(function (a, b) { .sort(function (a, b) {
return b.score - a.score return b.score - a.score
}) })
} }
/** /**
* Generates a vector containing all the tokens in the document matching the * Generates a vector containing all the tokens in the document matching the
* passed documentRef. * passed documentRef.
* *
...@@ -1131,7 +1134,7 @@ lunr.Index.prototype.search = function (query) { ...@@ -1131,7 +1134,7 @@ lunr.Index.prototype.search = function (query) {
* @private * @private
* @memberOf Index * @memberOf Index
*/ */
lunr.Index.prototype.documentVector = function (documentRef) { lunr.Index.prototype.documentVector = function (documentRef) {
var documentTokens = this.documentStore.get(documentRef), var documentTokens = this.documentStore.get(documentRef),
documentTokensLength = documentTokens.length, documentTokensLength = documentTokens.length,
documentVector = new lunr.Vector documentVector = new lunr.Vector
...@@ -1145,15 +1148,15 @@ lunr.Index.prototype.documentVector = function (documentRef) { ...@@ -1145,15 +1148,15 @@ lunr.Index.prototype.documentVector = function (documentRef) {
}; };
return documentVector return documentVector
} }
/** /**
* Returns a representation of the index ready for serialisation. * Returns a representation of the index ready for serialisation.
* *
* @returns {Object} * @returns {Object}
* @memberOf Index * @memberOf Index
*/ */
lunr.Index.prototype.toJSON = function () { lunr.Index.prototype.toJSON = function () {
return { return {
version: lunr.version, version: lunr.version,
fields: this._fields, fields: this._fields,
...@@ -1163,9 +1166,9 @@ lunr.Index.prototype.toJSON = function () { ...@@ -1163,9 +1166,9 @@ lunr.Index.prototype.toJSON = function () {
corpusTokens: this.corpusTokens.toJSON(), corpusTokens: this.corpusTokens.toJSON(),
pipeline: this.pipeline.toJSON() pipeline: this.pipeline.toJSON()
} }
} }
/** /**
* Applies a plugin to the current index. * Applies a plugin to the current index.
* *
* A plugin is a function that is called with the index as its context. * A plugin is a function that is called with the index as its context.
...@@ -1191,36 +1194,36 @@ lunr.Index.prototype.toJSON = function () { ...@@ -1191,36 +1194,36 @@ lunr.Index.prototype.toJSON = function () {
* @param {Function} plugin The plugin to apply. * @param {Function} plugin The plugin to apply.
* @memberOf Index * @memberOf Index
*/ */
lunr.Index.prototype.use = function (plugin) { lunr.Index.prototype.use = function (plugin) {
var args = Array.prototype.slice.call(arguments, 1) var args = Array.prototype.slice.call(arguments, 1)
args.unshift(this) args.unshift(this)
plugin.apply(this, args) plugin.apply(this, args)
} }
/*! /*!
* lunr.Store * lunr.Store
* Copyright (C) 2014 Oliver Nightingale * Copyright (C) 2014 Oliver Nightingale
*/ */
/** /**
* lunr.Store is a simple key-value store used for storing sets of tokens for * lunr.Store is a simple key-value store used for storing sets of tokens for
* documents stored in index. * documents stored in index.
* *
* @constructor * @constructor
* @module * @module
*/ */
lunr.Store = function () { lunr.Store = function () {
this.store = {} this.store = {}
this.length = 0 this.length = 0
} }
/** /**
* Loads a previously serialised store * Loads a previously serialised store
* *
* @param {Object} serialisedData The serialised store to load. * @param {Object} serialisedData The serialised store to load.
* @returns {lunr.Store} * @returns {lunr.Store}
* @memberOf Store * @memberOf Store
*/ */
lunr.Store.load = function (serialisedData) { lunr.Store.load = function (serialisedData) {
var store = new this var store = new this
store.length = serialisedData.length store.length = serialisedData.length
...@@ -1230,75 +1233,75 @@ lunr.Store.load = function (serialisedData) { ...@@ -1230,75 +1233,75 @@ lunr.Store.load = function (serialisedData) {
}, {}) }, {})
return store return store
} }
/** /**
* Stores the given tokens in the store against the given id. * Stores the given tokens in the store against the given id.
* *
* @param {Object} id The key used to store the tokens against. * @param {Object} id The key used to store the tokens against.
* @param {Object} tokens The tokens to store against the key. * @param {Object} tokens The tokens to store against the key.
* @memberOf Store * @memberOf Store
*/ */
lunr.Store.prototype.set = function (id, tokens) { lunr.Store.prototype.set = function (id, tokens) {
if (!this.has(id)) this.length++
this.store[id] = tokens this.store[id] = tokens
this.length = Object.keys(this.store).length }
}
/** /**
* Retrieves the tokens from the store for a given key. * Retrieves the tokens from the store for a given key.
* *
* @param {Object} id The key to lookup and retrieve from the store. * @param {Object} id The key to lookup and retrieve from the store.
* @returns {Object} * @returns {Object}
* @memberOf Store * @memberOf Store
*/ */
lunr.Store.prototype.get = function (id) { lunr.Store.prototype.get = function (id) {
return this.store[id] return this.store[id]
} }
/** /**
* Checks whether the store contains a key. * Checks whether the store contains a key.
* *
* @param {Object} id The id to look up in the store. * @param {Object} id The id to look up in the store.
* @returns {Boolean} * @returns {Boolean}
* @memberOf Store * @memberOf Store
*/ */
lunr.Store.prototype.has = function (id) { lunr.Store.prototype.has = function (id) {
return id in this.store return id in this.store
} }
/** /**
* Removes the value for a key in the store. * Removes the value for a key in the store.
* *
* @param {Object} id The id to remove from the store. * @param {Object} id The id to remove from the store.
* @memberOf Store * @memberOf Store
*/ */
lunr.Store.prototype.remove = function (id) { lunr.Store.prototype.remove = function (id) {
if (!this.has(id)) return if (!this.has(id)) return
delete this.store[id] delete this.store[id]
this.length-- this.length--
} }
/** /**
* Returns a representation of the store ready for serialisation. * Returns a representation of the store ready for serialisation.
* *
* @returns {Object} * @returns {Object}
* @memberOf Store * @memberOf Store
*/ */
lunr.Store.prototype.toJSON = function () { lunr.Store.prototype.toJSON = function () {
return { return {
store: this.store, store: this.store,
length: this.length length: this.length
} }
} }
/*! /*!
* lunr.stemmer * lunr.stemmer
* Copyright (C) 2014 Oliver Nightingale * Copyright (C) 2014 Oliver Nightingale
* Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt
*/ */
/** /**
* lunr.stemmer is an english language stemmer, this is a JavaScript * lunr.stemmer is an english language stemmer, this is a JavaScript
* implementation of the PorterStemmer taken from http://tartaurs.org/~martin * implementation of the PorterStemmer taken from http://tartaurs.org/~martin
* *
...@@ -1307,7 +1310,7 @@ lunr.Store.prototype.toJSON = function () { ...@@ -1307,7 +1310,7 @@ lunr.Store.prototype.toJSON = function () {
* @returns {String} * @returns {String}
* @see lunr.Pipeline * @see lunr.Pipeline
*/ */
lunr.stemmer = (function(){ lunr.stemmer = (function(){
var step2list = { var step2list = {
"ational" : "ate", "ational" : "ate",
"tional" : "tion", "tional" : "tion",
...@@ -1352,7 +1355,33 @@ lunr.stemmer = (function(){ ...@@ -1352,7 +1355,33 @@ lunr.stemmer = (function(){
mgr1 = "^(" + C + ")?" + V + C + V + C, // [C]VCVC... is m>1 mgr1 = "^(" + C + ")?" + V + C + V + C, // [C]VCVC... is m>1
s_v = "^(" + C + ")?" + v; // vowel in stem s_v = "^(" + C + ")?" + v; // vowel in stem
return function (w) { var re_mgr0 = new RegExp(mgr0);
var re_mgr1 = new RegExp(mgr1);
var re_meq1 = new RegExp(meq1);
var re_s_v = new RegExp(s_v);
var re_1a = /^(.+?)(ss|i)es$/;
var re2_1a = /^(.+?)([^s])s$/;
var re_1b = /^(.+?)eed$/;
var re2_1b = /^(.+?)(ed|ing)$/;
var re_1b_2 = /.$/;
var re2_1b_2 = /(at|bl|iz)$/;
var re3_1b_2 = new RegExp("([^aeiouylsz])\\1$");
var re4_1b_2 = new RegExp("^" + C + v + "[^aeiouwxy]$");
var re_1c = /^(.+?[^aeiou])y$/;
var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
var re2_4 = /^(.+?)(s|t)(ion)$/;
var re_5 = /^(.+?)e$/;
var re_5_1 = /ll$/;
var re3_5 = new RegExp("^" + C + v + "[^aeiouwxy]$");
var porterStemmer = function porterStemmer(w) {
var stem, var stem,
suffix, suffix,
firstch, firstch,
...@@ -1369,106 +1398,105 @@ lunr.stemmer = (function(){ ...@@ -1369,106 +1398,105 @@ lunr.stemmer = (function(){
} }
// Step 1a // Step 1a
re = /^(.+?)(ss|i)es$/; re = re_1a
re2 = /^(.+?)([^s])s$/; re2 = re2_1a;
if (re.test(w)) { w = w.replace(re,"$1$2"); } if (re.test(w)) { w = w.replace(re,"$1$2"); }
else if (re2.test(w)) { w = w.replace(re2,"$1$2"); } else if (re2.test(w)) { w = w.replace(re2,"$1$2"); }
// Step 1b // Step 1b
re = /^(.+?)eed$/; re = re_1b;
re2 = /^(.+?)(ed|ing)$/; re2 = re2_1b;
if (re.test(w)) { if (re.test(w)) {
var fp = re.exec(w); var fp = re.exec(w);
re = new RegExp(mgr0); re = re_mgr0;
if (re.test(fp[1])) { if (re.test(fp[1])) {
re = /.$/; re = re_1b_2;
w = w.replace(re,""); w = w.replace(re,"");
} }
} else if (re2.test(w)) { } else if (re2.test(w)) {
var fp = re2.exec(w); var fp = re2.exec(w);
stem = fp[1]; stem = fp[1];
re2 = new RegExp(s_v); re2 = re_s_v;
if (re2.test(stem)) { if (re2.test(stem)) {
w = stem; w = stem;
re2 = /(at|bl|iz)$/; re2 = re2_1b_2;
re3 = new RegExp("([^aeiouylsz])\\1$"); re3 = re3_1b_2;
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); re4 = re4_1b_2;
if (re2.test(w)) { w = w + "e"; } if (re2.test(w)) { w = w + "e"; }
else if (re3.test(w)) { re = /.$/; w = w.replace(re,""); } else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,""); }
else if (re4.test(w)) { w = w + "e"; } else if (re4.test(w)) { w = w + "e"; }
} }
} }
// Step 1c // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say)
re = /^(.+?)y$/; re = re_1c;
if (re.test(w)) { if (re.test(w)) {
var fp = re.exec(w); var fp = re.exec(w);
stem = fp[1]; stem = fp[1];
re = new RegExp(s_v); w = stem + "i";
if (re.test(stem)) { w = stem + "i"; }
} }
// Step 2 // Step 2
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; re = re_2;
if (re.test(w)) { if (re.test(w)) {
var fp = re.exec(w); var fp = re.exec(w);
stem = fp[1]; stem = fp[1];
suffix = fp[2]; suffix = fp[2];
re = new RegExp(mgr0); re = re_mgr0;
if (re.test(stem)) { if (re.test(stem)) {
w = stem + step2list[suffix]; w = stem + step2list[suffix];
} }
} }
// Step 3 // Step 3
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; re = re_3;
if (re.test(w)) { if (re.test(w)) {
var fp = re.exec(w); var fp = re.exec(w);
stem = fp[1]; stem = fp[1];
suffix = fp[2]; suffix = fp[2];
re = new RegExp(mgr0); re = re_mgr0;
if (re.test(stem)) { if (re.test(stem)) {
w = stem + step3list[suffix]; w = stem + step3list[suffix];
} }
} }
// Step 4 // Step 4
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; re = re_4;
re2 = /^(.+?)(s|t)(ion)$/; re2 = re2_4;
if (re.test(w)) { if (re.test(w)) {
var fp = re.exec(w); var fp = re.exec(w);
stem = fp[1]; stem = fp[1];
re = new RegExp(mgr1); re = re_mgr1;
if (re.test(stem)) { if (re.test(stem)) {
w = stem; w = stem;
} }
} else if (re2.test(w)) { } else if (re2.test(w)) {
var fp = re2.exec(w); var fp = re2.exec(w);
stem = fp[1] + fp[2]; stem = fp[1] + fp[2];
re2 = new RegExp(mgr1); re2 = re_mgr1;
if (re2.test(stem)) { if (re2.test(stem)) {
w = stem; w = stem;
} }
} }
// Step 5 // Step 5
re = /^(.+?)e$/; re = re_5;
if (re.test(w)) { if (re.test(w)) {
var fp = re.exec(w); var fp = re.exec(w);
stem = fp[1]; stem = fp[1];
re = new RegExp(mgr1); re = re_mgr1;
re2 = new RegExp(meq1); re2 = re_meq1;
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); re3 = re3_5;
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) { if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) {
w = stem; w = stem;
} }
} }
re = /ll$/; re = re_5_1;
re2 = new RegExp(mgr1); re2 = re_mgr1;
if (re.test(w) && re2.test(w)) { if (re.test(w) && re2.test(w)) {
re = /.$/; re = re_1b_2;
w = w.replace(re,""); w = w.replace(re,"");
} }
...@@ -1479,16 +1507,18 @@ lunr.stemmer = (function(){ ...@@ -1479,16 +1507,18 @@ lunr.stemmer = (function(){
} }
return w; return w;
} };
})();
return porterStemmer;
})();
lunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer') lunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer')
/*! /*!
* lunr.stopWordFilter * lunr.stopWordFilter
* Copyright (C) 2014 Oliver Nightingale * Copyright (C) 2014 Oliver Nightingale
*/ */
/** /**
* lunr.stopWordFilter is an English language stop word list filter, any words * lunr.stopWordFilter is an English language stop word list filter, any words
* contained in the list will not be passed through the filter. * contained in the list will not be passed through the filter.
* *
...@@ -1500,13 +1530,13 @@ lunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer') ...@@ -1500,13 +1530,13 @@ lunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer')
* @returns {String} * @returns {String}
* @see lunr.Pipeline * @see lunr.Pipeline
*/ */
lunr.stopWordFilter = function (token) { lunr.stopWordFilter = function (token) {
if (lunr.stopWordFilter.stopWords.indexOf(token) === -1) return token if (lunr.stopWordFilter.stopWords.indexOf(token) === -1) return token
} }
lunr.stopWordFilter.stopWords = new lunr.SortedSet lunr.stopWordFilter.stopWords = new lunr.SortedSet
lunr.stopWordFilter.stopWords.length = 119 lunr.stopWordFilter.stopWords.length = 119
lunr.stopWordFilter.stopWords.elements = [ lunr.stopWordFilter.stopWords.elements = [
"", "",
"a", "a",
"able", "able",
...@@ -1627,15 +1657,15 @@ lunr.stopWordFilter.stopWords.elements = [ ...@@ -1627,15 +1657,15 @@ lunr.stopWordFilter.stopWords.elements = [
"yet", "yet",
"you", "you",
"your" "your"
] ]
lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter') lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter')
/*! /*!
* lunr.trimmer * lunr.trimmer
* Copyright (C) 2014 Oliver Nightingale * Copyright (C) 2014 Oliver Nightingale
*/ */
/** /**
* lunr.trimmer is a pipeline function for trimming non word * lunr.trimmer is a pipeline function for trimming non word
* characters from the begining and end of tokens before they * characters from the begining and end of tokens before they
* enter the index. * enter the index.
...@@ -1649,47 +1679,47 @@ lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter') ...@@ -1649,47 +1679,47 @@ lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter')
* @returns {String} * @returns {String}
* @see lunr.Pipeline * @see lunr.Pipeline
*/ */
lunr.trimmer = function (token) { lunr.trimmer = function (token) {
return token return token
.replace(/^\W+/, '') .replace(/^\W+/, '')
.replace(/\W+$/, '') .replace(/\W+$/, '')
} }
lunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer') lunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer')
/*! /*!
* lunr.stemmer * lunr.stemmer
* Copyright (C) 2014 Oliver Nightingale * Copyright (C) 2014 Oliver Nightingale
* Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt
*/ */
/** /**
* lunr.TokenStore is used for efficient storing and lookup of the reverse * lunr.TokenStore is used for efficient storing and lookup of the reverse
* index of token to document ref. * index of token to document ref.
* *
* @constructor * @constructor
*/ */
lunr.TokenStore = function () { lunr.TokenStore = function () {
this.root = { docs: {} } this.root = { docs: {} }
this.length = 0 this.length = 0
} }
/** /**
* Loads a previously serialised token store * Loads a previously serialised token store
* *
* @param {Object} serialisedData The serialised token store to load. * @param {Object} serialisedData The serialised token store to load.
* @returns {lunr.TokenStore} * @returns {lunr.TokenStore}
* @memberOf TokenStore * @memberOf TokenStore
*/ */
lunr.TokenStore.load = function (serialisedData) { lunr.TokenStore.load = function (serialisedData) {
var store = new this var store = new this
store.root = serialisedData.root store.root = serialisedData.root
store.length = serialisedData.length store.length = serialisedData.length
return store return store
} }
/** /**
* Adds a new token doc pair to the store. * Adds a new token doc pair to the store.
* *
* By default this function starts at the root of the current store, however * By default this function starts at the root of the current store, however
...@@ -1702,7 +1732,7 @@ lunr.TokenStore.load = function (serialisedData) { ...@@ -1702,7 +1732,7 @@ lunr.TokenStore.load = function (serialisedData) {
* is used. * is used.
* @memberOf TokenStore * @memberOf TokenStore
*/ */
lunr.TokenStore.prototype.add = function (token, doc, root) { lunr.TokenStore.prototype.add = function (token, doc, root) {
var root = root || this.root, var root = root || this.root,
key = token[0], key = token[0],
rest = token.slice(1) rest = token.slice(1)
...@@ -1716,9 +1746,9 @@ lunr.TokenStore.prototype.add = function (token, doc, root) { ...@@ -1716,9 +1746,9 @@ lunr.TokenStore.prototype.add = function (token, doc, root) {
} else { } else {
return this.add(rest, doc, root[key]) return this.add(rest, doc, root[key])
} }
} }
/** /**
* Checks whether this key is contained within this lunr.TokenStore. * Checks whether this key is contained within this lunr.TokenStore.
* *
* By default this function starts at the root of the current store, however * By default this function starts at the root of the current store, however
...@@ -1728,7 +1758,7 @@ lunr.TokenStore.prototype.add = function (token, doc, root) { ...@@ -1728,7 +1758,7 @@ lunr.TokenStore.prototype.add = function (token, doc, root) {
* @param {Object} root An optional node at which to start * @param {Object} root An optional node at which to start
* @memberOf TokenStore * @memberOf TokenStore
*/ */
lunr.TokenStore.prototype.has = function (token) { lunr.TokenStore.prototype.has = function (token) {
if (!token) return false if (!token) return false
var node = this.root var node = this.root
...@@ -1740,9 +1770,9 @@ lunr.TokenStore.prototype.has = function (token) { ...@@ -1740,9 +1770,9 @@ lunr.TokenStore.prototype.has = function (token) {
} }
return true return true
} }
/** /**
* Retrieve a node from the token store for a given token. * Retrieve a node from the token store for a given token.
* *
* By default this function starts at the root of the current store, however * By default this function starts at the root of the current store, however
...@@ -1754,7 +1784,7 @@ lunr.TokenStore.prototype.has = function (token) { ...@@ -1754,7 +1784,7 @@ lunr.TokenStore.prototype.has = function (token) {
* @see TokenStore.prototype.get * @see TokenStore.prototype.get
* @memberOf TokenStore * @memberOf TokenStore
*/ */
lunr.TokenStore.prototype.getNode = function (token) { lunr.TokenStore.prototype.getNode = function (token) {
if (!token) return {} if (!token) return {}
var node = this.root var node = this.root
...@@ -1766,9 +1796,9 @@ lunr.TokenStore.prototype.getNode = function (token) { ...@@ -1766,9 +1796,9 @@ lunr.TokenStore.prototype.getNode = function (token) {
} }
return node return node
} }
/** /**
* Retrieve the documents for a node for the given token. * Retrieve the documents for a node for the given token.
* *
* By default this function starts at the root of the current store, however * By default this function starts at the root of the current store, however
...@@ -1779,15 +1809,15 @@ lunr.TokenStore.prototype.getNode = function (token) { ...@@ -1779,15 +1809,15 @@ lunr.TokenStore.prototype.getNode = function (token) {
* @returns {Object} * @returns {Object}
* @memberOf TokenStore * @memberOf TokenStore
*/ */
lunr.TokenStore.prototype.get = function (token, root) { lunr.TokenStore.prototype.get = function (token, root) {
return this.getNode(token, root).docs || {} return this.getNode(token, root).docs || {}
} }
lunr.TokenStore.prototype.count = function (token, root) { lunr.TokenStore.prototype.count = function (token, root) {
return Object.keys(this.get(token, root)).length return Object.keys(this.get(token, root)).length
} }
/** /**
* Remove the document identified by ref from the token in the store. * Remove the document identified by ref from the token in the store.
* *
* By default this function starts at the root of the current store, however * By default this function starts at the root of the current store, however
...@@ -1799,7 +1829,7 @@ lunr.TokenStore.prototype.count = function (token, root) { ...@@ -1799,7 +1829,7 @@ lunr.TokenStore.prototype.count = function (token, root) {
* @returns {Object} * @returns {Object}
* @memberOf TokenStore * @memberOf TokenStore
*/ */
lunr.TokenStore.prototype.remove = function (token, ref) { lunr.TokenStore.prototype.remove = function (token, ref) {
if (!token) return if (!token) return
var node = this.root var node = this.root
...@@ -1809,9 +1839,9 @@ lunr.TokenStore.prototype.remove = function (token, ref) { ...@@ -1809,9 +1839,9 @@ lunr.TokenStore.prototype.remove = function (token, ref) {
} }
delete node.docs[ref] delete node.docs[ref]
} }
/** /**
* Find all the possible suffixes of the passed token using tokens * Find all the possible suffixes of the passed token using tokens
* currently in the store. * currently in the store.
* *
...@@ -1819,7 +1849,7 @@ lunr.TokenStore.prototype.remove = function (token, ref) { ...@@ -1819,7 +1849,7 @@ lunr.TokenStore.prototype.remove = function (token, ref) {
* @returns {Array} * @returns {Array}
* @memberOf TokenStore * @memberOf TokenStore
*/ */
lunr.TokenStore.prototype.expand = function (token, memo) { lunr.TokenStore.prototype.expand = function (token, memo) {
var root = this.getNode(token), var root = this.getNode(token),
docs = root.docs || {}, docs = root.docs || {},
memo = memo || [] memo = memo || []
...@@ -1834,24 +1864,24 @@ lunr.TokenStore.prototype.expand = function (token, memo) { ...@@ -1834,24 +1864,24 @@ lunr.TokenStore.prototype.expand = function (token, memo) {
}, this) }, this)
return memo return memo
} }
/** /**
* Returns a representation of the token store ready for serialisation. * Returns a representation of the token store ready for serialisation.
* *
* @returns {Object} * @returns {Object}
* @memberOf TokenStore * @memberOf TokenStore
*/ */
lunr.TokenStore.prototype.toJSON = function () { lunr.TokenStore.prototype.toJSON = function () {
return { return {
root: this.root, root: this.root,
length: this.length length: this.length
} }
} }
/** /**
* export the module via AMD, CommonnJS or as a browser global * export the module via AMD, CommonJS or as a browser global
* Export code from https://github.com/umdjs/umd/blob/master/returnExports.js * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
*/ */
;(function (root, factory) { ;(function (root, factory) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment