# core/formatters/page.formatter.ts

> 39 lines of code and 15 definitions.

Tree: Bane's Lab Build Scripts
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/build-scripts#file-build-scripts-core-formatters-page-formatter-ts
Source text: https://banes-lab.com/source/build-scripts/core/formatters/page.formatter.ts.txt

Listed in [core/formatters](https://banes-lab.com/api/source/build-scripts/core/formatters.md), after [core/formatters/ontology.formatter.ts](https://banes-lab.com/source/build-scripts/core/formatters/ontology.formatter.ts.md) and before [core/formatters/record.formatter.ts](https://banes-lab.com/source/build-scripts/core/formatters/record.formatter.ts.md).

## Definitions

- `renderFullText` (lexical_declaration, line 24, exported)
- `renderMarkdownPage` (lexical_declaration, line 17, exported)
- `renderPageHtml` (lexical_declaration, line 35, exported)
- `withLineEnd` (lexical_declaration, line 13)
- `SEPARATOR` (lexical_declaration, line 6)
- `BLANK` (lexical_declaration, line 7)
- `LINE_END` (lexical_declaration, line 8)
- `HEADING_MARK` (lexical_declaration, line 9)
- `QUOTE_MARK` (lexical_declaration, line 10)
- `CANONICAL_LABEL` (lexical_declaration, line 11)
- `canonical` (lexical_declaration, line 20, exported)
- `pages` (lexical_declaration, line 28, exported)
- `heading` (lexical_declaration, line 29, exported)
- `summary` (lexical_declaration, line 30, exported)
- `consent` (lexical_declaration, line 31, exported)

## Contained in

- [core/formatters](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-formatters.md)

## Uses

- [core/adapters/document.adapter.ts](https://banes-lab.com/source/build-scripts/core/adapters/document.adapter.ts.md)

## Used by

- [core/coordinators/payload.coordinator.ts](https://banes-lab.com/source/build-scripts/core/coordinators/payload.coordinator.ts.md)
- [core/persistence/page.persistence.ts](https://banes-lab.com/source/build-scripts/core/persistence/page.persistence.ts.md)

## Linked from

- [core/adapters](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-adapters.md)
- [core/coordinators](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-coordinators.md)
- [core/formatters](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-formatters.md)
- [core/persistence](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-persistence.md)

## Source

```typescript
import type { DiscoveredRoute, Discovery } from "#types/site.types";
import type { PageRoute, PageSource } from "#types/page.types";
import { rewriteDocument } from "#core/adapters/document.adapter";
import { trainingConsent } from "#configuration/strings/site.strings";

const SEPARATOR = "\n\n---\n\n";
const BLANK = "\n\n";
const LINE_END = "\n";
const HEADING_MARK = "# ";
const QUOTE_MARK = "> ";
const CANONICAL_LABEL = "Canonical: ";

const withLineEnd = function withLineEnd(parts: readonly string[], joint: string): string {
    return parts.join(joint) + LINE_END;
};

export const renderMarkdownPage = function renderMarkdownPage(site: string, route: DiscoveredRoute): string {
    const heading = HEADING_MARK + route.title;
    const summary = QUOTE_MARK + route.description;
    const canonical = CANONICAL_LABEL + site + route.path;
    return withLineEnd([heading, summary, canonical, route.markdown], BLANK);
};

export const renderFullText = function renderFullText(
    discovery: Discovery,
    routes: readonly DiscoveredRoute[],
): string {
    const pages = routes.map((route) => renderMarkdownPage(discovery.site, route).trimEnd());
    const heading = HEADING_MARK + discovery.name;
    const summary = QUOTE_MARK + discovery.summary;
    const consent = trainingConsent(discovery.consent, discovery.author, discovery.site);
    return withLineEnd([heading, summary, consent, ...pages], SEPARATOR);
};

export const renderPageHtml = function renderPageHtml(loaded: PageSource, template: string, route: PageRoute): string {
    loaded.visit(route.path);
    return rewriteDocument(template, (root) => {
        loaded.renderer.applyHead(
            root,
            loaded.renderer.headOf(route.page, loaded.registry.loadedPage(route.page), route.path, route.dates),
        );
        root.getElementById(loaded.main)?.replaceChildren(...loaded.renderer.renderStaticPage(route.page));
    });
};
```
