193 lines
4.8 KiB
JavaScript
193 lines
4.8 KiB
JavaScript
/*!
|
|
* lunr.stemmer
|
|
* Copyright (C) @YEAR 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 () {
|
|
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) {
|
|
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
|
|
* it can start at any node of any token store if required.
|
|
*
|
|
* @param {String} token The token to store the doc under
|
|
* @param {Object} doc The doc to store against the token
|
|
* @param {Object} root An optional node at which to start looking for the
|
|
* correct place to enter the doc, by default the root of this lunr.TokenStore
|
|
* is used.
|
|
* @memberOf TokenStore
|
|
*/
|
|
lunr.TokenStore.prototype.add = function (token, doc, root) {
|
|
var root = root || this.root,
|
|
key = token.charAt(0),
|
|
rest = token.slice(1)
|
|
|
|
if (!(key in root)) root[key] = {docs: {}}
|
|
|
|
if (rest.length === 0) {
|
|
root[key].docs[doc.ref] = doc
|
|
this.length += 1
|
|
return
|
|
} 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
|
|
* it can start at any node of any token store if required.
|
|
*
|
|
* @param {String} token The token to check for
|
|
* @param {Object} root An optional node at which to start
|
|
* @memberOf TokenStore
|
|
*/
|
|
lunr.TokenStore.prototype.has = function (token) {
|
|
if (!token) return false
|
|
|
|
var node = this.root
|
|
|
|
for (var i = 0; i < token.length; i++) {
|
|
if (!node[token.charAt(i)]) return false
|
|
|
|
node = node[token.charAt(i)]
|
|
}
|
|
|
|
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
|
|
* it can start at any node of any token store if required.
|
|
*
|
|
* @param {String} token The token to get the node for.
|
|
* @param {Object} root An optional node at which to start.
|
|
* @returns {Object}
|
|
* @see TokenStore.prototype.get
|
|
* @memberOf TokenStore
|
|
*/
|
|
lunr.TokenStore.prototype.getNode = function (token) {
|
|
if (!token) return {}
|
|
|
|
var node = this.root
|
|
|
|
for (var i = 0; i < token.length; i++) {
|
|
if (!node[token.charAt(i)]) return {}
|
|
|
|
node = node[token.charAt(i)]
|
|
}
|
|
|
|
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
|
|
* it can start at any node of any token store if required.
|
|
*
|
|
* @param {String} token The token to get the documents for.
|
|
* @param {Object} root An optional node at which to start.
|
|
* @returns {Object}
|
|
* @memberOf TokenStore
|
|
*/
|
|
lunr.TokenStore.prototype.get = function (token, root) {
|
|
return this.getNode(token, root).docs || {}
|
|
}
|
|
|
|
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
|
|
* it can start at any node of any token store if required.
|
|
*
|
|
* @param {String} token The token to get the documents for.
|
|
* @param {String} ref The ref of the document to remove from this token.
|
|
* @param {Object} root An optional node at which to start.
|
|
* @returns {Object}
|
|
* @memberOf TokenStore
|
|
*/
|
|
lunr.TokenStore.prototype.remove = function (token, ref) {
|
|
if (!token) return
|
|
var node = this.root
|
|
|
|
for (var i = 0; i < token.length; i++) {
|
|
if (!(token.charAt(i) in node)) return
|
|
node = node[token.charAt(i)]
|
|
}
|
|
|
|
delete node.docs[ref]
|
|
}
|
|
|
|
/**
|
|
* Find all the possible suffixes of the passed token using tokens
|
|
* currently in the store.
|
|
*
|
|
* @param {String} token The token to expand.
|
|
* @returns {Array}
|
|
* @memberOf TokenStore
|
|
*/
|
|
lunr.TokenStore.prototype.expand = function (token, memo) {
|
|
var root = this.getNode(token),
|
|
docs = root.docs || {},
|
|
memo = memo || []
|
|
|
|
if (Object.keys(docs).length) memo.push(token)
|
|
|
|
Object.keys(root)
|
|
.forEach(function (key) {
|
|
if (key === 'docs') return
|
|
|
|
memo.concat(this.expand(token + key, memo))
|
|
}, this)
|
|
|
|
return memo
|
|
}
|
|
|
|
/**
|
|
* Returns a representation of the token store ready for serialisation.
|
|
*
|
|
* @returns {Object}
|
|
* @memberOf TokenStore
|
|
*/
|
|
lunr.TokenStore.prototype.toJSON = function () {
|
|
return {
|
|
root: this.root,
|
|
length: this.length
|
|
}
|
|
}
|