# presentation/components/code.component.ts

> 88 lines of code and 11 definitions.

Tree: Site tree
Language: typescript
Layer: product
Canonical: https://banes-lab.com/anatomy/tree#file-presentation-components-code-component-ts
Source text: https://banes-lab.com/assets/sources/source.fe6b18d10094ca320491bb667cce7fccd9ceaf845bcf9dc5943b7f70d19d7a37.generated.txt

## Definitions

- `createPlainCodeBlock` (lexical_declaration, line 43, exported)
- `createCodeBlock` (lexical_declaration, line 66, exported)
- `createCodeBody` (lexical_declaration, line 21)
- `revealLine` (lexical_declaration, line 25, exported)
- `span` (lexical_declaration, line 29, exported)
- `panel` (lexical_declaration, line 34, exported)
- `lines` (lexical_declaration, line 67, exported)
- `expandable` (lexical_declaration, line 68, exported)
- `actions` (lexical_declaration, line 69, exported)
- `header` (lexical_declaration, line 82, exported)
- `block` (lexical_declaration, line 86, exported)

## Uses

- [core/factories/element.factory.ts](https://banes-lab.com/source/tree/core/factories/element.factory.ts.md)
- [presentation/components/clipboard.component.ts](https://banes-lab.com/source/tree/presentation/components/clipboard.component.ts.md)
- [presentation/components/overlay.component.ts](https://banes-lab.com/source/tree/presentation/components/overlay.component.ts.md)
- [presentation/components/panel.component.ts](https://banes-lab.com/source/tree/presentation/components/panel.component.ts.md)
- [presentation/renderers/syntax.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/syntax.renderer.ts.md)

## Used by

- [presentation/renderers/anatomy.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/anatomy.renderer.ts.md)
- [presentation/renderers/block.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/block.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/markdown.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/markdown.renderer.ts.md)

## Source

```typescript
import {
    CODE_LINE_ATTRIBUTE,
    CODE_LINE_CLASS,
    CODE_LINE_MARKED_CLASS,
} from "#configuration/constants/syntax.constants";
import {
    COLLAPSED_LINE_LIMIT,
    EXPANDABLE_CLASS,
    LANGUAGE_ATTRIBUTE,
    LINE_BREAK,
} from "#configuration/constants/code.constants";
import { LINES_SUFFIX, VIEW_FULL_CODE_TITLE } from "#configuration/strings/code.strings";
import { PANEL_CLASS, PANEL_REVEAL_EVENT } from "#configuration/constants/panel.constants";
import { SCROLL_BEHAVIOR, SCROLL_BLOCK } from "#configuration/constants/tab.constants";
import { appendChildren, createElement } from "#core/factories/element.factory";
import { createCopyButton } from "#presentation/components/clipboard.component";
import { createExpandButton } from "#presentation/components/overlay.component";
import { createPanel } from "#presentation/components/panel.component";
import { renderSyntax } from "#presentation/renderers/syntax.renderer";

const createCodeBody = function createCodeBody(code: string, language: string, className: string): HTMLElement {
    return createPanel(renderSyntax(code, language), className, "origin").element;
};

export const revealLine = function revealLine(scope: Element, line: number): boolean {
    for (const marked of scope.querySelectorAll(`.${CODE_LINE_CLASS}.${CODE_LINE_MARKED_CLASS}`)) {
        marked.classList.remove(CODE_LINE_MARKED_CLASS);
    }
    const span = scope.querySelector<HTMLElement>(`.${CODE_LINE_CLASS}[${CODE_LINE_ATTRIBUTE}="${String(line)}"]`);
    if (span === null) {
        return false;
    }
    span.classList.add(CODE_LINE_MARKED_CLASS);
    const panel = span.closest(`.${PANEL_CLASS}`);
    if (panel === null) {
        span.scrollIntoView({ behavior: SCROLL_BEHAVIOR, block: SCROLL_BLOCK });
    } else {
        panel.dispatchEvent(new CustomEvent(PANEL_REVEAL_EVENT, { detail: span.offsetTop }));
    }
    return true;
};

export const createPlainCodeBlock = function createPlainCodeBlock(
    code: string,
    title: string,
    language: string,
): HTMLElement {
    const header = createElement("div", {
        children: [
            createElement("span", { className: "code-title", text: title }),
            createElement("div", { children: [createCopyButton(() => code, "code-copy")], className: "code-actions" }),
        ],
        className: "code-header",
    });
    const block = createElement("pre", {
        attributes: { [LANGUAGE_ATTRIBUTE]: language },
        className: "code-block code-plain",
    });
    appendChildren(block, [
        header,
        createElement("div", { children: [renderSyntax(code, language)], className: "code-whole" }),
    ]);
    return block;
};

export const createCodeBlock = function createCodeBlock(code: string, title: string, language: string): HTMLElement {
    const lines = code.split(LINE_BREAK).length;
    const expandable = lines > COLLAPSED_LINE_LIMIT;
    const actions = createElement("div", { className: "code-actions" });
    if (expandable) {
        actions.append(
            createExpandButton(
                "code-expand",
                VIEW_FULL_CODE_TITLE,
                title,
                () => createCodeBody(code, language, "code-full"),
                [createElement("span", { text: String(lines) + LINES_SUFFIX })],
            ),
        );
    }
    actions.append(createCopyButton(() => code, "code-copy"));
    const header = createElement("div", {
        children: [createElement("span", { className: "code-title", text: title }), actions],
        className: "code-header",
    });
    const block = createElement("pre", {
        attributes: { [LANGUAGE_ATTRIBUTE]: language },
        className: expandable ? `code-block ${EXPANDABLE_CLASS}` : "code-block",
    });
    appendChildren(block, [header, createCodeBody(code, language, "code-content")]);
    return block;
};
```
