double quotes inclusion
This commit is contained in:
+34
-14
@@ -49,6 +49,26 @@ function normalizeQuotes(s: string): string {
|
||||
.replace(/[‘’‚‛′]/g, "'");
|
||||
}
|
||||
|
||||
// Strip IAST / Vedic diacritics for matching. Decomposes via NFD then drops
|
||||
// codepoints in the Combining Diacritical Marks block. Necessary because
|
||||
// Typesense returns snippets from the `_ascii` shadow field (e.g. "Krsna")
|
||||
// while the rendered DOM uses the original IAST form ("Kṛṣṇa") — without
|
||||
// this normalization, a search-result link to KB 1.34 with prefix "Krsna is
|
||||
// so beautiful" never matches the "Kṛṣṇa is so beautiful" in the DOM.
|
||||
//
|
||||
// Length-preserving for NFC input (one NFC char → one ASCII char): NFD
|
||||
// expands an accented char into base + combining mark, the regex deletes
|
||||
// only the combining mark, and the base is left. So position maps built
|
||||
// from the original collapsed string remain valid after this transform.
|
||||
function stripDiacritics(s: string): string {
|
||||
return s.normalize("NFD").replace(/[̀-ͯ]/g, "");
|
||||
}
|
||||
|
||||
// Combined normalization used on both sides of every match.
|
||||
function normalizeForMatch(s: string): string {
|
||||
return stripDiacritics(normalizeQuotes(s.toLowerCase()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a text fragment from URL params.
|
||||
* Supports `§` (current), `|` (v2 legacy), and `,` (v1 legacy) delimiters.
|
||||
@@ -103,10 +123,10 @@ export function extractMatchedText(
|
||||
// Build a single string with paragraph breaks
|
||||
const fullText = plainParagraphs.join(" ");
|
||||
const normalized = fullText.replace(/\s+/g, " ");
|
||||
const normalizedLower = normalizeQuotes(normalized.toLowerCase());
|
||||
const normalizedLower = normalizeForMatch(normalized);
|
||||
|
||||
const normalizedPrefix = normalizeQuotes(
|
||||
fragment.prefix.replace(/\s+/g, " ").toLowerCase(),
|
||||
const normalizedPrefix = normalizeForMatch(
|
||||
fragment.prefix.replace(/\s+/g, " "),
|
||||
);
|
||||
let searchFrom = 0;
|
||||
let matchStart = -1;
|
||||
@@ -116,8 +136,8 @@ export function extractMatchedText(
|
||||
if (idx === -1) break;
|
||||
|
||||
if (fragment.suffix) {
|
||||
const normalizedSuffix = normalizeQuotes(
|
||||
fragment.suffix.replace(/\s+/g, " ").toLowerCase(),
|
||||
const normalizedSuffix = normalizeForMatch(
|
||||
fragment.suffix.replace(/\s+/g, " "),
|
||||
);
|
||||
const expectedEnd = idx + fragment.length;
|
||||
const suffixSearchStart = Math.max(
|
||||
@@ -397,15 +417,15 @@ export function findAndHighlightText(fragment: {
|
||||
}
|
||||
}
|
||||
|
||||
// Quote-normalize for matching so the prefix/suffix and the DOM text agree
|
||||
// even when one side uses straight ASCII quotes and the other uses curly
|
||||
// typographical quotes. Length-preserving, so collapsedPosMap indices stay
|
||||
// valid against rawText.
|
||||
const normalizedFullLower = normalizeQuotes(collapsedNorm.toLowerCase());
|
||||
// Normalize for matching so prefix/suffix and DOM text agree on quote style
|
||||
// and diacritics (search snippets come from the `_ascii` shadow field, the
|
||||
// DOM renders the original IAST form). Length-preserving for NFC input, so
|
||||
// collapsedPosMap indices remain valid against rawText.
|
||||
const normalizedFullLower = normalizeForMatch(collapsedNorm);
|
||||
|
||||
// Search for the prefix in the full text (case-insensitive)
|
||||
const normalizedPrefix = normalizeQuotes(
|
||||
fragment.prefix.replace(/\s+/g, " ").toLowerCase(),
|
||||
const normalizedPrefix = normalizeForMatch(
|
||||
fragment.prefix.replace(/\s+/g, " "),
|
||||
);
|
||||
let searchFrom = 0;
|
||||
let matchStartNorm = -1;
|
||||
@@ -416,8 +436,8 @@ export function findAndHighlightText(fragment: {
|
||||
|
||||
// If we have a suffix, verify it appears near the expected length
|
||||
if (fragment.suffix) {
|
||||
const normalizedSuffix = normalizeQuotes(
|
||||
fragment.suffix.replace(/\s+/g, " ").toLowerCase(),
|
||||
const normalizedSuffix = normalizeForMatch(
|
||||
fragment.suffix.replace(/\s+/g, " "),
|
||||
);
|
||||
// Search for suffix near the expected end position in the normalized string.
|
||||
// Use a wider tolerance window (±50) since normalization can shift positions.
|
||||
|
||||
Reference in New Issue
Block a user