use std::fmt::Write as _;
use super::super::*;
pub(crate) fn render_module_doc(module: &ModuleDoc) -> String {
let mut doc = frontmatter_with_degradation_and_verify_notes_without_ranges(
&module.module,
"code_module",
&module.source_spans,
&module.degraded_sources,
&module.verify_notes,
);
let _ = writeln!(doc, "# {}\n", module.module);
match parent_module(&module.module) {
Some(parent) => {
let _ = writeln!(doc, "Parent: {}\n", module_wikilink(parent));
}
None => doc.push_str("Parent: [[code/repo|Repository Overview]]\n\n"),
}
write_section(&mut doc, "Overview", &module.summary);
if !module.child_modules.is_empty() {
doc.push_str("## Child Modules\n\n");
write_markdown_table_header(&mut doc, &["Module", "Summary"]);
for child in &module.child_modules {
write_markdown_table_row(
&mut doc,
[
module_wikilink(&child.module),
super::cell_summary(&child.summary),
],
);
}
doc.push('\n');
}
if !module.direct_files.is_empty() {
doc.push_str("## Files\n\n");
write_markdown_table_header(&mut doc, &["File", "Summary"]);
for file in &module.direct_files {
write_markdown_table_row(&mut doc, [file_wikilink(&file.path), file.summary.clone()]);
}
doc.push('\n');
}
doc
}
pub(crate) fn render_file_doc(file: &FileDoc) -> String {
let mut doc = frontmatter_with_degradation_and_verify_notes_without_ranges(
&file.path,
"code_file",
&file.source_spans,
&file.degraded_sources,
&file.verify_notes,
);
let _ = writeln!(doc, "# {}\n", file.path);
if file.module.is_empty() {
doc.push_str("Module: [[code/repo|Repository Overview]]\n\n");
} else {
let _ = writeln!(doc, "Module: {}\n", module_wikilink(&file.module));
}
let body = file.body.trim();
if !body.is_empty() {
doc.push_str(body);
doc.push_str("\n\n");
}
doc.push_str("## Reference\n\n");
let (tests, api): (Vec<&SymbolDoc>, Vec<&SymbolDoc>) =
file.symbols.iter().partition(|symbol| symbol.is_test);
if api.is_empty() {
if tests.is_empty() {
doc.push_str("No indexed symbols.\n");
} else {
push_test_summary_line(&mut doc, tests.len());
}
return doc;
}
write_markdown_table_header(&mut doc, &["Symbol", "Kind", "Purpose"]);
for symbol in api.iter().take(REFERENCE_ROW_CAP) {
let symbol_cell = match &symbol.deprecation {
Some(_) => format!(
"{} ⚠️ **deprecated**",
inline_code(&symbol.symbol.qualified_name)
),
None => inline_code(&symbol.symbol.qualified_name),
};
let purpose_cell = match &symbol.deprecation {
Some(reason) if !reason.is_empty() => {
let reason = neutralize_symbol_purpose_links(reason);
format!(
"⚠️ **deprecated** — {} {}",
reason,
neutralize_symbol_purpose_links(&symbol.purpose)
)
}
Some(_) => format!(
"⚠️ **deprecated** {}",
neutralize_symbol_purpose_links(&symbol.purpose)
),
None => neutralize_symbol_purpose_links(&symbol.purpose),
};
write_markdown_table_row(
&mut doc,
[symbol_cell, symbol.symbol.kind.clone(), purpose_cell],
);
}
doc.push('\n');
if api.len() > REFERENCE_ROW_CAP {
let _ = writeln!(
doc,
"_{} more symbol(s) not shown — run `gcode outline {}` for the full list._\n",
api.len() - REFERENCE_ROW_CAP,
file.path
);
}
if !tests.is_empty() {
push_test_summary_line(&mut doc, tests.len());
}
doc
}
const REFERENCE_ROW_CAP: usize = 24;
fn push_test_summary_line(doc: &mut String, count: usize) {
let plural = if count == 1 { "" } else { "s" };
let _ = writeln!(doc, "_Verified by {count} in-file unit test{plural}._\n");
}