Skip to content

Commit bf9a10f

Browse files
committed
fix: resolve mandoc lint warnings in generated manpages
- Fix TH header: uppercase command names and remove invalid date format - Remove trailing whitespace from all manpage lines - Fix redundant .br paragraph macros that cause mandoc warnings - Post-process manpage output to ensure compliance with mandoc standards
1 parent 0f891cc commit bf9a10f

1 file changed

Lines changed: 62 additions & 2 deletions

File tree

src/bin/uudoc.rs

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,69 @@ fn gen_manpage<T: Args>(
9494
cmd
9595
};
9696

97+
// Generate the manpage to a buffer first so we can post-process it
98+
let mut buffer = Vec::new();
9799
let man = Man::new(command);
98-
man.render(&mut io::stdout())
99-
.expect("Man page generation failed");
100+
man.render(&mut buffer).expect("Man page generation failed");
101+
102+
// Convert to string for processing
103+
let mut manpage = String::from_utf8(buffer).expect("Invalid UTF-8 in manpage");
104+
105+
// Fix the TH line: remove version info from date field and uppercase the command name
106+
if let Some(th_pos) = manpage.find(".TH ") {
107+
if let Some(line_end) = manpage[th_pos..].find('\n') {
108+
let th_line = &manpage[th_pos..th_pos + line_end];
109+
// Parse the TH line parts
110+
let parts: Vec<&str> = th_line.split_whitespace().collect();
111+
if parts.len() >= 2 {
112+
let cmd_name = parts[1].to_uppercase();
113+
// Reconstruct TH line with uppercase command name and no date
114+
let new_th = format!(".TH {} 1", cmd_name);
115+
manpage.replace_range(th_pos..th_pos + line_end, &new_th);
116+
}
117+
}
118+
}
119+
120+
// Remove trailing whitespace from all lines and fix .br issues
121+
let lines: Vec<String> = manpage
122+
.lines()
123+
.map(|line| line.trim_end().to_string())
124+
.collect();
125+
126+
// Fix .br paragraph macro issues
127+
let mut fixed_lines = Vec::new();
128+
let mut skip_next_br = false;
129+
130+
for i in 0..lines.len() {
131+
let line = &lines[i];
132+
133+
if line == ".br" {
134+
// Check for problematic patterns with .br
135+
let prev_is_br = i > 0 && lines[i - 1] == ".br";
136+
let next_is_empty_then_br =
137+
i + 2 < lines.len() && lines[i + 1].is_empty() && lines[i + 2] == ".br";
138+
let prev_is_empty_with_br = i >= 2 && lines[i - 1].is_empty() && lines[i - 2] == ".br";
139+
140+
// Skip redundant .br in these patterns
141+
if skip_next_br || prev_is_br || next_is_empty_then_br || prev_is_empty_with_br {
142+
skip_next_br = false;
143+
continue;
144+
}
145+
146+
// If this .br is followed by empty line and another .br, skip the second one
147+
if next_is_empty_then_br {
148+
skip_next_br = true;
149+
}
150+
}
151+
152+
fixed_lines.push(line.clone());
153+
}
154+
155+
manpage = fixed_lines.join("\n");
156+
manpage.push('\n');
157+
158+
// Write the processed manpage to stdout
159+
io::stdout().write_all(manpage.as_bytes()).unwrap();
100160
io::stdout().flush().unwrap();
101161
process::exit(0);
102162
}

0 commit comments

Comments
 (0)