diff --git a/README.md b/README.md index 6c6ab30..bfd1a73 100644 --- a/README.md +++ b/README.md @@ -12,18 +12,9 @@ sxml-loader Scheme XML loader for webpack. -**NOTE**: -At the moment, the _sxml-loader_ only works with -[Chicken Scheme](http://call-cc.org/) and its -[sxml-serializer](http://wiki.call-cc.org/eggref/5/sxml-serializer) -egg, so you need to install them in order to use the _sxml-loader_. - Usage ----- -**SXML**: -```scm -'(h1 "Hello") -``` +_See the full example in the [example](example) directory._ **webpack.config.js**: ```js @@ -41,6 +32,29 @@ module.exports = { } ``` +By default SXML will be processed by _Chicken Scheme_ +with _sxml-serializer_ egg. You can use a different interpreter +by setting the loader options. + +GNU Guile example: +```js +// ... +use: [ + 'html-loader', + { + loader: 'sxml-loader', + options: { + interpreter: 'guile', + flags: ['-c'], // "eval" flag (in Guile case "-c") should be last. + + // SXML_LOADER_CONTENT will be replaced with processing SXML markup. + expr: '(use-modules (sxml simple))(sxml->xml SXML_LOADER_CONTENT)', + }, + }, +], +// ... +``` + License ------- GPLv3 or later. See full text in the [COPYING](COPYING) file diff --git a/src/loader.js b/src/loader.js index 9fadfa6..c0a3914 100644 --- a/src/loader.js +++ b/src/loader.js @@ -1,17 +1,64 @@ // 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: { + interpreter: { + type: 'string', + default: 'chicken-csi', + }, + flags: { + type: 'array', + default: ['-e'], + }, + expr: { + type: 'string', + default: '(import sxml-serializer)(display (serialize-sxml SXML_LOADER_CONTENT))', + }, + }, +}; module.exports = function(content, map, meta) { - const cb = this.async(); - const expr = `(import sxml-serializer)(display (serialize-sxml ${content}))`; - const scheme = spawn('chicken-csi', ['-e', expr]); + const options = this.getOptions(); + validate(schema, options, { + name: 'SXML Loader', + baseDataPath: 'options', + }); + + let interpreter = schema.properties.interpreter.default; + if (options.interpreter) + interpreter = options.interpreter; + + let flags = schema.properties.flags.default; + if (options.flags) + flags = options.flags; - scheme.stdout.on('data', data => { + let expr = schema.properties.expr.default; + if (options.expr) + expr = options.expr; + expr = expr.replace('SXML_LOADER_CONTENT', content); + flags.push(expr); + + const cb = this.async(); + runScheme(interpreter, flags).then(data => { cb(null, data, map, meta); + }).catch(err => { + console.error(err); }); +} + +function runScheme(interpreter, flags) { + return new Promise((resolve, reject) => { + const scheme = spawn(interpreter, flags); - scheme.stderr.on('data', data => { - console.error(data); + scheme.stdout.on('data', (data) => { + resolve(data); + }); + scheme.stderr.on('data', (data) => { + reject(data.toString()); + }); }); }