Doc2MD
Convert PDF, Office, legacy Office, or RTF input into Markdown, with optional image extraction
Run
wippy run kickside/doc2mdDoc2MD
Doc2MD is a Wippy library module that converts documents to Markdown through a Rust WebAssembly component.
It supports PDF, modern Office files (.docx, .xlsx, .pptx), legacy Office
files (.doc, .xls, .ppt), and RTF. Image extraction is opt-in, so the
default result is text-focused Markdown close to classic document-to-markdown
converters.
Public API
Import the Lua SDK from the public module entry:
imports:
kickside.convert.doc2md: kickside.convert.doc2md:doc2md
Convert raw bytes:
local doc2md = require("doc2md")
local document, err = doc2md.convert({
bytes = uploaded_bytes,
})
if err ~= nil then
return nil, err
end
return document.markdown
Convert a URL:
local document, err = doc2md.convert({
url = "https://example.com/report.pdf",
})
Enable image extraction explicitly (a second options argument):
local document, err = doc2md.convert({ bytes = uploaded_bytes }, {
extract_images = true,
})
Request and options
doc2md.convert(request [, options]):
request— a table with exactly one source:bytes: non-empty Lua binary string with the document content, orurl: HTTP(S) URL to download.
options— an optional table (unknown keys are rejected):extract_images: optional boolean, defaultfalse.
doc2md.new(runtime) builds an instance with injected runtime dependencies
({ funcs?, http_client? }) for tests or a custom HTTP client. See
RFC 0001.
Errors
Invalid input and conversion failures return nil, err where err is a
structured table with message, kind, and retryable. kind is one of
invalid_input, download_failed, decode_failed, internal. tostring(err)
and string concatenation yield the message. Inputs are capped at 128 MiB; URL
fetches are http(s)-only with a 30s timeout, a size cap, and runtime private-IP
blocking.
Response
Successful conversions return:
{
markdown = "# Converted markdown",
images = {
{
name = "image1.png",
data = raw_image_bytes,
},
},
}
images is always a table. It is empty when extract_images is false or when
the document has no extractable images. Image data is returned as raw binary Lua
strings, not base64.
Module Surface
The published doc2md namespace contains only the production entries:
kickside.convert.doc2md:doc2md: Lua SDK.kickside.convert.doc2md:converter: WebAssembly converter function.kickside.convert.doc2md:assets: embedded filesystem fordoc2md.wasm.
Tests, fixtures, and load harnesses live under app.env:**. That namespace is
excluded by wippy.yaml, so sample documents are not part of the published
package.
Development
make install
make build-component
make lint
make test
make load-test
make build-component requires the Rust toolchain with the wasm32-wasip2
target. make load-test runs excluded local validation entries and does not
change the publish surface.
Publish
Validate the exact publish path without uploading:
make publish-dry-run
Publish as a Wippy library module:
make publish
Those targets call wippy publish with --module-type library so first-time
registration does not create the module as an application.
License
MIT.