Skip to content

Commit

Permalink
frontend: add html/js logic of pandoc playground
Browse files Browse the repository at this point in the history
  • Loading branch information
TerrorJack committed Nov 15, 2024
1 parent ca0b0d3 commit 0b0a8be
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 1 deletion.
6 changes: 5 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ jobs:
~/.ghc-wasm/add_to_github_path.sh
popd
- name: checkout
uses: actions/checkout@v4

- name: checkout
uses: actions/checkout@v4
with:
Expand All @@ -57,10 +60,11 @@ jobs:
wasm32-wasi-cabal build pandoc-cli
popd
- name: wasm-opt
- name: dist
run: |
mkdir dist
wasm-opt --low-memory-unused --converge --gufa --flatten --rereloop -Oz $(find pandoc -type f -name pandoc.wasm) -o dist/pandoc.wasm
cp frontend/*.html frontend/*.js dist
- name: test
run: |
Expand Down
92 changes: 92 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>pandoc-wasm playground</title>
<style>
body {
display: flex;
flex-direction: column;
height: 100vh;
margin: 0;
font-family: monospace;
}

#container {
display: flex;
flex: 1;
overflow: hidden;
}

textarea {
width: 50%;
height: 100%;
border: none;
padding: 1rem;
resize: none;
box-sizing: border-box;
font-size: 1rem;
font-family: monospace;
}

#input {
border-right: 1px solid #ccc;
}

#output {
background-color: #f5f5f5;
color: #333;
}

#arguments-container {
padding: 0.5rem;
border-top: 1px solid #ccc;
background-color: #f9f9f9;
}

#arguments {
width: calc(100% - 1rem);
padding: 0.5rem;
font-size: 1rem;
box-sizing: border-box;
font-family: monospace;
}
</style>
</head>
<body>
<div id="container">
<textarea id="input" placeholder="Enter your input here..."></textarea>
<textarea
id="output"
readonly
placeholder="Output will be displayed here..."
></textarea>
</div>
<div id="arguments-container">
<input type="text" id="arguments" value="-f markdown -t rst" />
</div>
<script type="module">
import { run_pandoc } from "./index.js";

async function updateOutput() {
const inputText = document.getElementById("input").value;
const argumentsText = document
.getElementById("arguments")
.value.trim()
.split(" ");
try {
const output = await run_pandoc(argumentsText, inputText);
document.getElementById("output").value = output;
} catch (err) {
document.getElementById("output").value = `Error: ${err.message}`;
}
}

document.getElementById("input").addEventListener("input", updateOutput);
document
.getElementById("arguments")
.addEventListener("input", updateOutput);
</script>
</body>
</html>
62 changes: 62 additions & 0 deletions frontend/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {
WASI,
OpenFile,
File,
ConsoleStdout,
} from "https://cdn.jsdelivr.net/npm/@bjorn3/[email protected]/dist/index.js";

const mod = await WebAssembly.compileStreaming(fetch("./pandoc.wasm"));

const instance_promise_pool_size = 8;

const instance_promise_pool = [];

function instance_promise_pool_fill() {
if (instance_promise_pool.length < instance_promise_pool_size) {
for (
let i = instance_promise_pool.length;
i < instance_promise_pool_size;
++i
) {
const args = [];
const env = [];
const stdin_file = new File(new Uint8Array(), { readonly: true });
const stdout_file = new File(new Uint8Array(), { readonly: false });
const fds = [
new OpenFile(stdin_file),
new OpenFile(stdout_file),
ConsoleStdout.lineBuffered((msg) =>
console.warn(`[WASI stderr] ${msg}`)
),
];
const options = { debug: false };
const wasi = new WASI(args, env, fds, options);
instance_promise_pool.push(
WebAssembly.instantiate(mod, {
wasi_snapshot_preview1: wasi.wasiImport,
}).then((instance) => ({ instance, wasi, stdin_file, stdout_file }))
);
}
}
}

instance_promise_pool_fill();

const instances = (async function* () {
while (true) {
yield await instance_promise_pool.shift();
instance_promise_pool_fill();
}
})();

export async function run_pandoc(args, stdin_str) {
const { instance, wasi, stdin_file, stdout_file } = (await instances.next())
.value;
wasi.args = ["pandoc.wasm", ...args];
stdin_file.data = new TextEncoder().encode(stdin_str);
const ec = wasi.start(instance);
if (ec !== 0) {
throw new Error(`Non-zero exit code ${ec}`);
}
return new TextDecoder("utf-8", { fatal: true }).decode(stdout_file.data);
}

0 comments on commit 0b0a8be

Please sign in to comment.