diff markdown_converter/markdown_to_html_wasm.js @ 154:bdcc610eeed8

[Markdown Converter][GuiZe] Added markdown coverter in C and wasm rule sets. Needs further view on this as I haven't taken a look. Written by Claude.
author June Park <parkjune1995@gmail.com>
date Mon, 12 Jan 2026 09:11:58 -0800
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/markdown_converter/markdown_to_html_wasm.js	Mon Jan 12 09:11:58 2026 -0800
@@ -0,0 +1,143 @@
+/**
+ * Markdown to HTML Converter - WASM FFI Wrapper
+ * Loads the C implementation via WebAssembly and provides JavaScript API
+ *
+ * Build the WASM with: bazel build //markdown_converter:markdown_to_html_wasm
+ */
+
+class MarkdownConverterWasm {
+  constructor() {
+    this.wasm = undefined;
+    this.ready = false;
+  }
+
+  /**
+   * Initialize the WASM module
+   * @param {string} wasmPath - Path to the .wasm file
+   * @returns {Promise<void>}
+   */
+  async init(wasmPath = '/markdown_to_html_wasm.wasm') {
+    if (this.ready) return;
+
+    try {
+      this.wasm = await WebAssembly.instantiateStreaming(fetch(wasmPath), {
+        env: {}
+      });
+      this.ready = true;
+    } catch (err) {
+      console.error('Failed to load markdown WASM module:', err);
+      throw err;
+    }
+  }
+
+  /**
+   * Write string to WASM memory
+   * @private
+   */
+  _writeString(str) {
+    const encoder = new TextEncoder();
+    const bytes = encoder.encode(str + '\0');
+    const ptr = this.wasm.instance.exports.malloc(bytes.length);
+    const memory = new Uint8Array(this.wasm.instance.exports.memory.buffer);
+    memory.set(bytes, ptr);
+    return ptr;
+  }
+
+  /**
+   * Read string from WASM memory
+   * @private
+   */
+  _readString(ptr) {
+    const memory = new Uint8Array(this.wasm.instance.exports.memory.buffer);
+    let end = ptr;
+    while (memory[end] !== 0) end++;
+    const bytes = memory.slice(ptr, end);
+    const decoder = new TextDecoder();
+    return decoder.decode(bytes);
+  }
+
+  /**
+   * Reset the WASM heap (call between conversions to reclaim memory)
+   */
+  resetHeap() {
+    if (this.ready) {
+      this.wasm.instance.exports.heap_reset();
+    }
+  }
+
+  /**
+   * Convert markdown string to HTML string using WASM
+   * @param {string} markdown - The markdown text to convert
+   * @returns {string} The converted HTML
+   */
+  convert(markdown) {
+    if (!this.ready) {
+      throw new Error('WASM module not initialized. Call init() first.');
+    }
+
+    // Reset heap before each conversion to reclaim memory
+    this.resetHeap();
+
+    // Write markdown to WASM memory
+    const inputPtr = this._writeString(markdown);
+
+    // Call the C function
+    const outputPtr = this.wasm.instance.exports.markdown_to_html(inputPtr);
+
+    // Read the result
+    const html = this._readString(outputPtr);
+
+    return html;
+  }
+
+  /**
+   * Convert markdown to DOM elements (compatible with original API)
+   * @param {string} markdown - The markdown text to convert
+   * @returns {Array<HTMLElement>} Array of DOM elements
+   */
+  convertToElements(markdown) {
+    const html = this.convert(markdown);
+    const template = document.createElement('template');
+    template.innerHTML = html;
+    return Array.from(template.content.children);
+  }
+}
+
+// Singleton instance
+const markdownWasm = new MarkdownConverterWasm();
+
+/**
+ * Convert markdown to DOM elements (WASM version)
+ * Compatible with original markdownConverter() API
+ * @param {string} value - Markdown string
+ * @returns {Promise<Array<HTMLElement>>} Array of DOM elements
+ */
+async function markdownConverterWasm(value) {
+  if (!markdownWasm.ready) {
+    await markdownWasm.init();
+  }
+  return markdownWasm.convertToElements(value);
+}
+
+/**
+ * Render markdown to a container element (WASM version)
+ * Compatible with original renderMarkdown() API
+ * @param {HTMLElement} container - Container element
+ * @param {string} markdown - Markdown string
+ */
+async function renderMarkdownWasm(container, markdown) {
+  if (!markdownWasm.ready) {
+    await markdownWasm.init();
+  }
+  container.innerHTML = markdownWasm.convert(markdown);
+}
+
+// Export for use in other files
+if (typeof module !== 'undefined' && module.exports) {
+  module.exports = {
+    MarkdownConverterWasm,
+    markdownWasm,
+    markdownConverterWasm,
+    renderMarkdownWasm
+  };
+}