# domain/converters/ontology.graph.converter.ts

> 40 lines of code and 15 definitions.

Tree: Bane's Lab Site
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/tree#file-domain-converters-ontology-graph-converter-ts
Source text: https://banes-lab.com/source/tree/domain/converters/ontology.graph.converter.ts.txt

Listed in [domain/converters](https://banes-lab.com/api/source/tree/domain/converters.md), after [domain/converters/ontology.converter.ts](https://banes-lab.com/source/tree/domain/converters/ontology.converter.ts.md) and before [domain/converters/principle.converter.ts](https://banes-lab.com/source/tree/domain/converters/principle.converter.ts.md).

## Definitions

- `diagram` (lexical_declaration, line 29, exported)
- `edgeLine` (lexical_declaration, line 33, exported)
- `nodeId` (lexical_declaration, line 13, exported)
- `nodeLabel` (lexical_declaration, line 21, exported)
- `node` (lexical_declaration, line 25, exported)
- `QUOTE` (lexical_declaration, line 6)
- `APOSTROPHE` (lexical_declaration, line 7)
- `NODE_OPEN` (lexical_declaration, line 8)
- `NODE_CLOSE` (lexical_declaration, line 9)
- `INDENT` (lexical_declaration, line 10)
- `NODE_PREFIX` (lexical_declaration, line 11)
- `out` (lexical_declaration, line 14, exported)
- `localId` (lexical_declaration, line 37, exported)
- `prefix` (lexical_declaration, line 41, exported)
- `id` (lexical_declaration, line 45, exported)

## Contained in

- [domain/converters](https://banes-lab.com/anatomy/tree/folder-domain-converters.md)

## Used by

- [domain/converters/contract.converter.ts](https://banes-lab.com/source/tree/domain/converters/contract.converter.ts.md)
- [domain/converters/graph.converter.ts](https://banes-lab.com/source/tree/domain/converters/graph.converter.ts.md)
- [domain/converters/kind.converter.ts](https://banes-lab.com/source/tree/domain/converters/kind.converter.ts.md)
- [domain/converters/loop.converter.ts](https://banes-lab.com/source/tree/domain/converters/loop.converter.ts.md)
- [domain/converters/principle.converter.ts](https://banes-lab.com/source/tree/domain/converters/principle.converter.ts.md)
- [domain/converters/tension.converter.ts](https://banes-lab.com/source/tree/domain/converters/tension.converter.ts.md)

## Linked from

- [domain/converters](https://banes-lab.com/anatomy/tree/folder-domain-converters.md)

## Source

```typescript
import { SLUG_CHARS, UNDERSCORE } from "#configuration/constants/document.constants";
import type { EdgeRef } from "#types/link.types";
import { FACE_SEPARATOR } from "@govlab/constants";
import { LINE_BREAK } from "#configuration/constants/code.constants";

const QUOTE = '"';
const APOSTROPHE = "'";
const NODE_OPEN = '["';
const NODE_CLOSE = '"]';
const INDENT = "    ";
const NODE_PREFIX = "n_";

export const nodeId = function nodeId(id: string): string {
    let out = NODE_PREFIX;
    for (const char of id.toLowerCase()) {
        out += SLUG_CHARS.includes(char) ? char : UNDERSCORE;
    }
    return out;
};

export const nodeLabel = function nodeLabel(label: string): string {
    return label.replaceAll(QUOTE, APOSTROPHE);
};

export const node = function node(id: string, label: string): string {
    return INDENT + nodeId(id) + NODE_OPEN + nodeLabel(label) + NODE_CLOSE;
};

export const diagram = function diagram(header: string, lines: readonly string[]): string {
    return [header, ...lines].join(LINE_BREAK);
};

export const edgeLine = function edgeLine(from: string, arrow: string, to: string): string {
    return INDENT + nodeId(from) + arrow + nodeId(to);
};

export const localId = function localId(edge: EdgeRef, face: string, members: ReadonlySet<string>): string | null {
    if (edge.ref === null) {
        return null;
    }
    const prefix = face + FACE_SEPARATOR;
    if (!edge.ref.startsWith(prefix)) {
        return null;
    }
    const id = edge.ref.slice(prefix.length);
    return members.has(id) ? id : null;
};
```
