Skip to content

Commit

Permalink
Embed Katex as Wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
bep committed Jul 26, 2024
1 parent 7184214 commit fbea494
Show file tree
Hide file tree
Showing 19 changed files with 15,399 additions and 6 deletions.
24 changes: 24 additions & 0 deletions common/hugio/writers.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,27 @@ func ToReadCloser(r io.Reader) io.ReadCloser {
io.NopCloser(nil),
}
}

// PipeReadWriteCloser is a convenience type to create a pipe with a ReadCloser and a WriteCloser.
type PipeReadWriteCloser struct {
*io.PipeReader
*io.PipeWriter
}

// NewPipeReadWriteCloser creates a new PipeReadWriteCloser.
func NewPipeReadWriteCloser() PipeReadWriteCloser {
pr, pw := io.Pipe()
return PipeReadWriteCloser{pr, pw}
}

func (c PipeReadWriteCloser) Close() (err error) {
if err = c.PipeReader.Close(); err != nil {
return
}
err = c.PipeWriter.Close()
return
}

func (c PipeReadWriteCloser) WriteString(s string) (int, error) {
return c.PipeWriter.Write([]byte(s))
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ require (
github.com/spf13/pflag v1.0.5
github.com/tdewolff/minify/v2 v2.20.36
github.com/tdewolff/parse/v2 v2.7.15
github.com/tetratelabs/wazero v1.7.3
github.com/yuin/goldmark v1.7.4
github.com/yuin/goldmark-emoji v1.0.3
go.uber.org/automaxprocs v1.5.3
Expand Down
8 changes: 2 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,6 @@ github.com/bep/gowebp v0.3.0 h1:MhmMrcf88pUY7/PsEhMgEP0T6fDUnRTMpN8OclDrbrY=
github.com/bep/gowebp v0.3.0/go.mod h1:ZhFodwdiFp8ehGJpF4LdPl6unxZm9lLFjxD3z2h2AgI=
github.com/bep/helpers v0.4.0 h1:ab9veaAiWY4ST48Oxp5usaqivDmYdB744fz+tcZ3Ifs=
github.com/bep/helpers v0.4.0/go.mod h1:/QpHdmcPagDw7+RjkLFCvnlUc8lQ5kg4KDrEkb2Yyco=
github.com/bep/imagemeta v0.7.0 h1:I6Ve/UToNRdnh8qOlpuiR8dX56q6qi97hOqReaMsLMk=
github.com/bep/imagemeta v0.7.0/go.mod h1:5piPAq5Qomh07m/dPPCLN3mDJyFusvUG7VwdRD/vX0s=
github.com/bep/imagemeta v0.7.1 h1:ygl4REZscNxXr+0VjId0ZesLwe80EYGJLrYaevsB++I=
github.com/bep/imagemeta v0.7.1/go.mod h1:5piPAq5Qomh07m/dPPCLN3mDJyFusvUG7VwdRD/vX0s=
github.com/bep/imagemeta v0.7.2 h1:kfyda3+MwOmyXWVujbBubKss44VSPt7NIGgWJU6Jjvg=
github.com/bep/imagemeta v0.7.2/go.mod h1:5piPAq5Qomh07m/dPPCLN3mDJyFusvUG7VwdRD/vX0s=
github.com/bep/imagemeta v0.7.3 h1:tzicJxjBzEa74NP/A2owAidyl4vVoXQYIzUJ9K40mmE=
github.com/bep/imagemeta v0.7.3/go.mod h1:5piPAq5Qomh07m/dPPCLN3mDJyFusvUG7VwdRD/vX0s=
github.com/bep/lazycache v0.4.0 h1:X8yVyWNVupPd4e1jV7efi3zb7ZV/qcjKQgIQ5aPbkYI=
Expand Down Expand Up @@ -448,6 +442,8 @@ github.com/tdewolff/parse/v2 v2.7.15 h1:hysDXtdGZIRF5UZXwpfn3ZWRbm+ru4l53/ajBRGp
github.com/tdewolff/parse/v2 v2.7.15/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA=
github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo=
github.com/tetratelabs/wazero v1.7.3 h1:PBH5KVahrt3S2AHgEjKu4u+LlDbbk+nsGE3KLucy6Rw=
github.com/tetratelabs/wazero v1.7.3/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
4 changes: 4 additions & 0 deletions internal/ext/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
go generate ./gen
javy compile js/greet.bundle.js -d -o wasm/greet.wasm
javy compile js/renderkatex.bundle.js -d -o wasm/renderkatex.wasm
touch wasm_test.go
51 changes: 51 additions & 0 deletions internal/ext/gen/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//go:generate go run main.go
package main

import (
"fmt"
"log"
"os"
"path/filepath"
"strings"

"github.com/evanw/esbuild/pkg/api"
)

var scripts = []string{
"greet.js",
"renderkatex.js",
}

func main() {
for _, script := range scripts {
filename := filepath.Join("../js", script)
err := buildJSBundle(filename)
if err != nil {
log.Fatal(err)
}
}
}

func buildJSBundle(filename string) error {
result := api.Build(
api.BuildOptions{
EntryPoints: []string{filename},
Bundle: true,
Target: api.ES2020,
Outfile: strings.Replace(filename, ".js", ".bundle.js", 1),
SourceRoot: "../js",
})

if len(result.Errors) > 0 {
return fmt.Errorf("build failed: %v", result.Errors)
}
if len(result.OutputFiles) != 1 {
return fmt.Errorf("expected 1 output file, got %d", len(result.OutputFiles))
}

of := result.OutputFiles[0]
if err := os.WriteFile(filepath.FromSlash(of.Path), of.Contents, 0o644); err != nil {
return fmt.Errorf("write file failed: %v", err)
}
return nil
}
2 changes: 2 additions & 0 deletions internal/ext/js/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
package-lock.json
56 changes: 56 additions & 0 deletions internal/ext/js/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Read JSONL from stdin.
export function readInput(handle) {
const buffSize = 1024;
let currentLine = [];
const buffer = new Uint8Array(buffSize);

// Read all the available bytes
while (true) {
// Stdin file descriptor
const fd = 0;
let bytesRead = 0;
try {
bytesRead = Javy.IO.readSync(fd, buffer);
} catch (e) {
// IO.readSync fails with os error 29 when stdin closes.
if (e.message.includes('os error 29')) {
break;
}
throw new Error('Error reading from stdin');
}

if (bytesRead < 0) {
throw new Error('Error reading from stdin');
break;
}

if (bytesRead === 0) {
break;
}

currentLine = [...currentLine, ...buffer.subarray(0, bytesRead)];

// Split array into chunks by newline.
let i = 0;
for (let j = 0; i < currentLine.length; i++) {
if (currentLine[i] === 10) {
const chunk = currentLine.splice(j, i + 1);
const arr = new Uint8Array(chunk);
const json = JSON.parse(new TextDecoder().decode(arr));
handle(json);
j = i + 1;
}
}
// Remove processed data.
currentLine = currentLine.slice(i);
}
}

// Write JSONL to stdout
export function writeOutput(output) {
const encodedOutput = new TextEncoder().encode(JSON.stringify(output) + '\n');
const buffer = new Uint8Array(encodedOutput);
// Stdout file descriptor
const fd = 1;
Javy.IO.writeSync(fd, buffer);
}
51 changes: 51 additions & 0 deletions internal/ext/js/greet.bundle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
(() => {
// ../js/common.js
function readInput(handle) {
const buffSize = 1024;
let currentLine = [];
const buffer = new Uint8Array(buffSize);
while (true) {
const fd = 0;
let bytesRead = 0;
try {
bytesRead = Javy.IO.readSync(fd, buffer);
} catch (e) {
if (e.message.includes("os error 29")) {
break;
}
throw new Error("Error reading from stdin");
}
if (bytesRead < 0) {
throw new Error("Error reading from stdin");
break;
}
if (bytesRead === 0) {
break;
}
currentLine = [...currentLine, ...buffer.subarray(0, bytesRead)];
let i = 0;
for (let j = 0; i < currentLine.length; i++) {
if (currentLine[i] === 10) {
const chunk = currentLine.splice(j, i + 1);
const arr = new Uint8Array(chunk);
const json = JSON.parse(new TextDecoder().decode(arr));
handle(json);
j = i + 1;
}
}
currentLine = currentLine.slice(i);
}
}
function writeOutput(output) {
const encodedOutput = new TextEncoder().encode(JSON.stringify(output) + "\n");
const buffer = new Uint8Array(encodedOutput);
const fd = 1;
Javy.IO.writeSync(fd, buffer);
}

// ../js/greet.js
var greet = function(input) {
writeOutput({ id: input.id, greeting: "Hello " + input.name + "!" });
};
readInput(greet);
})();
7 changes: 7 additions & 0 deletions internal/ext/js/greet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { readInput, writeOutput } from './common';

const greet = function (input) {
writeOutput({ id: input.id, greeting: 'Hello ' + input.name + '!' });
};

readInput(greet);
14 changes: 14 additions & 0 deletions internal/ext/js/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "js",
"version": "1.0.0",
"main": "greet.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"katex": "^0.16.11"
}
}
Loading

0 comments on commit fbea494

Please sign in to comment.