thesandwi.ch/posthtml-djot/lib/index.js
Isaac Mills cbfa885984
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Migrate to djot
2025-07-16 11:45:32 -06:00

108 lines
2.3 KiB
JavaScript

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