core/parsers/knob.parser.ts
core/parsers/knob.parser.ts is a file in GovLab Quality. 54 lines of code and 12 definitions.
import { everyChar, isDigit, isIdentifierChar } from "@govlab/constants";
const SCAN_STOPS: ReadonlySet<string> = new Set(["\n", ";", ")"]);
const RUBY_TAG = "!ruby/";
export const intAt = function intAt(text: string, start: number): number | null {
let i = start;
while (i < text.length && !isDigit(text[i] ?? "")) {
if (SCAN_STOPS.has(text[i] ?? "")) {
return null;
}
i += 1;
}
let digits = "";
while (i < text.length && isDigit(text[i] ?? "")) {
digits += text[i];
i += 1;
}
return digits === "" ? null : Number(digits);
};
export const intAfter = function intAfter(
text: string,
marker: string,
opts: { from: number; window?: number },
): number | null {
const at = text.indexOf(marker, opts.from);
if (at === -1 || (typeof opts.window === "number" && at - opts.from > opts.window)) {
return null;
}
return intAt(text, at + marker.length);
};
export const withoutRubyTags = function withoutRubyTags(text: string): string {
let result = "";
let i = 0;
while (i < text.length) {
if (text.startsWith(RUBY_TAG, i)) {
while (i < text.length && text[i] !== " " && text[i] !== "\n") {
i += 1;
}
} else {
result += text[i];
i += 1;
}
}
return result;
};
export const isDigitsOnly = function isDigitsOnly(raw: string): boolean {
return raw.length > 0 && everyChar(raw, isDigit);
};
export const trailingIdentifier = function trailingIdentifier(chunk: string): string {
let field = "";
for (const ch of chunk) {
field = isIdentifierChar(ch) ? field + ch : "";
}
return field;
};