Fix highlighting for hyphenated values. Improve highlighting text matching logic. Handle text split across items.
parent
82f02c0772
commit
ed34687dc4
|
|
@ -184,10 +184,10 @@ export default function KennzahlenTable({
|
|||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell width="25%">
|
||||
<TableCell width="30%">
|
||||
<strong>Kennzahl</strong>
|
||||
</TableCell>
|
||||
<TableCell width="60%">
|
||||
<TableCell width="55%">
|
||||
<strong>Wert</strong>
|
||||
</TableCell>
|
||||
<TableCell align="center" width="15%">
|
||||
|
|
|
|||
|
|
@ -95,53 +95,78 @@ export default function PDFViewer({
|
|||
useEffect(() => {
|
||||
const tmpPos: string[] = [];
|
||||
const tmpPosHighlight: string[] = [];
|
||||
const textItems = textContent.filter(
|
||||
(e) => e.text !== "" && e.text !== " ",
|
||||
);
|
||||
|
||||
textItems.forEach((e, i) => {
|
||||
for (const s of highlight
|
||||
.filter((h) => h.page === pageNumber)
|
||||
.map((h) => h.text)) {
|
||||
if (s.split(" ")[0] === e.text) {
|
||||
if (
|
||||
s.split(" ").reduce((prev, curr, j) => {
|
||||
return prev && curr === textItems[i + j].text;
|
||||
}, true)
|
||||
) {
|
||||
for (
|
||||
let k = textItems[i].i;
|
||||
k < textItems[i + s.split(" ").length]?.i ||
|
||||
k < textItems[i + s.split(" ").length - 1]?.i;
|
||||
k++
|
||||
if (textContent.length === 0) {
|
||||
setPosHighlight([]);
|
||||
setPosHighlightFocus([]);
|
||||
return;
|
||||
}
|
||||
const findTextPositions = (searchText: string): number[] => {
|
||||
const positions: number[] = [];
|
||||
const normalizedSearch = searchText.toLowerCase().trim();
|
||||
|
||||
textContent.forEach((item, index) => {
|
||||
if (item.text.toLowerCase().trim() === normalizedSearch) {
|
||||
positions.push(index);
|
||||
}
|
||||
});
|
||||
|
||||
if (positions.length === 0) {
|
||||
let cumulativeText = '';
|
||||
const textBoundaries: { start: number; end: number; index: number }[] = [];
|
||||
|
||||
textContent.forEach((item, index) => {
|
||||
const start = cumulativeText.length;
|
||||
cumulativeText += item.text;
|
||||
const end = cumulativeText.length;
|
||||
textBoundaries.push({ start, end, index });
|
||||
});
|
||||
|
||||
const lowerCumulative = cumulativeText.toLowerCase();
|
||||
let searchIndex = lowerCumulative.indexOf(normalizedSearch);
|
||||
|
||||
while (searchIndex !== -1) {
|
||||
const endIndex = searchIndex + normalizedSearch.length;
|
||||
|
||||
textBoundaries.forEach(boundary => {
|
||||
if (
|
||||
(boundary.start <= searchIndex && searchIndex < boundary.end) || // Search starts in this item
|
||||
(boundary.start < endIndex && endIndex <= boundary.end) || // Search ends in this item
|
||||
(searchIndex <= boundary.start && boundary.end <= endIndex) // This item is completely within search
|
||||
) {
|
||||
tmpPos.push(textContent[k].posKey);
|
||||
if (!positions.includes(boundary.index)) {
|
||||
positions.push(boundary.index);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
searchIndex = lowerCumulative.indexOf(normalizedSearch, searchIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (focusHighlight?.page === pageNumber) {
|
||||
if (focusHighlight.text.split(" ")[0] === e.text) {
|
||||
if (
|
||||
focusHighlight.text.split(" ").reduce((prev, curr, j) => {
|
||||
return prev && curr === textItems[i + j].text;
|
||||
}, true)
|
||||
) {
|
||||
for (
|
||||
let k = textItems[i].i;
|
||||
k < textItems[i + focusHighlight.text.split(" ").length]?.i ||
|
||||
k < textItems[i + focusHighlight.text.split(" ").length - 1]?.i;
|
||||
k++
|
||||
) {
|
||||
tmpPosHighlight.push(textContent[k].posKey);
|
||||
}
|
||||
return positions.sort((a, b) => a - b);
|
||||
};
|
||||
highlight
|
||||
.filter(h => h.page === pageNumber)
|
||||
.forEach(highlightItem => {
|
||||
const positions = findTextPositions(highlightItem.text);
|
||||
positions.forEach(pos => {
|
||||
if (pos >= 0 && pos < textContent.length) {
|
||||
tmpPos.push(textContent[pos].posKey);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (focusHighlight?.page === pageNumber && focusHighlight.text) {
|
||||
const positions = findTextPositions(focusHighlight.text);
|
||||
|
||||
positions.forEach(pos => {
|
||||
if (pos >= 0 && pos < textContent.length) {
|
||||
tmpPosHighlight.push(textContent[pos].posKey);
|
||||
}
|
||||
}
|
||||
});
|
||||
setPosHighlight(tmpPos);
|
||||
setPosHighlightFocus(tmpPosHighlight);
|
||||
});
|
||||
}
|
||||
|
||||
setPosHighlight([...new Set(tmpPos)]);
|
||||
setPosHighlightFocus([...new Set(tmpPosHighlight)]);
|
||||
}, [highlight, focusHighlight, pageNumber, textContent]);
|
||||
|
||||
const onGetTextSuccess: OnGetTextSuccess = useCallback((fullText) => {
|
||||
|
|
|
|||
|
|
@ -183,6 +183,7 @@ function ExtractedResultsPage() {
|
|||
setCustomValue(value);
|
||||
setSelectedIndex(-1);
|
||||
setFocusHighlightOverride(null);
|
||||
}
|
||||
|
||||
const handleCustomPageChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>,
|
||||
|
|
|
|||
Loading…
Reference in New Issue