diff --git a/frontend/src/pages/ontologies/entities/entityPageSections/addLinksToText.tsx b/frontend/src/pages/ontologies/entities/entityPageSections/addLinksToText.tsx
index af88583dc..5349879df 100644
--- a/frontend/src/pages/ontologies/entities/entityPageSections/addLinksToText.tsx
+++ b/frontend/src/pages/ontologies/entities/entityPageSections/addLinksToText.tsx
@@ -4,7 +4,6 @@ import { randomString } from "../../../../app/util";
import EntityLink from "../../../../components/EntityLink";
import Entity from "../../../../model/Entity";
import LinkedEntities from "../../../../model/LinkedEntities";
-import Image3D from "../../../../components/Image3D";
export default function addLinksToText(
text: string,
@@ -13,15 +12,53 @@ export default function addLinksToText(
currentEntity: Entity | undefined,
entityType: "ontologies" | "classes" | "properties" | "individuals"
) {
- let linksToSplice: Array<{ start: number; end: number; link: JSX.Element }> =
- [];
+ let linksToSplice: Array<{ start: number; end: number; link: JSX.Element }> = [];
+ let urlMatches: Array<{ start: number; end: number }> = []; // To store the ranges of URLs
+
+ // First, find all URLs and record their ranges
+ const urlRe = /[A-z]+:\/\/[^\s]+/g;
+ for (let match = urlRe.exec(text); match; match = urlRe.exec(text)) {
+ const url = match[0];
+ linksToSplice.push({
+ start: match.index,
+ end: match.index + url.length,
+ link: (
+
+
+ {url}
+
+
+ ),
+ });
+ urlMatches.push({ start: match.index, end: match.index + url.length });
+ }
+
+ // Then, process entity IDs
for (let entityId of Object.keys(linkedEntities.linkedEntities)) {
for (
let n = text.indexOf(entityId, 0);
n !== -1;
n = text.indexOf(entityId, n)
) {
+ // We need to handle this case when entity ID is part of a URL and it then gets linked to an entity but
+ // resulting url is broken. So, we need to keep the URL as is if the entity ID is part of a URL.
+ // Check if the entity ID is within any URL range
+ let isWithinURL = urlMatches.some(
+ (urlRange) =>
+ n >= urlRange.start && n + entityId.length <= urlRange.end
+ );
+ if (isWithinURL) {
+ // Skip this entity ID because it's part of a URL
+ n += entityId.length;
+ continue;
+ }
+
linksToSplice.push({
start: n,
end: n + entityId.length,
@@ -41,65 +78,45 @@ export default function addLinksToText(
}
}
- const urlRe = /[A-z]+:\/\/[^\s]+/g;
- for (let match = urlRe.exec(text); match; match = urlRe.exec(text)) {
- const url = match[0];
- // console.log("found match " + url);
- linksToSplice.push({
- start: match.index,
- end: match.index + url.length,
- link: (
-
-
- {url}
-
-
- ),
- });
- }
-
- removeOverlapping: for (let n = 0; n < linksToSplice.length; ) {
- for (let n2 = 0; n2 < linksToSplice.length; ++n2) {
- let spliceA = linksToSplice[n];
- let spliceB = linksToSplice[n2];
+ // Remove overlapping links by sorting and keeping the first one
+ linksToSplice.sort((a, b) => a.start - b.start);
- if (spliceA === spliceB) continue;
-
- // The splices overlap if neither ends before the other starts
- if (spliceA.end >= spliceB.start && spliceB.end >= spliceA.start) {
- // console.log("Removing overlapping");
- linksToSplice.splice(n2, 1);
- continue removeOverlapping;
- }
+ // Remove overlaps
+ for (let i = 0; i < linksToSplice.length - 1; i++) {
+ const current = linksToSplice[i];
+ const next = linksToSplice[i + 1];
+ if (current.end > next.start) {
+ // Overlap detected, remove the next link
+ linksToSplice.splice(i + 1, 1);
+ i--; // Adjust index after removal
}
- ++n;
}
if (linksToSplice.length === 0) return text;
- // linksToSplice.sort((a, b) => a.start - b.start);
- // console.dir(linksToSplice);
+ // Build the final result
let res: JSX.Element[] = [];
- let n = 0;
+ let lastIndex = 0;
for (let link of linksToSplice) {
+ if (lastIndex < link.start) {
+ res.push(
+
+ {text.substring(lastIndex, link.start)}
+
+ );
+ }
+ res.push(link.link);
+ lastIndex = link.end;
+ }
+
+ if (lastIndex < text.length) {
res.push(
-
- {text.substring(n, link.start)}
-
+
+ {text.substring(lastIndex)}
+
);
- res.push(link.link);
- n = link.end;
}
- res.push(
- {text.slice(n)}
- );
return res;
}