diff options
| author | eltrac <hi@eltr.ac> | 2026-09-20 15:55:47 +0800 |
|---|---|---|
| committer | eltrac <hi@eltr.ac> | 2026-09-20 17:15:43 +0800 |
| commit | b85d76db3e17188ee73d5c0455e8b1976ce9a5cc (patch) | |
| tree | a0e6ef3c0a9b64f90249c751de9f4b39adbb8613 | |
| parent | ba6d01449539190c59f4f9793d0ab67dca777a23 (diff) | |
clj: finish clojure wrapper of wasm
add README.md
| -rw-r--r-- | .gitignore | 4 | ||||
| -rw-r--r-- | Makefile | 6 | ||||
| -rw-r--r-- | README.md | 72 | ||||
| -rw-r--r-- | go/Makefile | 2 | ||||
| -rw-r--r-- | project.clj | 10 | ||||
| -rw-r--r-- | src/mf2clj/core.clj | 19 |
6 files changed, 111 insertions, 2 deletions
@@ -1,3 +1,7 @@ /.clj-kondo/.cache/v1 /.lsp/.cache /resources/mf2go.wasm +/.lein-repl-history +/.nrepl-port +/target +/native/ @@ -1,3 +1,9 @@ build-wasm:
@cd go && tinygo build -o ../resources/mf2go.wasm -target wasip1 -buildmode=c-shared main.go
+build-jar:
+ @lein uberjar
+
+build:
+ @make build-wasm
+ @make build-jar
diff --git a/README.md b/README.md new file mode 100644 index 0000000..a00007c --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +# mf2clj
+
+A Clojure library that parses [microformats](http://microformats.org/). Under the hood, it's a thin wrapper of a [Extism](https://extism.org/) plugin written in Go (source of which is also in this repository), and the plugin itself is a wrapper of Will Norris' [microformats parser](https://github.com/willnorris/microformats). *Yes, that's a lot of wrappers! I have a good excuse for that.*
+
+## How It Works
+
+1. `go/main.go` defines `parse()` function, which wraps [microformats.Parse()](https://pkg.go.dev/willnorris.com/go/microformats#Parse) and makes it callable after compiled to WebAssembly.
+2. `src/mf2clj/core.clj` loads compile `mf2go.wasm` from `resources/` and calls `parse`.
+3. User/client calls `mf2clj.core/parse` with no knowledge of the wrappers and WebAssembly.
+
+The code is so simple that you're probably better off copy-pasting it to your codebase directly.
+
+```go
+// go/main.go
+package main
+
+import (
+ "bytes"
+
+ "github.com/extism/go-pdk"
+ "willnorris.com/go/microformats"
+)
+
+//go:wasmexport parse
+func parse() int32 {
+ input := pdk.Input()
+ r := bytes.NewReader(input)
+ data := microformats.Parse(r, nil)
+
+ pdk.OutputJSON(data)
+ return 0
+}
+```
+
+```clojure
+;; src/mf2clj/core.clj
+(ns mf2clj.core
+ (:require [clojure.java.io :as io])
+ (:import [org.extism.sdk.chicory Manifest ManifestWasm Plugin]
+ [java.nio.charset StandardCharsets]))
+
+(defn- manifest-from-wasm [wasm]
+ (Manifest/ofWasms (into-array ManifestWasm [wasm])))
+
+(def plugin
+ (-> "mf2go.wasm" io/resource io/input-stream .readAllBytes
+ ManifestWasm/fromBytes .build
+ manifest-from-wasm .build
+ Plugin/ofManifest .build))
+
+(defn parse [html-string]
+ (let [charset StandardCharsets/UTF_8
+ html-bytes (.getBytes html-string charset)]
+ (String. (.call plugin "parse" html-bytes) charset)))
+```
+
+Seriously, that's all of it.
+
+## *What's your excuse?*
+
+microformats is a very *niche* standard that's only popular*-ish* in the [IndieWeb](https://indieweb.org/) community. Clojure is more niche even within this small community. It makes no sense to develop and maintain a *native* Clojure parser.
+
+Currently, the closest thing available is [this library](https://codeberg.org/alinnow/microformats) by [Alin](https://codeberg.org/alinnow), whose last commit was in 2014. The next best thing would be a Java library since Clojure can call Java code with no problem, but [mf2j](https://github.com/karadaisy/mf2j) hasn't been updated since 2026. Both libraries is **incomplete**.
+
+I see no reason why a new Clojure/Java parser wouldn't be abandoned either.
+
+The [go parser](https://github.com/willnorris/microformats) isn't exactly actively maintained, but at least it's complete and stable. It just makes more sense to use an existing stable library.
+
+Programming languages aren't really a barrier any more. Many languages can compile to WebAssembly and even more can run WebAssembly. So here we are: A Clojure library that runs WebAssembly written in Go under the hood.
+
+I suppose I could use [Rust](https://crates.io/crates/microformats/0.2.0), but it doesn't really make a difference.
+
diff --git a/go/Makefile b/go/Makefile deleted file mode 100644 index 45477be..0000000 --- a/go/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -build-wasm: - @tinygo build -o mf2go.wasm -target wasip1 -buildmode=c-shared main.go diff --git a/project.clj b/project.clj new file mode 100644 index 0000000..0eba58d --- /dev/null +++ b/project.clj @@ -0,0 +1,10 @@ +(defproject mf2clj "v0.0.1"
+ :description "A Clojure wrapper of Will Norris' microformats parser in Go, which runs WebAssembly under the hood."
+ :url "https://src.eltr.ac/eltrac/mf2clj"
+ :min-lein-version "2.0.0"
+ :dependencies [[org.clojure/clojure "1.12.4"]
+ [org.extism.sdk/chicory-sdk-core "0.3.0"]]
+ :profiles {:uberjar {:aot :all}}
+ :license {:name "GNU Affero General Public License"
+ :url "https://www.gnu.org/licenses/agpl-3.0.html"
+ :distribution :repo})
diff --git a/src/mf2clj/core.clj b/src/mf2clj/core.clj new file mode 100644 index 0000000..8d655b1 --- /dev/null +++ b/src/mf2clj/core.clj @@ -0,0 +1,19 @@ +(ns mf2clj.core
+ (:require [clojure.java.io :as io])
+ (:import [org.extism.sdk.chicory Manifest ManifestWasm Plugin]
+ [java.nio.charset StandardCharsets]))
+
+(defn- manifest-from-wasm [wasm]
+ (Manifest/ofWasms (into-array ManifestWasm [wasm])))
+
+(def plugin
+ (-> "mf2go.wasm" io/resource io/input-stream .readAllBytes
+ ManifestWasm/fromBytes .build
+ manifest-from-wasm .build
+ Plugin/ofManifest .build))
+
+(defn parse [html-string]
+ (let [charset StandardCharsets/UTF_8
+ html-bytes (.getBytes html-string charset)]
+ (String. (.call plugin "parse" html-bytes) charset)))
+
|
