# core/formatters/markdown.formatter.ts

> 37 lines of code and 19 definitions.

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

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

## Definitions

- `addressLines` (lexical_declaration, line 26, exported)
- `BLANK` (lexical_declaration, line 1)
- `LINE_END` (lexical_declaration, line 2)
- `BULLET` (lexical_declaration, line 3)
- `HEADING` (lexical_declaration, line 4)
- `SUBHEADING` (lexical_declaration, line 5)
- `QUOTE` (lexical_declaration, line 6)
- `TICK` (lexical_declaration, line 7)
- `FENCE_MINIMUM` (lexical_declaration, line 8)
- `blocks` (lexical_declaration, line 10, exported)
- `heading` (lexical_declaration, line 14, exported)
- `quote` (lexical_declaration, line 18, exported)
- `section` (lexical_declaration, line 22, exported)
- `held` (lexical_declaration, line 27, exported)
- `code` (lexical_declaration, line 31, exported)
- `fenced` (lexical_declaration, line 35, exported)
- `longest` (lexical_declaration, line 36, exported)
- `run` (lexical_declaration, line 37, exported)
- `fence` (lexical_declaration, line 42, exported)

## Contained in

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

## Used by

- [core/formatters/company.formatter.ts](https://banes-lab.com/source/build-scripts/core/formatters/company.formatter.ts.md)
- [core/formatters/data.formatter.ts](https://banes-lab.com/source/build-scripts/core/formatters/data.formatter.ts.md)
- [core/formatters/index.formatter.ts](https://banes-lab.com/source/build-scripts/core/formatters/index.formatter.ts.md)
- [core/formatters/record.formatter.ts](https://banes-lab.com/source/build-scripts/core/formatters/record.formatter.ts.md)
- [core/formatters/section.formatter.ts](https://banes-lab.com/source/build-scripts/core/formatters/section.formatter.ts.md)
- [core/formatters/source.formatter.ts](https://banes-lab.com/source/build-scripts/core/formatters/source.formatter.ts.md)

## Linked from

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

## Source

```typescript
const BLANK = "\n\n";
const LINE_END = "\n";
const BULLET = "- ";
const HEADING = "# ";
const SUBHEADING = "## ";
const QUOTE = "> ";
const TICK = "`";
const FENCE_MINIMUM = 3;

export const blocks = function blocks(parts: readonly (string | null)[]): string {
    return parts.filter((part): part is string => part !== null && part.length > 0).join(BLANK) + LINE_END;
};

export const heading = function heading(title: string): string {
    return HEADING + title;
};

export const quote = function quote(text: string | null): string | null {
    return text === null || text.length === 0 ? null : QUOTE + text;
};

export const section = function section(title: string, items: readonly string[]): string | null {
    return items.length === 0 ? null : SUBHEADING + title + BLANK + items.map((item) => BULLET + item).join(LINE_END);
};

export const addressLines = function addressLines(pairs: readonly (readonly [string, string | null])[]): string | null {
    const held = pairs.filter((pair): pair is readonly [string, string] => pair[1] !== null);
    return held.length === 0 ? null : held.map(([label, value]) => `${label}: ${value}`).join(LINE_END);
};

export const code = function code(text: string): string {
    return TICK + text + TICK;
};

export const fenced = function fenced(text: string, language: string): string {
    let longest = 0;
    let run = 0;
    for (const char of text) {
        run = char === TICK ? run + 1 : 0;
        longest = Math.max(longest, run);
    }
    const fence = TICK.repeat(Math.max(FENCE_MINIMUM, longest + 1));
    return fence + language + LINE_END + text.trimEnd() + LINE_END + fence;
};
```
