@@ -75,6 +75,10 @@ export class Query {
|
|||||||
return this.getTags().map(o => o.replace(/^#/, ''))
|
return this.getTags().map(o => o.replace(/^#/, ''))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns An array of strings that are in quotes
|
||||||
|
*/
|
||||||
public getExactTerms(): string[] {
|
public getExactTerms(): string[] {
|
||||||
return [
|
return [
|
||||||
...new Set(
|
...new Set(
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ import {
|
|||||||
excerptBefore,
|
excerptBefore,
|
||||||
} from 'src/globals'
|
} from 'src/globals'
|
||||||
import { settings } from 'src/settings'
|
import { settings } from 'src/settings'
|
||||||
import { escapeRegex, warnDebug } from './utils'
|
import { warnDebug } from './utils'
|
||||||
import type { Query } from 'src/search/query'
|
import type { Query } from 'src/search/query'
|
||||||
import { Notice } from 'obsidian'
|
import { Notice } from 'obsidian'
|
||||||
|
import { escapeRegExp } from 'lodash-es'
|
||||||
|
|
||||||
export function highlighterGroups(_substring: string, ...args: any[]) {
|
export function highlighterGroups(_substring: string, ...args: any[]) {
|
||||||
// args[0] is the single char preceding args[1], which is the word we want to highlight
|
// args[0] is the single char preceding args[1], which is the word we want to highlight
|
||||||
@@ -21,39 +22,35 @@ export function highlighterGroups(_substring: string, ...args: any[]) {
|
|||||||
return '<no content>'
|
return '<no content>'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps the matches in the text with a <span> element and a highlight class
|
||||||
|
* @param text
|
||||||
|
* @param matches
|
||||||
|
* @returns The html string with the matches highlighted
|
||||||
|
*/
|
||||||
export function highlightText(text: string, matches: SearchMatch[]): string {
|
export function highlightText(text: string, matches: SearchMatch[]): string {
|
||||||
matches.forEach(matchInfo => {
|
try {
|
||||||
const matchRegex = new RegExp(`\\b${matchInfo.match}\\b`, 'giu')
|
return text.replace(
|
||||||
const matchOffsets = []
|
new RegExp(
|
||||||
|
matches
|
||||||
let match
|
.map(matchInfo => `\\b${escapeRegExp(matchInfo.match)}\\b`)
|
||||||
while ((match = matchRegex.exec(text)) !== null) {
|
.join('|'),
|
||||||
matchOffsets.push({ index: match.index, text: match[0] })
|
'giu'
|
||||||
|
),
|
||||||
|
match => {
|
||||||
|
const matchInfo = matches.find(info =>
|
||||||
|
match.match(new RegExp(`\\b${escapeRegExp(info.match)}\\b`, 'giu'))
|
||||||
|
)
|
||||||
|
if (matchInfo) {
|
||||||
|
return `<span class="${highlightClass}">${match}</span>`
|
||||||
}
|
}
|
||||||
|
return match
|
||||||
if (!matchOffsets.length) {
|
}
|
||||||
|
)
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Omnisearch - Error in highlightText()', e)
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
const closestMatch = matchOffsets.reduce((prev, curr) => {
|
|
||||||
return Math.abs(curr.index - matchInfo.offset) <
|
|
||||||
Math.abs(prev.index - matchInfo.offset)
|
|
||||||
? curr
|
|
||||||
: prev
|
|
||||||
})
|
|
||||||
|
|
||||||
if (matchOffsets.includes(closestMatch)) {
|
|
||||||
const originalMatch = closestMatch.text
|
|
||||||
text =
|
|
||||||
text.substring(0, closestMatch.index) +
|
|
||||||
`<span class="${highlightClass}">` +
|
|
||||||
originalMatch +
|
|
||||||
'</span>' +
|
|
||||||
text.substring(closestMatch.index + originalMatch.length)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return text
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function escapeHTML(html: string): string {
|
export function escapeHTML(html: string): string {
|
||||||
@@ -94,10 +91,9 @@ export function stringsToRegex(strings: string[]): RegExp {
|
|||||||
? `^|${SPACE_OR_PUNCTUATION_UNIQUE.source}|\-|[A-Z]`
|
? `^|${SPACE_OR_PUNCTUATION_UNIQUE.source}|\-|[A-Z]`
|
||||||
: `^|${SPACE_OR_PUNCTUATION_UNIQUE.source}|\-`) +
|
: `^|${SPACE_OR_PUNCTUATION_UNIQUE.source}|\-`) +
|
||||||
')' +
|
')' +
|
||||||
`(${strings.map(s => escapeRegex(s)).join('|')})`
|
`(${strings.map(s => escapeRegExp(s)).join('|')})`
|
||||||
|
|
||||||
const reg = new RegExp(`${joined}`, 'gu')
|
return new RegExp(`${joined}`, 'gu')
|
||||||
return reg
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getMatches(
|
export function getMatches(
|
||||||
@@ -122,8 +118,8 @@ export function getMatches(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the query can be found "as is" in the text, put this match first
|
// If the query is more than 1 token and can be found "as is" in the text, put this match first
|
||||||
if (query) {
|
if (query && query.query.text.length > 1) {
|
||||||
const best = text.indexOf(query.segmentsToStr())
|
const best = text.indexOf(query.segmentsToStr())
|
||||||
if (best > -1 && matches.find(m => m.offset === best)) {
|
if (best > -1 && matches.find(m => m.offset === best)) {
|
||||||
matches = matches.filter(m => m.offset !== best)
|
matches = matches.filter(m => m.offset !== best)
|
||||||
|
|||||||
@@ -25,12 +25,6 @@ export function wait(ms: number): Promise<void> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/a/3561711
|
|
||||||
// but we enclose special chars in brackets to avoid them being interpreted as regex
|
|
||||||
export function escapeRegex(str: string): string {
|
|
||||||
return str.replace(/[-/\\^$*+?.()|[\]{}]/g, '[$&]')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the positions of all occurences of `val` inside of `text`
|
* Returns the positions of all occurences of `val` inside of `text`
|
||||||
* https://stackoverflow.com/a/58828841
|
* https://stackoverflow.com/a/58828841
|
||||||
|
|||||||
Reference in New Issue
Block a user