# core/predicates/character.predicate.ts

> 28 lines of code and 8 definitions.

Tree: GovLab Docs
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/docs#file-docs-core-predicates-character-predicate-ts
Source text: https://banes-lab.com/source/docs/core/predicates/character.predicate.ts.txt

Listed in [core/predicates](https://banes-lab.com/api/source/docs/core/predicates.md), before [core/predicates/code.typescript.predicate.ts](https://banes-lab.com/source/docs/core/predicates/code.typescript.predicate.ts.md).

## Definitions

- `isAsciiAlnum` (lexical_declaration, line 8, exported)
- `isKebab` (lexical_declaration, line 20, exported)
- `isAsciiLower` (lexical_declaration, line 12, exported)
- `isKebabChar` (lexical_declaration, line 16)
- `LOWER_SET` (lexical_declaration, line 3)
- `HYPHEN` (lexical_declaration, line 4)
- `DOUBLE_HYPHEN` (lexical_declaration, line 5)
- `KEBAB_CHARS` (lexical_declaration, line 6)

## Contained in

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

## Used by

- [core/analyzers/vocabulary.analyzer.ts](https://banes-lab.com/source/docs/core/analyzers/vocabulary.analyzer.ts.md)
- [core/normalizers/diagram.normalizer.ts](https://banes-lab.com/source/docs/core/normalizers/diagram.normalizer.ts.md)
- [core/plugins/manifest.document.plugin.ts](https://banes-lab.com/source/docs/core/plugins/manifest.document.plugin.ts.md)
- [core/validators/metadata.validator.ts](https://banes-lab.com/source/docs/core/validators/metadata.validator.ts.md)

## Linked from

- [core/analyzers](https://banes-lab.com/anatomy/docs/folder-docs-core-analyzers.md)
- [core/normalizers](https://banes-lab.com/anatomy/docs/folder-docs-core-normalizers.md)
- [core/plugins](https://banes-lab.com/anatomy/docs/folder-docs-core-plugins.md)
- [core/predicates](https://banes-lab.com/anatomy/docs/folder-docs-core-predicates.md)
- [core/validators](https://banes-lab.com/anatomy/docs/folder-docs-core-validators.md)

## Source

```typescript
import { DIGITS, LOWER_ALPHA, isAlpha, isDigit } from "@govlab/constants";

const LOWER_SET: ReadonlySet<string> = new Set(LOWER_ALPHA);
const HYPHEN = "-";
const DOUBLE_HYPHEN = "--";
const KEBAB_CHARS: ReadonlySet<string> = new Set([...LOWER_ALPHA, ...DIGITS, HYPHEN]);

export const isAsciiAlnum = function isAsciiAlnum(char: string): boolean {
    return isAlpha(char) || isDigit(char);
};

export const isAsciiLower = function isAsciiLower(char: string): boolean {
    return LOWER_SET.has(char);
};

const isKebabChar = function isKebabChar(char: string): boolean {
    return KEBAB_CHARS.has(char);
};

export const isKebab = function isKebab(value: unknown): boolean {
    if (typeof value !== "string" || value.length === 0) {
        return false;
    }
    if (value.startsWith(HYPHEN) || value.endsWith(HYPHEN) || value.includes(DOUBLE_HYPHEN)) {
        return false;
    }
    for (const char of value) {
        if (!isKebabChar(char)) {
            return false;
        }
    }
    return true;
};
```
