| import { escapeHtml } from "./escapeHtml"; |
| |
| /** |
| * Highlight specified tokens in text content. |
| * |
| * @param content - Text content. |
| * @param tokens - Tokens to be highlighted (in lower-case and sorted by descending of length). |
| * @param forceMatched - Whether to force matched. |
| * |
| * @returns A html string with marked tokens. |
| */ |
| export function highlight( |
| content: string, |
| tokens: string[], |
| forceMatched?: boolean |
| ): string { |
| const html: string[] = []; |
| |
| for (const token of tokens) { |
| const index = content.toLowerCase().indexOf(token); |
| if (index >= 0) { |
| if (index > 0) { |
| html.push(highlight(content.substr(0, index), tokens)); |
| } |
| html.push( |
| `<mark>${escapeHtml(content.substr(index, token.length))}</mark>` |
| ); |
| const end = index + token.length; |
| if (end < content.length) { |
| html.push(highlight(content.substr(end), tokens)); |
| } |
| break; |
| } |
| } |
| |
| if (html.length === 0) { |
| return forceMatched |
| ? `<mark>${escapeHtml(content)}</mark>` |
| : escapeHtml(content); |
| } |
| |
| return html.join(""); |
| } |