You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
64 lines
1.8 KiB
64 lines
1.8 KiB
// SPDX-License-Identifier: GPL-3.0-or-later |
|
// Copyright 2022 Ivan Polyakov |
|
|
|
const { spawn } = require('child_process'); |
|
const { validate } = require('schema-utils'); |
|
|
|
const schema = { |
|
type: 'object', |
|
properties: { |
|
expr: { |
|
type: 'string', |
|
default: '(define loader-context \"SXML_LOADER_CONTEXT\")(use-modules (sxml simple))(sxml->xml SXML_LOADER_CONTENT)', |
|
}, |
|
doctype: { |
|
type: 'string', |
|
default: '<!DOCTYPE html>', |
|
}, |
|
afterTranslate: { |
|
instanceOf: 'Function', |
|
}, |
|
}, |
|
}; |
|
|
|
module.exports = function(content, map, meta) { |
|
const options = this.getOptions(); |
|
validate(schema, options, { |
|
name: 'SXML Loader', |
|
baseDataPath: 'options', |
|
}); |
|
|
|
let doctype = schema.properties.doctype.default; |
|
if (options.doctype) |
|
doctype = options.doctype; |
|
|
|
let expr = schema.properties.expr.default; |
|
if (options.expr) |
|
expr = options.expr; |
|
expr = expr.replace('SXML_LOADER_CONTENT', content); |
|
expr = expr.replace('SXML_LOADER_CONTEXT', this.context + '/'); |
|
|
|
const cb = this.async(); |
|
runScheme('guile', ['-c', expr]).then(data => { |
|
let markup = `${doctype}\n${data}`; |
|
if (options.afterTranslate) { |
|
markup = options.afterTranslate(markup); |
|
} |
|
|
|
cb(null, markup, map, meta); |
|
}).catch(code => { |
|
console.error(`Guile exited with code ${code}`); |
|
}); |
|
} |
|
|
|
function runScheme(interpreter, flags) { |
|
return new Promise((resolve, reject) => { |
|
const scheme = spawn(interpreter, flags); |
|
|
|
scheme.stdout.on('data', resolve); |
|
scheme.stderr.on('data', (data) => { |
|
console.error(data.toString()); |
|
}); |
|
scheme.on('exit', reject); |
|
}); |
|
}
|
|
|