# presentation/renderers/block.renderer.ts

> 172 lines of code and 20 definitions.

Tree: Site tree
Language: typescript
Layer: product
Canonical: https://banes-lab.com/anatomy/tree#file-presentation-renderers-block-renderer-ts
Source text: https://banes-lab.com/assets/sources/source.794fcc5aad9a2f58e1e5ce448b8b1d652bb98a38791bb865fcfc2842e09fa18c.generated.txt

## Definitions

- `renderBlock` (lexical_declaration, line 176, exported)
- `renderList` (lexical_declaration, line 44)
- `renderSimple` (lexical_declaration, line 150)
- `renderComposite` (lexical_declaration, line 106)
- `renderCoded` (lexical_declaration, line 86)
- `renderText` (lexical_declaration, line 39)
- `renderGroups` (lexical_declaration, line 75)
- `isComposite` (lexical_declaration, line 138)
- `isCoded` (lexical_declaration, line 142)
- `isGrammar` (lexical_declaration, line 146)
- `renderGroup` (lexical_declaration, line 58)
- `list` (lexical_declaration, line 49)
- `className` (lexical_declaration, line 76)
- `wrapper` (lexical_declaration, line 77)
- `CompositeBlock` (type_alias_declaration, line 82)
- `CodedBlock` (type_alias_declaration, line 84)
- `SimpleBlock` (type_alias_declaration, line 132)
- `COMPOSITE_KINDS` (lexical_declaration, line 134)
- `CODED_KINDS` (lexical_declaration, line 135)
- `GRAMMAR_KINDS` (lexical_declaration, line 136)

## Uses

- [core/factories/element.factory.ts](https://banes-lab.com/source/tree/core/factories/element.factory.ts.md)
- [presentation/components/code.component.ts](https://banes-lab.com/source/tree/presentation/components/code.component.ts.md)
- [presentation/renderers/card.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/card.renderer.ts.md)
- [presentation/renderers/definition.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/definition.renderer.ts.md)
- [presentation/renderers/figure.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/figure.renderer.ts.md)
- [presentation/renderers/glossary.block.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/glossary.block.renderer.ts.md)
- [presentation/renderers/grammar.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/grammar.renderer.ts.md)
- [presentation/renderers/lesson.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/lesson.renderer.ts.md)
- [presentation/renderers/link.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/link.renderer.ts.md)
- [presentation/renderers/metric.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/metric.renderer.ts.md)
- [presentation/renderers/source.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/source.renderer.ts.md)
- [presentation/renderers/table.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/table.renderer.ts.md)
- [presentation/renderers/text.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/text.renderer.ts.md)
- [presentation/renderers/walk.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/walk.renderer.ts.md)

## Used by

- [presentation/renderers/folder.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/folder.renderer.ts.md)
- [presentation/renderers/glossary.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/glossary.renderer.ts.md)
- [presentation/renderers/ontology.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/ontology.renderer.ts.md)

## Source

```typescript
import type {
    Block,
    CardBlock,
    CodeBlock,
    DefinitionBlock,
    FigureBlock,
    GlossaryBlock,
    GroupBlock,
    GroupEntry,
    LessonBlock,
    LinkBlock,
    ListBlock,
    MarkdownBlock,
    MermaidBlock,
    MetricBlock,
    SourceBlock,
    TableBlock,
    TextBlock,
    WalkBlock,
} from "#types/block.types";
import { appendChildren, createElement } from "#core/factories/element.factory";
import type { GrammarBlock } from "#types/grammar.types";
import { createCodeBlock } from "#presentation/components/code.component";
import { fillMarkup } from "#presentation/renderers/text.renderer";
import { renderCards } from "#presentation/renderers/card.renderer";
import { renderDefinition } from "#presentation/renderers/definition.renderer";
import { renderDiagram } from "#presentation/renderers/diagram.renderer";
import { renderDocument } from "#presentation/renderers/markdown.renderer";
import { renderFigure } from "#presentation/renderers/figure.renderer";
import { renderGlossary } from "#presentation/renderers/glossary.block.renderer";
import { renderGrammarBlock } from "#presentation/renderers/grammar.renderer";
import { renderLesson } from "#presentation/renderers/lesson.renderer";
import { renderLinks } from "#presentation/renderers/link.renderer";
import { renderMetrics } from "#presentation/renderers/metric.renderer";
import { renderSource } from "#presentation/renderers/source.renderer";
import { renderTable } from "#presentation/renderers/table.renderer";
import { renderWalk } from "#presentation/renderers/walk.renderer";

const renderText = function renderText(block: TextBlock): Element {
    const className = block.note === true ? "block-note" : "block-text";
    return fillMarkup(createElement("p", { className }), block.text);
};

const renderList = function renderList(block: ListBlock): Element {
    const wrapper = createElement("div", { className: "block-list" });
    if (block.label !== undefined) {
        wrapper.append(createElement("h4", { className: "block-label", text: block.label }));
    }
    const list = createElement(block.ordered === true ? "ol" : "ul", {});
    appendChildren(
        list,
        block.items.map((item) => fillMarkup(createElement("li", {}), item)),
    );
    wrapper.append(list);
    return wrapper;
};

const renderGroup = function renderGroup(group: GroupEntry): Element {
    const wrapper = createElement("div", { className: "block-group" });
    if (group.title !== undefined) {
        wrapper.append(fillMarkup(createElement("h4", { className: "block-label" }), group.title));
    }
    if (group.content !== undefined) {
        wrapper.append(fillMarkup(createElement("p", { className: "block-text" }), group.content));
    }
    if (group.items !== undefined) {
        wrapper.append(renderList({ items: group.items, kind: "list" }));
    }
    if (group.entries !== undefined) {
        wrapper.append(renderGlossary({ entries: group.entries, kind: "glossary" }));
    }
    return wrapper;
};

const renderGroups = function renderGroups(block: GroupBlock): Element {
    const className = block.tone === undefined ? "block-groups" : `block-groups ${block.tone}`;
    const wrapper = createElement("div", { className });
    appendChildren(wrapper, block.groups.map(renderGroup));
    return wrapper;
};

type CompositeBlock = CardBlock | FigureBlock | LessonBlock | MermaidBlock | MetricBlock | WalkBlock;

type CodedBlock = CodeBlock | DefinitionBlock | MarkdownBlock | SourceBlock;

const renderCoded = function renderCoded(block: CodedBlock): Element {
    switch (block.kind) {
        case "code": {
            return createCodeBlock(block.code, block.title, block.language);
        }
        case "source": {
            return renderSource(block);
        }
        case "markdown": {
            return renderDocument(block);
        }
        case "definition": {
            return renderDefinition(block);
        }
        default: {
            return renderDefinition(block);
        }
    }
};

const renderComposite = function renderComposite(block: CompositeBlock): Element {
    switch (block.kind) {
        case "card": {
            return renderCards(block);
        }
        case "lesson": {
            return renderLesson(block);
        }
        case "figure": {
            return renderFigure(block);
        }
        case "mermaid": {
            return renderDiagram(block);
        }
        case "walk": {
            return renderWalk(block);
        }
        case "metric": {
            return renderMetrics(block);
        }
        default: {
            return renderMetrics(block);
        }
    }
};

type SimpleBlock = GlossaryBlock | GroupBlock | LinkBlock | ListBlock | TableBlock | TextBlock;

const COMPOSITE_KINDS = new Set<Block["kind"]>(["card", "figure", "lesson", "mermaid", "metric", "walk"]);
const CODED_KINDS = new Set<Block["kind"]>(["code", "definition", "markdown", "source"]);
const GRAMMAR_KINDS = new Set<Block["kind"]>(["check", "compare", "diagram", "keyword", "type"]);

const isComposite = function isComposite(block: Block): block is CompositeBlock {
    return COMPOSITE_KINDS.has(block.kind);
};

const isCoded = function isCoded(block: Block): block is CodedBlock {
    return CODED_KINDS.has(block.kind);
};

const isGrammar = function isGrammar(block: Block): block is GrammarBlock {
    return GRAMMAR_KINDS.has(block.kind);
};

const renderSimple = function renderSimple(block: SimpleBlock): Element {
    switch (block.kind) {
        case "text": {
            return renderText(block);
        }
        case "list": {
            return renderList(block);
        }
        case "glossary": {
            return renderGlossary(block);
        }
        case "table": {
            return renderTable(block);
        }
        case "group": {
            return renderGroups(block);
        }
        case "link": {
            return renderLinks(block);
        }
        default: {
            return renderLinks(block);
        }
    }
};

export const renderBlock = function renderBlock(block: Block): Element {
    if (isGrammar(block)) {
        return renderGrammarBlock(block);
    }
    if (isCoded(block)) {
        return renderCoded(block);
    }
    if (isComposite(block)) {
        return renderComposite(block);
    }
    return renderSimple(block);
};
```
