Skip to content

Commit

Permalink
Add QuickJS support
Browse files Browse the repository at this point in the history
  • Loading branch information
yne committed Jun 16, 2024
1 parent d333b7b commit cf2f66f
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 4 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING-CODE.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Next, run npm's `install` command:

You're now ready to build Asciidoctor.js.

TIP: Opal.js, the Ruby runtime in JavaScript is available in `packages/core/node_modules/asciidoctor-opal-runtime/src/opal.js`
TIP: Opal.js, the Ruby runtime in JavaScript is available in `packages/core/node_modules/@asciidoctor/opal-runtime/src/opal.js`

== Building

Expand Down
4 changes: 4 additions & 0 deletions docs/modules/setup/pages/runtime.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
:uri-spidermonkey-read: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Introduction_to_the_JavaScript_shell#Built-in_functions
:uri-phantomjs-read: http://phantomjs.org/api/fs/method/read.html
:uri-node-fs: https://nodejs.org/api/fs.html
:uri-quickjs-read: https://bellard.org/quickjs/

:uri-v8: https://developers.google.com/v8
:uri-graalvm: https://www.graalvm.org
Expand Down Expand Up @@ -89,6 +90,9 @@ The implementation will use the {uri-spidermonkey-read}[`read` function].
`phantomjs`::
The implementation will use the {uri-phantomjs-read}[`fs.read` function].

`quickjs`::
The implementation will use the {uri-quickjs-read}[`std.loadFile` module].

== Retrieve the runtime environment

Once Asciidoctor.js is instantiated, you can retrieve the runtime environment with the `getRuntime` function:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# TODO: add QuickJS-specific class override here
21 changes: 21 additions & 0 deletions packages/core/lib/asciidoctor/js/opal_ext/quickjs.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
%x(
var platform, engine, framework, ioModule;
if (typeof moduleConfig === 'object' && typeof moduleConfig.runtime === 'object') {
var runtime = moduleConfig.runtime;
platform = runtime.platform;
engine = runtime.engine;
framework = runtime.framework;
ioModule = runtime.ioModule;
}
ioModule = ioModule || 'quickjs';
platform = platform || 'quickjs';
engine = engine || '';
framework = framework || '')

JAVASCRIPT_IO_MODULE = %x(ioModule)
JAVASCRIPT_PLATFORM = %x(platform)
JAVASCRIPT_ENGINE = %x(engine)
JAVASCRIPT_FRAMEWORK = %x(framework)

require 'asciidoctor/js/opal_ext/quickjs/file'
13 changes: 13 additions & 0 deletions packages/core/lib/asciidoctor/js/opal_ext/quickjs/file.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class File

def self.read(path)
%x{
const body = std.loadFile(path);
if (body === null) {
console.log(`unable to loadFile:"${path}" from:"${os.getcwd()[0]}" realpath:"${os.realpath(path)[0]}"`);
}
return body || '';
}
end

end
13 changes: 12 additions & 1 deletion packages/core/lib/asciidoctor/js/opal_ext/umd.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
var isNode = typeof process === 'object' && typeof process.versions === 'object' && process.browser != true,
isElectron = typeof navigator === 'object' && typeof navigator.userAgent === 'string' && typeof navigator.userAgent.indexOf('Electron') !== -1,
isBrowser = typeof window === 'object',
isQuickjs = typeof std === 'object',
isGraalVM = typeof Polyglot === 'object' && Polyglot.import,
isPhantomJS = typeof window === 'object' && typeof window.phantom === 'object',
isWebWorker = typeof importScripts === 'function',
Expand Down Expand Up @@ -36,6 +37,10 @@
platform = platform || 'standalone';
framework = framework || 'spidermonkey';
}
else if (isQuickjs) {
platform = platform || 'browser';
framework = framework || 'quickjs';
}
else if (isBrowser) {
platform = platform || 'browser';
if (isPhantomJS) {
Expand Down Expand Up @@ -65,15 +70,18 @@
if (ioModule !== 'spidermonkey'
&& ioModule !== 'phantomjs'
&& ioModule !== 'node'
&& ioModule !== 'quickjs'
&& ioModule !== 'graalvm'
&& ioModule !== 'xmlhttprequest') {
throw new Error('Invalid IO module, `config.ioModule` must be one of: spidermonkey, phantomjs, node, graalvm or xmlhttprequest');
throw new Error('Invalid IO module, `config.ioModule` must be one of: spidermonkey, quickjs, phantomjs, node, graalvm or xmlhttprequest');
}
} else {
if (framework === 'spidermonkey') {
ioModule = 'spidermonkey';
} else if (framework === 'phantomjs') {
ioModule = 'phantomjs';
} else if (framework === 'quickjs') {
ioModule = 'quickjs';
} else if (platform === 'node') {
ioModule = 'node';
} else if (engine === 'graalvm') {
Expand Down Expand Up @@ -107,6 +115,9 @@
if JAVASCRIPT_IO_MODULE == 'spidermonkey'
require 'asciidoctor/js/opal_ext/spidermonkey/file'
end
if JAVASCRIPT_IO_MODULE == 'quickjs'
require 'asciidoctor/js/opal_ext/quickjs/file'
end
if JAVASCRIPT_IO_MODULE == 'xmlhttprequest'
require 'asciidoctor/js/opal_ext/browser/file'
end
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"test:node": "mocha spec/*/*.spec.cjs && npm run test:node:esm",
"test:node:esm": "mocha --experimental-json-modules spec/node/asciidoctor.spec.js",
"test:browser": "node spec/browser/run.cjs",
"test:quickjs": "qjs --unhandled-rejection spec/quickjs/run.mjs",
"test:types": "rm -f types/tests.js && eslint types --ext .ts && tsc --build types/tsconfig.json && node --input-type=commonjs types/tests.js",
"test": "node tasks/test/unsupported-features.cjs && npm run test:node && npm run test:browser && npm run test:types",
"build": "node tasks/build.cjs && npm run test && npm run lint",
Expand Down
18 changes: 18 additions & 0 deletions packages/core/spec/quickjs/run.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* global Asciidoctor */
import Asciidoctor from '../../build/asciidoctor-quickjs.js'
const asciidoctor = Asciidoctor()

const data = '= asciidoctor.js, AsciiDoc in JavaScript\n' +
'Doc Writer <docwriter@example.com>\n\n' +
'Asciidoctor and Opal come together to bring\n' +
'http://asciidoc.org[AsciiDoc] to the browser!.\n\n' +
'== Technologies\n\n' +
'* AsciiDoc\n' +
'* Asciidoctor\n' +
'* Opal\n\n' +
'NOTE: That\'s all she wrote!!!\n\n' +
'include::spec/fixtures/include.adoc[]'

const options = { safe: 0, header_footer: true, attributes: { stylesheet: "spec/fixtures/css/simple.css", showtitle: true } }
const html = asciidoctor.convert(data, options)
console.log(html)
33 changes: 33 additions & 0 deletions packages/core/src/template-asciidoctor-quickjs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* global Asciidoctor, ASCIIDOCTOR_JS_VERSION */
import * as std from 'std';
import * as os from 'os';

//{{opalCode}}

const __path__ = {
separator: os.platform == "win32" ? '\\' : '/',
split(path) { return path.split(this.separator); },
join(compo) { return compo.join(this.separator); },
basename(path) { return this.join(this.split(path).slice(0,-1)); },
dirname(path) { return this.split(path).pop(); },
};
const __asciidoctorDistDir__ = os.realpath(scriptArgs[0])[0].match(os.platform == "win32" ? /.*\\/ : /.*\//);

export default function (moduleConfig) {
//{{asciidoctorCode}}

//{{asciidoctorAPI}}

//{{asciidoctorVersion}}

/**
* Get Asciidoctor.js version number.
*
* @memberof Asciidoctor
* @returns {string} - returns the version number of Asciidoctor.js.
*/
Asciidoctor.prototype.getVersion = function () {
return ASCIIDOCTOR_JS_VERSION
}
return Opal.Asciidoctor
}
6 changes: 4 additions & 2 deletions packages/core/tasks/module/builder.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ const generateFlavors = async (asciidoctorCoreTarget, environments) => {
const opalExtData = fs.readFileSync(`build/opal-ext-${environment}.js`, 'utf8')
const asciidoctorCoreData = fs.readFileSync(asciidoctorCoreTarget, 'utf8')
let data
if (['node', 'browser'].includes(environment)) {
if (['node', 'browser', 'quickjs'].includes(environment)) {
const asciidoctorExtData = fs.readFileSync(`build/asciidoctor-ext-${environment}.js`, 'utf8')
data = opalExtData.concat('\n').concat(asciidoctorExtData).concat('\n').concat(asciidoctorCoreData)
} else {
Expand All @@ -150,6 +150,8 @@ const generateFlavors = async (asciidoctorCoreTarget, environments) => {
const target = `build/asciidoctor-${environment}.js`
if (environment === 'node') {
templateFile = 'src/template-asciidoctor-node.js'
} else if (environment === 'quickjs') {
templateFile = 'src/template-asciidoctor-quickjs.js'
} else {
templateFile = 'src/template-asciidoctor-browser.js'
}
Expand Down Expand Up @@ -216,7 +218,7 @@ module.exports = class Builder {
this.benchmarkBuildDir = path.join('build', 'benchmark')
this.examplesBuildDir = path.join('build', 'examples')
this.asciidocRepoBaseURI = 'https://raw.githubusercontent.com/asciidoc/asciidoc/d43faae38c4a8bf366dcba545971da99f2b2d625'
this.environments = ['node', 'graalvm', 'browser']
this.environments = ['node', 'graalvm', 'browser', 'quickjs']
this.asciidoctorCoreTarget = path.join('build', 'asciidoctor-core.js')
}

Expand Down

0 comments on commit cf2f66f

Please sign in to comment.