|
|
@ -52,40 +52,21 @@ const removeMarkdown = (
|
|
|
|
return markdown
|
|
|
|
return markdown
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return output
|
|
|
|
return output
|
|
|
|
};
|
|
|
|
}
|
|
|
|
// -----
|
|
|
|
// -----
|
|
|
|
|
|
|
|
|
|
|
|
(async function() {
|
|
|
|
const highlight = (content, term) => {
|
|
|
|
const encoder = (str) => str.toLowerCase().split(/([^a-z]|[^\x00-\x7F])+/)
|
|
|
|
const highlightWindow = 20
|
|
|
|
const contentIndex = new FlexSearch.Document({
|
|
|
|
|
|
|
|
cache: true,
|
|
|
|
|
|
|
|
charset: 'latin:extra',
|
|
|
|
|
|
|
|
optimize: true,
|
|
|
|
|
|
|
|
index: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
field: 'content',
|
|
|
|
|
|
|
|
tokenize: 'reverse',
|
|
|
|
|
|
|
|
encode: encoder,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
field: 'title',
|
|
|
|
|
|
|
|
tokenize: 'forward',
|
|
|
|
|
|
|
|
encode: encoder,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { content } = await fetchData
|
|
|
|
// try to find direct match first
|
|
|
|
for (const [key, value] of Object.entries(content)) {
|
|
|
|
const directMatchIdx = content.indexOf(term)
|
|
|
|
contentIndex.add({
|
|
|
|
if (directMatchIdx !== -1) {
|
|
|
|
id: key,
|
|
|
|
const h = highlightWindow / 2
|
|
|
|
title: value.title,
|
|
|
|
const before = content.substring(0, directMatchIdx).split(" ").slice(-h)
|
|
|
|
content: removeMarkdown(value.content),
|
|
|
|
const after = content.substring(directMatchIdx + term.length, content.length - 1).split(" ").slice(0, h)
|
|
|
|
})
|
|
|
|
return (before.length == h ? `...${before.join(" ")}` : before.join(" ")) + `<span class="search-highlight">${term}</span>` + after.join(" ")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const highlight = (content, term) => {
|
|
|
|
|
|
|
|
const highlightWindow = 20
|
|
|
|
|
|
|
|
const tokenizedTerm = term.split(/\s+/).filter((t) => t !== '')
|
|
|
|
const tokenizedTerm = term.split(/\s+/).filter((t) => t !== '')
|
|
|
|
const splitText = content.split(/\s+/).filter((t) => t !== '')
|
|
|
|
const splitText = content.split(/\s+/).filter((t) => t !== '')
|
|
|
|
const includesCheck = (token) =>
|
|
|
|
const includesCheck = (token) =>
|
|
|
@ -128,6 +109,35 @@ const removeMarkdown = (
|
|
|
|
.replaceAll('</span> <span class="search-highlight">', ' ')
|
|
|
|
.replaceAll('</span> <span class="search-highlight">', ' ')
|
|
|
|
return `${startIndex === 0 ? '' : '...'}${mappedText}${endIndex === splitText.length ? '' : '...'
|
|
|
|
return `${startIndex === 0 ? '' : '...'}${mappedText}${endIndex === splitText.length ? '' : '...'
|
|
|
|
}`
|
|
|
|
}`
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(async function() {
|
|
|
|
|
|
|
|
const encoder = (str) => str.toLowerCase().split(/([^a-z]|[^\x00-\x7F])+/)
|
|
|
|
|
|
|
|
const contentIndex = new FlexSearch.Document({
|
|
|
|
|
|
|
|
cache: true,
|
|
|
|
|
|
|
|
charset: 'latin:extra',
|
|
|
|
|
|
|
|
optimize: true,
|
|
|
|
|
|
|
|
index: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
field: 'content',
|
|
|
|
|
|
|
|
tokenize: 'reverse',
|
|
|
|
|
|
|
|
encode: encoder,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
field: 'title',
|
|
|
|
|
|
|
|
tokenize: 'forward',
|
|
|
|
|
|
|
|
encode: encoder,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { content } = await fetchData
|
|
|
|
|
|
|
|
for (const [key, value] of Object.entries(content)) {
|
|
|
|
|
|
|
|
contentIndex.add({
|
|
|
|
|
|
|
|
id: key,
|
|
|
|
|
|
|
|
title: value.title,
|
|
|
|
|
|
|
|
content: removeMarkdown(value.content),
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const resultToHTML = ({ url, title, content, term }) => {
|
|
|
|
const resultToHTML = ({ url, title, content, term }) => {
|
|
|
|