plissken-core::render::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¶
plissken-core::render::docstring_renderer::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")
}
plissken-core::render::docstring_renderer::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
}
plissken-core::render::docstring_renderer::render_returns¶
pub
Render returns section.
Format:
Source
plissken-core::render::docstring_renderer::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
}
plissken-core::render::docstring_renderer::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 {
// Dedent the example to remove common leading whitespace
let dedented = dedent_code(example);
let trimmed = dedented.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(&dedented);
output.push_str(&format!("```{}\n{}\n```\n\n", lang, trimmed));
}
}
output.trim_end().to_string()
}
plissken-core::render::docstring_renderer::dedent_code¶
private
Remove common leading whitespace from all lines in a code block.
This handles indented docstring examples where all lines have a consistent leading indent that should be removed.
Source
fn dedent_code(code: &str) -> String {
let lines: Vec<&str> = code.lines().collect();
if lines.is_empty() {
return String::new();
}
// Find the minimum indent of non-empty lines
let min_indent = lines
.iter()
.filter(|line| !line.trim().is_empty())
.map(|line| line.len() - line.trim_start().len())
.min()
.unwrap_or(0);
// Remove that many leading spaces from each line
lines
.iter()
.map(|line| {
if line.len() >= min_indent {
&line[min_indent..]
} else {
line.trim_start()
}
})
.collect::<Vec<_>>()
.join("\n")
}
plissken-core::render::docstring_renderer::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"
}
plissken-core::render::docstring_renderer::escape_table_content¶
private
Escape content for use in Markdown tables.
Pipes need to be escaped and newlines replaced.