core/normalizers/link.normalizer.ts
core/normalizers/link.normalizer.ts is a file in Bane's Lab Content. 42 lines of code and 15 definitions.
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);
};