import { AndRule, type DataRef, LiteralRule, type Rule, type RuleTestResponse, } from '@os-team/lexical-rules'; import SRule from '../rules/SRule.js'; import PubidLiteralRule from '../rules/PubidLiteralRule.js'; import type { Parser } from './Parser.js'; export interface PublicID { type: 'PUBLIC_ID'; pubidValue: string; } /** * See https://www.w3.org/TR/xml/#NT-PublicID */ class PublicIDParser implements Parser { private readonly rule: Rule<[string, undefined, string]>; public constructor() { const publicRule = new LiteralRule('PUBLIC'); // 'PUBLIC' const sRule = new SRule('+'); // S const pubidLiteralRule = new PubidLiteralRule(); // PubidLiteral this.rule = new AndRule([publicRule, sRule, pubidLiteralRule]); // 'PUBLIC' S PubidLiteral } public test(ref: DataRef, pos: number): RuleTestResponse { const [isValid, nextPos, res] = this.rule.test(ref, pos); if (!isValid || res === undefined) return [false, nextPos]; return [true, nextPos, { type: 'PUBLIC_ID', pubidValue: res[2] }]; } public build(data: PublicID) { return `PUBLIC "${data.pubidValue.replaceAll('"', "'")}"`; } } export default PublicIDParser;