diff --git a/src/shadow.tsx b/src/shadow.tsx index 02c68e6..a24cf5f 100644 --- a/src/shadow.tsx +++ b/src/shadow.tsx @@ -2,36 +2,32 @@ import React, { ReactNode, useState } from "react"; import { Highlight } from "./highlight"; function buildShadow(highlights: Highlight[], text: string): ReactNode[] { - let remaining_highlights = highlights.slice(); let output: ReactNode[] = []; let i = 0; let state = ShadowState.Text; let buffer = ""; for (let chr of text) { - if (state == ShadowState.Text) { - if ( - remaining_highlights.length > 0 && - i == remaining_highlights[0].start - ) { - // Start a span - output.push(buffer); - buffer = chr; - state = ShadowState.Highlight; - } else { - // Add a character - buffer += chr; - } - } else if (state == ShadowState.Highlight) { - if (remaining_highlights.length > 0 && i == remaining_highlights[0].end) { - // End the span - output.push({buffer}); - buffer = chr; - state = ShadowState.Text; - remaining_highlights = remaining_highlights.slice(1); - } else { - // Add a character - buffer += chr; - } + const thisCharHighlighted = isInHighlight(highlights, i); + if (state == ShadowState.Text && thisCharHighlighted) { + // Start a span + output.push(buffer); + buffer = chr; + state = ShadowState.Highlight; + } else if (state == ShadowState.Text && !thisCharHighlighted) { + // Add a character + buffer += chr; + } else if (state == ShadowState.Highlight && thisCharHighlighted) { + // Add a character + buffer += chr; + } else if (state == ShadowState.Highlight && !thisCharHighlighted) { + // End the span + output.push( + + {buffer} + , + ); + buffer = chr; + state = ShadowState.Text; } ++i; } @@ -40,26 +36,23 @@ function buildShadow(highlights: Highlight[], text: string): ReactNode[] { if (state == ShadowState.Text) { output.push(buffer); } else if (state == ShadowState.Highlight) { - output.push({buffer}); + output.push( + + {buffer} + , + ); } } return output; } -function unicodeAwareSlice(text: string, start: number, end: number): string { - // Boooo javascript - let i = 0; - let output = ""; - for (let chr of text) { - if (i >= end) { - break; +function isInHighlight(highlights: Highlight[], offset: number): boolean { + for (const highlight of highlights) { + if (highlight.start <= offset && offset < highlight.end) { + return true; } - if (i >= start) { - output += chr; - } - ++i; } - return output; + return false; } const enum ShadowState {