domain/converters/reference.converter.ts
domain/converters/reference.converter.ts is a file in Bane's Lab Site. 148 lines of code and 32 definitions.
import { ANATOMY_FACE, CHAPTER_FACE } from "#configuration/constants/vocabulary.constants";
import { ANATOMY_PAGE, ONTOLOGY_PAGE } from "#core/ids/page.ids";
import type { ChapterReference, ReferenceTarget } from "#types/reference.types";
import { DEFINITION_ANCHOR, FILE_ANCHOR, FOLDER_ANCHOR } from "#core/ids/anatomy.ids";
import {
HOME_PATH,
RECORDS_SEGMENT,
nodeFromPath,
pageFromPath,
payloadPath,
tabFromPath,
} from "#core/assets/link.assets";
import { LINK_CLOSE, LINK_OPEN } from "#configuration/constants/markdown.constants";
import { ANCHOR_PREFIX } from "#configuration/constants/document.constants";
import { FACE_SEPARATOR } from "@govlab/constants";
import { refOfAnchor } from "#domain/converters/ontology.converter";
const LABEL_CLOSE = "]";
const TARGET_OPEN = "(";
const MARKS: ReadonlySet<string> = new Set(["*", "`"]);
const LESSON_KIND = "lesson";
const fragmentOf = function fragmentOf(href: string): string | null {
const cut = href.indexOf(ANCHOR_PREFIX);
return cut === -1 ? null : href.slice(cut + ANCHOR_PREFIX.length);
};
const isNodeFragment = function isNodeFragment(fragment: string): boolean {
return (
fragment.startsWith(FILE_ANCHOR) || fragment.startsWith(FOLDER_ANCHOR) || fragment.startsWith(DEFINITION_ANCHOR)
);
};
const ontologyTarget = function ontologyTarget(fragment: string): ReferenceTarget | null {
const ref = refOfAnchor(fragment);
return ref === null ? null : { face: ref.slice(0, ref.indexOf(FACE_SEPARATOR)), ref };
};
const recordTarget = function recordTarget(href: string): ReferenceTarget | null {
const face = tabFromPath(href);
const id = nodeFromPath(href);
return face === null || id === null ? null : { face, ref: face + FACE_SEPARATOR + id };
};
export const targetOfHref = function targetOfHref(href: string): ReferenceTarget | null {
if (!href.startsWith(HOME_PATH)) {
return null;
}
if (pageFromPath(href, "") === RECORDS_SEGMENT) {
return recordTarget(href);
}
const fragment = fragmentOf(href);
if (fragment === null || fragment.length === 0) {
return null;
}
if (pageFromPath(href, "") === ONTOLOGY_PAGE) {
return ontologyTarget(fragment);
}
if (pageFromPath(href, "") === ANATOMY_PAGE && isNodeFragment(fragment)) {
return { face: ANATOMY_FACE, ref: ANATOMY_FACE + FACE_SEPARATOR + fragment };
}
return { face: CHAPTER_FACE, ref: CHAPTER_FACE + FACE_SEPARATOR + href };
};
export const payloadOfHref = function payloadOfHref(href: string): string {
return payloadPath(pageFromPath(href, ""), tabFromPath(href));
};
interface Bracketed {
readonly label: string;
readonly next: number;
}
const bracketedAt = function bracketedAt(text: string, at: number): Bracketed | null {
const close = text.indexOf(LABEL_CLOSE, at);
if (close === -1) {
return null;
}
const label = text.slice(at + LINK_OPEN.length, close);
if (text.charAt(close + LABEL_CLOSE.length) !== TARGET_OPEN) {
return { label, next: close + LABEL_CLOSE.length };
}
const end = text.indexOf(LINK_CLOSE, close);
return { label, next: end === -1 ? close + LABEL_CLOSE.length : end + LINK_CLOSE.length };
};
export const plainMarkdown = function plainMarkdown(text: string): string {
let out = "";
let at = 0;
while (at < text.length) {
const char = text.charAt(at);
const bracketed = char === LINK_OPEN ? bracketedAt(text, at) : null;
if (bracketed !== null) {
out += bracketed.label;
at = bracketed.next;
continue;
}
if (!MARKS.has(char)) {
out += char;
}
at += 1;
}
return out;
};
interface SectionLike {
readonly id: string;
readonly intro?: string;
readonly subsections?: readonly {
readonly blocks?: readonly { readonly kind: string; readonly principle?: string }[];
}[];
readonly title: string;
}
const isRecord = function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null;
};
const isSection = function isSection(value: unknown): value is SectionLike {
return isRecord(value) && typeof value["id"] === "string" && typeof value["title"] === "string";
};
const sectionsOf = function sectionsOf(node: unknown): readonly SectionLike[] {
if (Array.isArray(node)) {
return node.flatMap(sectionsOf);
}
if (typeof node !== "object" || node === null) {
return [];
}
if ("sections" in node && Array.isArray(node.sections)) {
return node.sections.filter(isSection);
}
if ("tabs" in node) {
return sectionsOf(node.tabs);
}
if ("content" in node) {
return sectionsOf(node.content);
}
return [];
};
const principleOf = function principleOf(section: SectionLike): string | null {
for (const subsection of section.subsections ?? []) {
for (const block of subsection.blocks ?? []) {
if (block.kind === LESSON_KIND && typeof block.principle === "string") {
return plainMarkdown(block.principle);
}
}
}
return null;
};
export const chapterOf = function chapterOf(payload: unknown, sectionId: string): ChapterReference | null {
const section = sectionsOf(payload).find((candidate) => candidate.id === sectionId);
if (section === undefined) {
return null;
}
return {
intro: section.intro === undefined ? null : plainMarkdown(section.intro),
principle: principleOf(section),
relations: [],
title: section.title,
};
};