organic_ast_explorer/src/shadow.tsx

70 lines
1.6 KiB
TypeScript
Raw Normal View History

2024-01-23 02:59:59 +00:00
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(<span className="highlighted">{buffer}</span>);
buffer = chr;
state = ShadowState.Text;
remaining_highlights = remaining_highlights.slice(1);
} else {
// Add a character
buffer += chr;
}
}
++i;
}
if (buffer.length > 0) {
if (state == ShadowState.Text) {
output.push(buffer);
} else if (state == ShadowState.Highlight) {
output.push(<span className="highlighted">{buffer}</span>);
}
}
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;
}
if (i >= start) {
output += chr;
}
++i;
}
return output;
}
const enum ShadowState {
Text,
Highlight,
}
export {
buildShadow
}