import type { RuleTestResponse } from '@os-team/lexical-rules'; import type { DataWithOptionsRef, Parser } from './Parser.js'; import ContentParser, { type Content } from './ContentParser.js'; import STagParser from './STagParser.js'; import ETagParser from './ETagParser.js'; export interface Tag { type: 'TAG'; name: string; content: Content; attrs?: Record; } /** * The tag. */ class TagParser implements Parser { private readonly sTagParser: STagParser; private readonly contentParser: ContentParser; public constructor() { this.sTagParser = new STagParser(); // STag this.contentParser = new ContentParser(); // content } public test(ref: DataWithOptionsRef, pos: number): RuleTestResponse { // STag const [sTagIsValid, sTagNextPos, sTagRes] = this.sTagParser.test(ref, pos); if (!sTagIsValid || sTagRes === undefined) return [false, sTagNextPos]; const { name, attrs } = sTagRes; // content const [contentIsValid, contentNextPos, contentRes] = this.contentParser.test(ref, sTagNextPos); if (!contentIsValid || contentRes === undefined) { return [false, contentNextPos]; } // ETag const eTagParser = new ETagParser(name); const [eTagIsValid, eTagNextPos] = eTagParser.test(ref, contentNextPos); if (!eTagIsValid) return [false, eTagNextPos]; const tag: Tag = { type: 'TAG', name, content: contentRes }; if (attrs) tag.attrs = attrs; return [true, eTagNextPos, tag]; } public build(data: Tag) { const { name, content, attrs } = data; if (content === undefined && !attrs) return ''; const sTag = this.sTagParser.build({ type: 'START_TAG', name, attrs }); const strContent = this.contentParser.build(content); const eTagParser = new ETagParser(name); const eTag = eTagParser.build(); return `${sTag}${strContent}${eTag}`; } } export default TagParser;