UNPKG

conflutora

Version:

Provider to convert and publish Antora documentation on Confluence

112 lines 4.89 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.HtmlParserService = void 0; const node_html_parser_1 = require("node-html-parser"); const xmlbuilder_1 = __importDefault(require("xmlbuilder")); const Logger_js_1 = require("../utils/Logger.js"); class HtmlParserService { logger = new Logger_js_1.Logger(this.constructor.name); tagMapper = { p: (xml, elem) => xml.ele('p').raw(elem.innerHTML.trim()), h1: (xml, elem) => xml.ele('h1').raw(elem.innerHTML), h2: (xml, elem) => xml.ele('h2').raw(elem.innerHTML), h3: (xml, elem) => xml.ele('h3').raw(elem.innerHTML), h4: (xml, elem) => xml.ele('h4').raw(elem.innerHTML), h5: (xml, elem) => xml.ele('h5').raw(elem.innerHTML), h6: (xml, elem) => xml.ele('h6').raw(elem.innerHTML), hr: (xml, elem) => xml.ele('hr', { 'ac:layout': 'default' }).up(), // Use 'up()' to go back to the parent after appending the hr tag ul: (xml, elem) => { const ul = xml.ele('ul'); elem.childNodes.filter(child => child.rawTagName === 'li').forEach(child => { this.tagMapper.li(ul, child); }); }, ol: (xml, elem) => { const ol = xml.ele('ol'); elem.childNodes.filter(child => child.rawTagName === 'li').forEach(child => { this.tagMapper.li(ol, child); }); }, li: (xml, elem) => xml.ele('li').raw(elem.innerHTML), a: (xml, elem) => { const href = elem.getAttribute('href') ?? '#'; xml.ele('a', { href }).raw(elem.textContent.trim()); }, img: (xml, elem) => { const src = elem.getAttribute('src') ?? ''; const alt = elem.getAttribute('alt') ?? ''; xml.ele('ac:image', { 'ri:filename': src }) .ele('ri:attachment', { 'ri:filename': src }) .up() .ele('ac:plain-text-link-body') .txt(`![${alt}](${src})`); } // img: (xml, elem) => { // const src = elem.getAttribute('src') ?? '' // const alt = elem.getAttribute('alt') ?? '' // const img = xml.ele('ac:image', { 'ri:filename': src }) // img.ele('ri:attachment', { 'ri:filename': src }).up() // img.ele('ac:plain-text-link-body') // .text(`![${alt}](${src})`) // } }; getPageTitle(htmlContent) { const dom = (0, node_html_parser_1.parse)(htmlContent); const titleSelectors = ['h1.page', 'h1', 'h2']; for (const selector of titleSelectors) { const titleElement = dom.querySelector(selector); if (titleElement?.text) { return titleElement.text.trim(); } else { this.logger.debug(`No title found using selector '${selector}'`); } } this.logger.error('Failed to extract a title from the input'); return undefined; } extractBodyContent(htmlContent) { const dom = (0, node_html_parser_1.parse)(htmlContent, { blockTextElements: { code: true } }); return dom.querySelector('article.doc')?.innerHTML ?? dom.querySelector('main.article')?.innerHTML ?? ''; } convertToConfluenceXML(htmlContent) { // this.logger.info('Converting HTML to Confluence XML', htmlContent) const dom = (0, node_html_parser_1.parse)(htmlContent); const xml = xmlbuilder_1.default.create('ac:rich-text-body', { version: '1.0', encoding: 'UTF-8', standalone: true, headless: true }); // Convert HTML nodes to Confluence XHTML format dom.childNodes.forEach(node => { if (node.nodeType === 1) { this.htmlToConfluence(xml, node); } }); const xmlContent = xml.end({ pretty: true }); // this.logger.info('XML result:', xmlContent) return xmlContent; } htmlToConfluence(xml, elem) { const tag = elem.tagName.toLowerCase(); const mapper = this.tagMapper[tag]; if (mapper) { mapper(xml, elem); } else if (elem.childNodes.length > 0) { // Generic handling for unknown tags const generic = xml.ele(tag); elem.childNodes.forEach(child => { if (child.nodeType === 1) { this.htmlToConfluence(generic, child); } else { generic.text(child.rawText); } }); } else { xml.ele(tag).raw(elem.innerHTML); // Fallback to raw HTML } } } exports.HtmlParserService = HtmlParserService; //# sourceMappingURL=html-parser.service.js.map