import { AndRule, type DataRef, LiteralRule, type Rule, type RuleTestResponse, } from '@os-team/lexical-rules'; import type { Parser } from './Parser.js'; import SRule from '../rules/SRule.js'; import EqRule from '../rules/EqRule.js'; import AnyQuotedRule from '../rules/AnyQuotedRule.js'; import EncNameRule from '../rules/EncNameRule.js'; /** * The encoding name. * See https://www.w3.org/TR/xml/#NT-EncodingDecl */ class EncodingDeclParser implements Parser { private readonly rule: Rule<[undefined, string, undefined, string]>; public constructor() { const sRule = new SRule('+'); // S const encodingRule = new LiteralRule('encoding'); // 'encoding' const eqRule = new EqRule(); // Eq const encNameRule = new EncNameRule(); // EncName const quotedEncNameRule = new AnyQuotedRule(encNameRule); // ('"' EncName '"' | "'" EncName "'" ) this.rule = new AndRule([sRule, encodingRule, eqRule, quotedEncNameRule]); // S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" ) } 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, res[3]]; } public build(data: string) { if (!/^[A-Za-z][A-Za-z0-9._-]*$/.test(data)) { throw new Error('The encoding name in the XML declaration is incorrect'); } return ` encoding="${data}"`; } } export default EncodingDeclParser;