# domain/converters/reference.converter.ts

> 121 lines of code and 27 definitions.

Tree: Site tree
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/tree#file-domain-converters-reference-converter-ts
Source text: https://banes-lab.com/assets/sources/source.c3db46a9945fc121ffe5035d25f8a30723103e155d3aa28d8692c9317f9c05fb.generated.txt

## Definitions

- `plainMarkdown` (lexical_declaration, line 58, exported)
- `principleOf` (lexical_declaration, line 113)
- `isNodeFragment` (lexical_declaration, line 21)
- `ontologyTarget` (lexical_declaration, line 27)
- `isRecord` (lexical_declaration, line 86)
- `targetOfHref` (lexical_declaration, line 32, exported)
- `payloadOfHref` (lexical_declaration, line 49, exported)
- `chapterOf` (lexical_declaration, line 124, exported)
- `isSection` (lexical_declaration, line 90)
- `LINK_OPEN` (lexical_declaration, line 10)
- `LINK_MIDDLE` (lexical_declaration, line 11)
- `LINK_CLOSE` (lexical_declaration, line 12)
- `MARKS` (lexical_declaration, line 13)
- `LESSON_KIND` (lexical_declaration, line 14)
- `fragmentOf` (lexical_declaration, line 16)
- `cut` (lexical_declaration, line 17)
- `ref` (lexical_declaration, line 28)
- `fragment` (lexical_declaration, line 36, exported)
- `linkEnd` (lexical_declaration, line 53)
- `middle` (lexical_declaration, line 54)
- `out` (lexical_declaration, line 59, exported)
- `at` (lexical_declaration, line 60, exported)
- `char` (lexical_declaration, line 62, exported)
- `close` (lexical_declaration, line 63, exported)
- `SectionLike` (interface_declaration, line 77)
- `sectionsOf` (lexical_declaration, line 94)
- `section` (lexical_declaration, line 125, exported)

## Uses

- [core/assets/link.assets.ts](https://banes-lab.com/source/tree/core/assets/link.assets.ts.md)

## Source

```typescript
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, pageFromPath, payloadPath, tabFromPath } from "#assets/link.assets";
import { ANCHOR_PREFIX } from "#configuration/constants/document.constants";
import { FACE_SEPARATOR } from "@govlab/constants";
import { refOfAnchor } from "#domain/converters/ontology.converter";

const LINK_OPEN = "[";
const LINK_MIDDLE = "](";
const LINK_CLOSE = ")";
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 };
};

export const targetOfHref = function targetOfHref(href: string): ReferenceTarget | null {
    if (!href.startsWith(HOME_PATH)) {
        return null;
    }
    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));
};

const linkEnd = function linkEnd(text: string, at: number): number {
    const middle = text.indexOf(LINK_MIDDLE, at);
    return middle === -1 ? -1 : text.indexOf(LINK_CLOSE, middle);
};

export const plainMarkdown = function plainMarkdown(text: string): string {
    let out = "";
    let at = 0;
    while (at < text.length) {
        const char = text.charAt(at);
        const close = char === LINK_OPEN ? linkEnd(text, at) : -1;
        if (close !== -1) {
            out += text.slice(at + 1, text.indexOf(LINK_MIDDLE, at));
            at = close + 1;
            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,
    };
};
```
