# core/converters/code.converter.ts

> 19 lines of code and 6 definitions.

Tree: GovLab Patterns
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/patterns#file-patterns-core-converters-code-converter-ts
Source text: https://banes-lab.com/source/patterns/core/converters/code.converter.ts.txt

Listed in [core/converters](https://banes-lab.com/api/source/patterns/core/converters.md), before [core/converters/definition.converter.ts](https://banes-lab.com/source/patterns/core/converters/definition.converter.ts.md).

## Definitions

- `bodyHash` (lexical_declaration, line 20, exported)
- `normalize` (lexical_declaration, line 6)
- `WHITESPACE` (lexical_declaration, line 3)
- `GAP` (lexical_declaration, line 4)
- `out` (lexical_declaration, line 7)
- `gap` (lexical_declaration, line 8)

## Contained in

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

## Used by

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

## Linked from

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

## Source

```typescript
import { fingerprintOf } from "@govlab/content-fingerprint";

const WHITESPACE: ReadonlySet<string> = new Set([" ", "\t", "\n", "\r"]);
const GAP = " ";

const normalize = function normalize(text: string): string {
    let out = "";
    let gap = false;
    for (const char of text) {
        if (WHITESPACE.has(char)) {
            gap = true;
        } else {
            out += gap && out.length > 0 ? `${GAP}${char}` : char;
            gap = false;
        }
    }
    return out;
};

export const bodyHash = function bodyHash(text: string): string {
    return fingerprintOf([normalize(text)]);
};
```
