# core/sanitizers/code.go.sanitizer.ts

> 81 lines of code and 23 definitions.

Tree: GovLab Docs
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/docs#file-docs-core-sanitizers-code-go-sanitizer-ts
Source text: https://banes-lab.com/source/docs/core/sanitizers/code.go.sanitizer.ts.txt

Listed in [core/sanitizers](https://banes-lab.com/api/source/docs/core/sanitizers.md).

## Definitions

- `blank` (lexical_declaration, line 8)
- `#scanStringChar` (method_definition, line 57)
- `#scanBlockComment` (method_definition, line 76)
- `PAIR` (lexical_declaration, line 1)
- `LINE_BREAK` (lexical_declaration, line 2)
- `RAW_QUOTE` (lexical_declaration, line 3)
- `ESCAPE` (lexical_declaration, line 4)
- `QUOTES` (lexical_declaration, line 5)
- `BLANK_PAIR` (lexical_declaration, line 6)
- `GoSanitizer` (class_declaration, line 12)
- `#src` (public_field_definition, line 13)
- `#length` (public_field_definition, line 14)
- `#at` (public_field_definition, line 15)
- `#out` (public_field_definition, line 16)
- `constructor` (method_definition, line 18)
- `run` (method_definition, line 23)
- `#char` (method_definition, line 30)
- `#step` (method_definition, line 34)
- `#scanString` (method_definition, line 48)
- `open` (lexical_declaration, line 51)
- `char` (lexical_declaration, line 58)
- `#scanLineComment` (method_definition, line 69)
- `sanitizeGo` (lexical_declaration, line 90, exported)

## Contained in

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

## Linked from

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

## Source

```typescript
const PAIR = 2;
const LINE_BREAK = "\n";
const RAW_QUOTE = "`";
const ESCAPE = "\\";
const QUOTES: ReadonlySet<string> = new Set(['"', "'", RAW_QUOTE]);
const BLANK_PAIR = "  ";

const blank = function blank(char: string): string {
    return char === LINE_BREAK ? LINE_BREAK : " ";
};

class GoSanitizer {
    readonly #src: string;
    readonly #length: number;
    #at = 0;
    #out = "";

    public constructor(src: string) {
        this.#src = src;
        this.#length = src.length;
    }

    public run(): string {
        while (this.#at < this.#length) {
            this.#step();
        }
        return this.#out;
    }

    #char(offset = 0): string {
        return this.#src.charAt(this.#at + offset);
    }

    #step(): void {
        const char = this.#char();
        if (QUOTES.has(char)) {
            this.#scanString(char);
        } else if (char === "/" && this.#char(1) === "/") {
            this.#scanLineComment();
        } else if (char === "/" && this.#char(1) === "*") {
            this.#scanBlockComment();
        } else {
            this.#out += char;
            this.#at += 1;
        }
    }

    #scanString(quote: string): void {
        this.#out += " ";
        this.#at += 1;
        let open = true;
        while (open && this.#at < this.#length) {
            open = this.#scanStringChar(quote);
        }
    }

    #scanStringChar(quote: string): boolean {
        const char = this.#char();
        if (char === ESCAPE && quote !== RAW_QUOTE) {
            this.#out += BLANK_PAIR;
            this.#at += PAIR;
            return true;
        }
        this.#out += blank(char);
        this.#at += 1;
        return char !== quote;
    }

    #scanLineComment(): void {
        while (this.#at < this.#length && this.#char() !== LINE_BREAK) {
            this.#out += " ";
            this.#at += 1;
        }
    }

    #scanBlockComment(): void {
        this.#out += BLANK_PAIR;
        this.#at += PAIR;
        while (this.#at < this.#length && !(this.#char() === "*" && this.#char(1) === "/")) {
            this.#out += blank(this.#char());
            this.#at += 1;
        }
        if (this.#at < this.#length) {
            this.#out += BLANK_PAIR;
            this.#at += PAIR;
        }
    }
}

export const sanitizeGo = function sanitizeGo(src: string): string {
    return new GoSanitizer(src).run();
};
```
