import {render} from 'posthtml-render' import {parser} from 'posthtml-parser' import * as djot from '@djot/djot' import minIndent from 'min-indent' import {resolve} from 'node:path' import {readFileSync} from 'node:fs' import {match} from 'posthtml/lib/api.js' const normalize = data => { const indents = minIndent(data) // Removing indents if (indents !== 0) { const replaceRegex = new RegExp(`^[ \\t]{${indents}}`, 'gm') return data.replace(replaceRegex, '') } return data } const parse = (data, settings, html_settings, hasTag) => { // Parsing content const parsed = djot.renderHTML(djot.parse(data, settings), html_settings) return hasTag ? `\n${parsed}` : parsed } const importDjot = (src, settings) => { const from = resolve(settings.root, src) const content = readFileSync(from, settings.encoding) return normalize(content) } const plugin = options => { const settings = { root: './', encoding: 'utf8', djot: {}, djot_html: {}, ...options } return tree => { tree.match = tree.match || match tree.match([ {tag: 'dj'}, {tag: 'djot'}, {attrs: {dj: ''}}, {attrs: {djot: ''}} ], node => { let content = '' if (['dj', 'djot'].includes(node.tag)) { node.tag = false } if (node.attrs) { // Change tag if (node.attrs.tag) { node.tag = node.attrs.tag delete node.attrs.tag } for (const attribute of ['dj', 'djot']) { if (attribute in node.attrs) { delete node.attrs[attribute] } } // Import djot file if specified const src = node.attrs.src || false if (src) { content += importDjot(src, settings) if (tree.messages) { const from = resolve(settings.root, src) tree.messages.push({ type: 'dependency', file: from }) } delete node.attrs.src } } // Converting content to html tree content += normalize(render(node.content)) // Parsing content const parsed = parse(content, settings.djot, settings.djot_html, node.tag) // Converting tree to html content node.content = parser(parsed) return node }) return tree } } export default plugin