import { FENCE_MARK, FOLDER_SEPARATOR, LINK_CLOSE, LINK_MIDDLE } from "#configuration/constants/chapter.constants"; import { ANCHOR_MARK } from "#configuration/constants/readme.constants"; import { LINE_END } from "#configuration/constants/inventory.constants"; import type { LinkResolver } from "#types/chapter.types"; import { SITE_URL } from "@banes-lab/web/core/assets/link.assets.ts"; const ROOT_LINK = LINK_MIDDLE + FOLDER_SEPARATOR; const targetOf = function targetOf(target: string, resolve: LinkResolver): string { const hash = target.indexOf(ANCHOR_MARK); const path = hash === -1 ? target : target.slice(0, hash); const fragment = hash === -1 ? "" : target.slice(hash); const [page = "", tab = null] = path.split(FOLDER_SEPARATOR).filter((segment) => segment.length > 0); const file = resolve(page, tab); return file === null ? SITE_URL + target : file + fragment; }; const relinkLine = function relinkLine(line: string, resolve: LinkResolver): string { let out = ""; let index = 0; while (index < line.length) { const open = line.indexOf(ROOT_LINK, index); const close = open === -1 ? -1 : line.indexOf(LINK_CLOSE, open); if (close === -1) { return out + line.slice(index); } const start = open + LINK_MIDDLE.length; out += line.slice(index, start) + targetOf(line.slice(start, close), resolve); index = close; } return out; }; export const relinked = function relinked(markdown: string, resolve: LinkResolver): string { let fenced = false; return markdown .split(LINE_END) .map((line) => { if (line.startsWith(FENCE_MARK)) { fenced = !fenced; return line; } return fenced ? line : relinkLine(line, resolve); }) .join(LINE_END); };