| | |
| | | return markdown |
| | | } |
| | | return output |
| | | }; |
| | | // ----- |
| | | |
| | | (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 highlight = (content, term) => { |
| | | const highlightWindow = 20 |
| | | |
| | | // try to find direct match first |
| | | const directMatchIdx = content.indexOf(term) |
| | | if (directMatchIdx !== -1) { |
| | | const h = highlightWindow / 2 |
| | | const before = content.substring(0, directMatchIdx).split(" ").slice(-h) |
| | | 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 tokenizedTerm = term.split(/\s+/).filter((t) => t !== '') |
| | | const splitText = content.split(/\s+/).filter((t) => t !== '') |
| | | const includesCheck = (token) => |
| | |
| | | .replaceAll('</span> <span class="search-highlight">', ' ') |
| | | 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 }) => { |