import { AndRule, type DataRef, LiteralRule, MaybeRule, type Rule, type RuleTestResponse, } from '@os-team/lexical-rules'; import type { Parser } from './Parser.js'; import VersionInfoParser from './VersionInfoParser.js'; import EncodingDeclParser from './EncodingDeclParser.js'; import SdDeclParser from './SdDeclParser.js'; import SRule from '../rules/SRule.js'; export interface XMLDecl { version: string; encoding?: string; standalone?: boolean; } /** * The XML declaration. * See https://www.w3.org/TR/xml/#NT-XMLDecl */ class XMLDeclParser implements Parser { private readonly versionInfoParser: VersionInfoParser; private readonly encodingDeclParser: EncodingDeclParser; private readonly sdDeclParser: SdDeclParser; private rule: Rule< [string, string, string | undefined, boolean | undefined, undefined, string] >; public constructor() { const prefixRule = new LiteralRule(''); // '?>' this.rule = new AndRule([ prefixRule, this.versionInfoParser, maybeEncodingDeclRule, maybeSdDeclRule, anySRule, suffixRule, ]); // '' } public test(ref: DataRef, pos: number): RuleTestResponse { const [isValid, nextPos, res] = this.rule.test(ref, pos); if (!isValid || res === undefined) return [false, nextPos]; const [, version, encoding, standalone] = res; const xmlDecl: XMLDecl = { version }; if (encoding !== undefined) xmlDecl.encoding = encoding; if (standalone !== undefined) xmlDecl.standalone = standalone; return [true, nextPos, xmlDecl]; } public build(data: XMLDecl) { const { version, encoding, standalone } = data; const versionInfo = this.versionInfoParser.build(version); const encodingDecl = encoding ? this.encodingDeclParser.build(encoding) : ''; const sdDecl = standalone ? this.sdDeclParser.build(standalone) : ''; return ``; } } export default XMLDeclParser;