docstring_renderer Rust¶
Docstring rendering for parsed documentation
This module provides rendering functionality for converting ParsedDocstring
structures into formatted Markdown with parameter tables, return sections,
raises tables, and code examples.
Functions¶
fn render_docstring¶
pub
Render a parsed docstring to Markdown.
Produces formatted Markdown with: - Summary and description paragraphs - Parameters table (Name | Type | Description) - Returns section with type and description - Raises table (Exception | Description) - Examples as fenced code blocks Empty sections are omitted entirely.
Examples:
use plissken_core::model::{ParsedDocstring, ParamDoc, ReturnDoc};
use plissken_core::render::render_docstring;
let doc = ParsedDocstring {
summary: Some("Calculate the sum of two numbers.".to_string()),
description: None,
params: vec![
ParamDoc { name: "a".to_string(), ty: Some("int".to_string()), description: "First number".to_string() },
ParamDoc { name: "b".to_string(), ty: Some("int".to_string()), description: "Second number".to_string() },
],
returns: Some(ReturnDoc { ty: Some("int".to_string()), description: "The sum".to_string() }),
raises: vec![],
examples: vec![],
};
let output = render_docstring(&doc);
assert!(output.contains("Calculate the sum"));
assert!(output.contains("| `a` | `int` |"));
Source
pub fn render_docstring(doc: &ParsedDocstring) -> String {
let mut sections = Vec::new();
// Summary
if let Some(ref summary) = doc.summary {
sections.push(summary.clone());
}
// Description (if different from summary)
if let Some(ref description) = doc.description {
sections.push(description.clone());
}
// Parameters table
if !doc.params.is_empty() {
sections.push(render_params_table(&doc.params));
}
// Returns section
if let Some(ref returns) = doc.returns {
sections.push(render_returns(returns));
}
// Raises table
if !doc.raises.is_empty() {
sections.push(render_raises_table(&doc.raises));
}
// Examples
if !doc.examples.is_empty() {
sections.push(render_examples(&doc.examples));
}
sections.join("\n\n")
}
fn render_params_table¶
pub
Render parameters as a Markdown table.
Format:
**Parameters:**
| Name | Type | Description |
|------|------|-------------|
| `param` | `type` | Description text |
Source
pub fn render_params_table(params: &[ParamDoc]) -> String {
let mut output = String::from("**Parameters:**\n\n");
output.push_str("| Name | Type | Description |\n");
output.push_str("|------|------|-------------|\n");
for param in params {
let ty = param.ty.as_deref().unwrap_or("-");
// Escape pipe characters in description for table compatibility
let desc = escape_table_content(¶m.description);
output.push_str(&format!("| `{}` | `{}` | {} |\n", param.name, ty, desc));
}
output
}
fn render_returns¶
pub
Render returns section.
Format:
Source
fn render_raises_table¶
pub
Render raises/exceptions as a Markdown table.
Format:
**Raises:**
| Exception | Description |
|-----------|-------------|
| `ValueError` | When value is invalid |
Source
pub fn render_raises_table(raises: &[RaisesDoc]) -> String {
let mut output = String::from("**Raises:**\n\n");
output.push_str("| Exception | Description |\n");
output.push_str("|-----------|-------------|\n");
for raise in raises {
let desc = escape_table_content(&raise.description);
output.push_str(&format!("| `{}` | {} |\n", raise.ty, desc));
}
output
}
fn render_examples¶
pub
Render examples as fenced code blocks.
Format:
<details>
<summary>Source</summary>
```rust
pub fn render_examples(examples: &[String]) -> String {
let mut output = String::from("**Examples:**\n\n");
for example in examples {
let trimmed = example.trim();
// If example already has code fences, include directly
if trimmed.starts_with("```") {
output.push_str(trimmed);
output.push_str("\n\n");
} else {
// Wrap in code fence with detected language
let lang = detect_example_language(example);
output.push_str(&format!("```{}\n{}\n```\n\n", lang, trimmed));
}
}
output.trim_end().to_string()
}
fn detect_example_language¶
private
Detect the programming language of an example code block.
Source
fn detect_example_language(example: &str) -> &'static str {
let trimmed = example.trim();
// Python indicators
if trimmed.starts_with(">>>")
|| trimmed.starts_with("def ")
|| trimmed.starts_with("class ")
|| trimmed.starts_with("import ")
|| trimmed.starts_with("from ")
|| trimmed.contains("print(")
{
return "python";
}
// Rust indicators
if trimmed.starts_with("fn ")
|| trimmed.starts_with("let ")
|| trimmed.starts_with("use ")
|| trimmed.starts_with("struct ")
|| trimmed.starts_with("impl ")
|| trimmed.contains("println!")
{
return "rust";
}
// Default to python for docstrings
"python"
}
fn escape_table_content¶
private
Escape content for use in Markdown tables.
Pipes need to be escaped and newlines replaced.