export function highlightStemmed()

in src/utils/highlightStemmed.ts [7:64]


export function highlightStemmed(
  content: string,
  positions: MetadataPosition[],
  tokens: string[],
  maxLength = searchResultContextMaxLength
): string {
  const { chunkIndex, chunks } = splitIntoChunks(content, positions, tokens);

  const leadingChunks = chunks.slice(0, chunkIndex);
  const firstChunk = chunks[chunkIndex];
  const html: string[] = [firstChunk.html];
  const trailingChunks = chunks.slice(chunkIndex + 1);

  let currentLength = firstChunk.textLength;
  let leftPadding = 0;
  let rightPadding = 0;
  let leftOverflowed = false;
  let rightOverflowed = false;

  while (currentLength < maxLength) {
    if (
      (leftPadding <= rightPadding || trailingChunks.length === 0) &&
      leadingChunks.length > 0
    ) {
      const chunk = leadingChunks.pop() as HighlightChunk;
      if (currentLength + chunk.textLength <= maxLength) {
        html.unshift(chunk.html);
        leftPadding += chunk.textLength;
        currentLength += chunk.textLength;
      } else {
        leftOverflowed = true;
        leadingChunks.length = 0;
      }
    } else if (trailingChunks.length > 0) {
      const chunk = trailingChunks.shift() as HighlightChunk;
      if (currentLength + chunk.textLength <= maxLength) {
        html.push(chunk.html);
        rightPadding += chunk.textLength;
        currentLength += chunk.textLength;
      } else {
        rightOverflowed = true;
        trailingChunks.length = 0;
      }
    } else {
      break;
    }
  }

  if (leftOverflowed || leadingChunks.length > 0) {
    html.unshift("…");
  }

  if (rightOverflowed || trailingChunks.length > 0) {
    html.push("…");
  }

  return html.join("");
}