rust-lang/cargo · error
not implemented
Error message
not implemented
What it means
mdman converts Markdown into man-page (troff) format. When it encounters a footnote definition block (Tag::FootnoteDefinition) in the Markdown event stream, it has no man-page equivalent implemented and calls unimplemented!(), which panics with 'not implemented'. Footnotes have no direct troff/man rendering path in this formatter.
Solutions
- Remove all footnote definitions (`[^id]: ...`) from the Markdown source before passing it to mdman.
- Inline the footnote text as a regular paragraph or a 'Notes' section in the man page source.
- If footnote support is required, implement a troff rendering for Tag::FootnoteDefinition in crates/mdman/src/format/man.rs (e.g. emit an .SH NOTES section) instead of unimplemented!().
Example fix
// before
Tag::FootnoteDefinition(_label) => unimplemented!(),
// after
Tag::FootnoteDefinition(_label) => {
// footnotes are dropped for man output
} Defensive patterns
Strategy: validation
Validate before calling
// Before invoking mdman, scan the source for footnote definitions
let src = std::fs::read_to_string(&md_path)?;
if src.lines().any(|l| l.trim_start().starts_with("[^") && l.contains("]:")) {
anyhow::bail!("source contains footnote definitions unsupported by mdman man output");
} Type guard
null
Try / catch
null
Prevention
- Keep man-page Markdown sources free of footnotes.
- Run mdman on a sanitized copy of docs that strips footnotes.
When it happens
Trigger: Running mdman to generate a man page from a Markdown source that contains a footnote definition, e.g. `[^1]: some text`. The pulldown-cmark parser emits Tag::FootnoteDefinition and the man formatter hits the unimplemented arm.
Common situations: Authors writing CLI tool docs add footnotes for citations/notes; running `mdman --format man` on such a file crashes. Mirrors of upstream docs that use footnotes also trip this.
Related errors
AI-assisted analysis of rust-lang/cargo@eb98b54bc9 (2026-08-11).
Data as JSON: /api/errors/de09039792cfe4dc.
Report an issue: GitHub.
Appendix: source
Thrown at crates/mdman/src/format/man.rs:174
Tag::Item => {
// Note: This uses explicit movement instead of .IP
// because the spacing on .IP looks weird to me.
// space down, indent 4
self.flush();
self.output.push_str(".sp\n.RS 4\n");
match list.last_mut().expect("item must have list start") {
// Ordered list.
Some(n) => {
// move left 4, output the list index number, move right 1.
write!(self.output, "\\h'-04' {}.\\h'+01'", n)?;
*n += 1;
}
// Unordered list.
None => self.output.push_str("\\h'-04'\\(bu\\h'+03'"),
}
suppress_paragraph = true;
}
Tag::FootnoteDefinition(_label) => unimplemented!(),
Tag::Table(alignment) => {
// Table start
// allbox = draw a box around all the cells
// tab(:) = Use `:` to separate cell data (instead of tab)
// ; = end of options
self.output.push_str(
"\n.TS\n\
allbox tab(:);\n",
);
let alignments: Vec<_> = alignment
.iter()
.map(|a| match a {
Alignment::Left | Alignment::None => "lt",
Alignment::Center => "ct",
Alignment::Right => "rt",
})
.collect();
self.output.push_str(&alignments.join(" "));View on GitHub (pinned to eb98b54bc9)