diff --git a/package.json b/package.json index d75d3fa..621c09e 100644 --- a/package.json +++ b/package.json @@ -181,6 +181,11 @@ "title": "Generate MoonBit Bindings", "category": "WIT" }, + { + "command": "wit-idl.generateBindingsMarkdown", + "title": "Generate Markdown Documentation", + "category": "WIT" + }, { "command": "wit-idl.extractWit", "title": "Extract WIT", @@ -271,6 +276,9 @@ }, { "command": "wit-idl.generateBindingsMoonBit" + }, + { + "command": "wit-idl.generateBindingsMarkdown" } ], "commandPalette": [ @@ -308,6 +316,10 @@ "command": "wit-idl.generateBindingsMoonBit", "when": "editorLangId == wit || witIdl.isWasmComponent" }, + { + "command": "wit-idl.generateBindingsMarkdown", + "when": "editorLangId == wit || witIdl.isWasmComponent" + }, { "command": "wit-idl.extractWit", "when": "witIdl.isWasmComponent" diff --git a/src/extension.ts b/src/extension.ts index 1a3c470..9a3fc57 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -670,6 +670,7 @@ export function activate(context: vscode.ExtensionContext) { const generateCSharpBindingsCommand = createGenerateBindingsCommand("csharp", "CSharp"); const generateGoBindingsCommand = createGenerateBindingsCommand("go", "Go"); const generateMoonBitBindingsCommand = createGenerateBindingsCommand("moonbit", "MoonBit"); + const generateMarkdownBindingsCommand = createGenerateBindingsCommand("markdown", "Markdown"); const onSaveListener = vscode.workspace.onDidSaveTextDocument(async (document) => { if (document.languageId === "wit") { @@ -721,6 +722,7 @@ export function activate(context: vscode.ExtensionContext) { generateCSharpBindingsCommand, generateGoBindingsCommand, generateMoonBitBindingsCommand, + generateMarkdownBindingsCommand, wasmToWitProvider, onSaveListener, onOpenListener, diff --git a/wit-bindgen-wasm/Cargo.lock b/wit-bindgen-wasm/Cargo.lock index 757e364..b8d12f7 100644 --- a/wit-bindgen-wasm/Cargo.lock +++ b/wit-bindgen-wasm/Cargo.lock @@ -165,6 +165,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "pulldown-cmark" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" +dependencies = [ + "bitflags", + "memchr", + "unicase", +] + [[package]] name = "quote" version = "1.0.42" @@ -293,6 +304,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + [[package]] name = "unicode-ident" version = "1.0.22" @@ -491,6 +508,18 @@ dependencies = [ "wit-parser", ] +[[package]] +name = "wit-bindgen-markdown" +version = "0.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f314a59c2d84fc97a48f44df445269a5711e3b91711720fedd4c9121c4c7430b" +dependencies = [ + "anyhow", + "heck", + "pulldown-cmark", + "wit-bindgen-core", +] + [[package]] name = "wit-bindgen-moonbit" version = "0.49.0" @@ -534,6 +563,7 @@ dependencies = [ "wit-bindgen-core", "wit-bindgen-cpp", "wit-bindgen-csharp", + "wit-bindgen-markdown", "wit-bindgen-moonbit", "wit-bindgen-rust", "wit-component", diff --git a/wit-bindgen-wasm/Cargo.toml b/wit-bindgen-wasm/Cargo.toml index 9fa82fa..5b89f47 100644 --- a/wit-bindgen-wasm/Cargo.toml +++ b/wit-bindgen-wasm/Cargo.toml @@ -26,6 +26,7 @@ wit-bindgen-cpp = "0.49" wit-bindgen-rust = "0.49" wit-bindgen-csharp = "0.49" wit-bindgen-moonbit = "0.49" +wit-bindgen-markdown = "0.49" wit-component = "0.243" anyhow = "1.0.100" diff --git a/wit-bindgen-wasm/README.md b/wit-bindgen-wasm/README.md index b4b62de..843a455 100644 --- a/wit-bindgen-wasm/README.md +++ b/wit-bindgen-wasm/README.md @@ -62,7 +62,7 @@ main(); - `has_world_definition(content: string): boolean` - Check for world definitions - `version(): string` - Get package version - `generate_bindings(content: string, language: string, world_name?: string): string` - Generate language bindings (returns JSON with file map) - - Supported languages: `rust`, `c`, `cpp` (or `c++`), `csharp` (or `c#`), `go`, `moonbit` + - Supported languages: `rust`, `c`, `cpp` (or `c++`), `csharp` (or `c#`), `go`, `moonbit`, `markdown` (or `md`) ### Binary Safety Contract diff --git a/wit-bindgen-wasm/src/lib.rs b/wit-bindgen-wasm/src/lib.rs index e5aca2a..4ad21f5 100644 --- a/wit-bindgen-wasm/src/lib.rs +++ b/wit-bindgen-wasm/src/lib.rs @@ -13,6 +13,7 @@ use wit_bindgen_c as c; use wit_bindgen_cpp as cpp; use wit_bindgen_csharp as csharp; use wit_bindgen_moonbit as moonbit; +use wit_bindgen_markdown as markdown; // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global // allocator. @@ -231,11 +232,12 @@ impl WitBindgen { "csharp" | "c#" => self.generate_csharp_bindings(content, world_name), "go" => self.generate_go_bindings(content, world_name), "moonbit" => self.generate_moonbit_bindings(content, world_name), + "markdown" | "md" => self.generate_markdown_bindings(content, world_name), _ => { let mut error_files = HashMap::new(); error_files.insert( "error.txt".to_string(), - format!("// Unsupported language: {}\n// Supported languages: rust, c, cpp, csharp, go, moonbit", language) + format!("// Unsupported language: {}\n// Supported languages: rust, c, cpp, csharp, go, moonbit, markdown", language) ); error_files }, @@ -456,6 +458,52 @@ impl WitBindgen { } } + /// Generate Markdown documentation using wit-bindgen-markdown library + fn generate_markdown_bindings(&self, content: &str, world_name: Option) -> HashMap { + match self.generate_markdown_with_wit_bindgen(content, world_name.as_deref()) { + Ok(files) => files, + Err(e) => { + console_error(&format!("wit-bindgen-markdown failed: {}", e)); + let mut error_files = HashMap::new(); + error_files.insert( + "error.txt".to_string(), + format!("Markdown generation failed: {}", e) + ); + error_files + } + } + } + + /// Internal implementation for generating Markdown documentation. + /// + /// This function performs the actual Markdown generation using the wit-bindgen-markdown library. + /// It returns a `Result` containing a map of generated files, or an error if generation fails. + fn generate_markdown_with_wit_bindgen(&self, content: &str, world_name: Option<&str>) -> Result, anyhow::Error> { + let inline_path = Path::new("inline.wit"); + let mut resolve = Resolve::default(); + let package_id = resolve.push_str(inline_path, content) + .with_context(|| "Failed to parse WIT content for Markdown generation")?; + + let world_id = if let Some(world_name) = world_name { + resolve.select_world(&[package_id], Some(world_name))? + } else { + resolve.select_world(&[package_id], None)? + }; + + let opts = markdown::Opts::default(); + let mut generator = opts.build(); + let mut files = Files::default(); + + generator.generate(&resolve, world_id, &mut files)?; + + let mut result = HashMap::new(); + for (filename, content) in files.iter() { + result.insert(filename.to_string(), bytes_to_latin1_string(content)); + } + + Ok(result) + } + /// Generate MoonBit bindings using wit-bindgen-moonbit library fn generate_moonbit_with_wit_bindgen(&self, content: &str, world_name: Option<&str>) -> Result, anyhow::Error> { let inline_path = Path::new("inline.wit");