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