# core/parsers/ontology.parser.ts

> 40 lines of code and 13 definitions.

Tree: GovLab Docs
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/docs#file-docs-core-parsers-ontology-parser-ts
Source text: https://banes-lab.com/source/docs/core/parsers/ontology.parser.ts.txt

Listed in [core/parsers](https://banes-lab.com/api/source/docs/core/parsers.md), after [core/parsers/metadata.parser.ts](https://banes-lab.com/source/docs/core/parsers/metadata.parser.ts.md) and before [core/parsers/reference.parser.ts](https://banes-lab.com/source/docs/core/parsers/reference.parser.ts.md).

## Definitions

- `isPlaceholder` (lexical_declaration, line 8)
- `refsInLine` (lexical_declaration, line 25)
- `ontologyRefs` (lexical_declaration, line 43, exported)
- `refOf` (lexical_declaration, line 17)
- `TICK` (lexical_declaration, line 4)
- `SEPARATOR` (lexical_declaration, line 5)
- `PLACEHOLDER_CHARS` (lexical_declaration, line 6)
- `colon` (lexical_declaration, line 18)
- `found` (lexical_declaration, line 26)
- `from` (lexical_declaration, line 27)
- `open` (lexical_declaration, line 29)
- `close` (lexical_declaration, line 30)
- `ref` (lexical_declaration, line 34)

## Contained in

- [core/parsers](https://banes-lab.com/anatomy/docs/folder-docs-core-parsers.md)

## Uses

- [core/parsers/markdown.parser.ts](https://banes-lab.com/source/docs/core/parsers/markdown.parser.ts.md)

## Linked from

- [core/parsers](https://banes-lab.com/anatomy/docs/folder-docs-core-parsers.md)

## Source

```typescript
import type { OntologyRef } from "#types/reference.types";
import { proseLines } from "#core/parsers/markdown.parser";

const TICK = "`";
const SEPARATOR = ":";
const PLACEHOLDER_CHARS: ReadonlySet<string> = new Set(["<", ">", "{", "}", "*", " ", "|", "/"]);

const isPlaceholder = function isPlaceholder(span: string): boolean {
    for (const char of span) {
        if (PLACEHOLDER_CHARS.has(char)) {
            return true;
        }
    }
    return false;
};

const refOf = function refOf(span: string, collections: ReadonlySet<string>): string | null {
    const colon = span.indexOf(SEPARATOR);
    if (colon <= 0 || colon === span.length - 1 || isPlaceholder(span)) {
        return null;
    }
    return collections.has(span.slice(0, colon)) ? span : null;
};

const refsInLine = function refsInLine(line: string, lineNo: number, collections: ReadonlySet<string>): OntologyRef[] {
    const found: OntologyRef[] = [];
    let from = 0;
    while (from < line.length) {
        const open = line.indexOf(TICK, from);
        const close = open === -1 ? -1 : line.indexOf(TICK, open + 1);
        if (close === -1) {
            return found;
        }
        const ref = refOf(line.slice(open + 1, close), collections);
        if (ref !== null) {
            found.push({ col: open + 1, line: lineNo, ref });
        }
        from = close + 1;
    }
    return found;
};

export const ontologyRefs = function ontologyRefs(source: string, collections: ReadonlySet<string>): OntologyRef[] {
    return proseLines(source).flatMap(({ line, lineNo }) => refsInLine(line, lineNo, collections));
};
```
