@@ -30,9 +30,12 @@ include!(concat!(env!("OUT_DIR"), "/uutils_map.rs"));
3030/// Post-process a generated manpage to fix mandoc lint issues
3131///
3232/// This function:
33- /// - Fixes the TH header by uppercasing command names and removing invalid date formats
33+ /// - Fixes the TH header by uppercasing command names and adding a proper date
3434/// - Removes trailing whitespace from all lines
3535/// - Fixes redundant .br paragraph macros that cause mandoc warnings
36+ /// - Removes .br before empty lines to avoid "br before sp" warnings
37+ /// - Removes .br after empty lines to avoid "br after sp" warnings
38+ /// - Fixes escape sequences (e.g., \\\\0 to \\0) to avoid "undefined escape" warnings
3639fn post_process_manpage ( manpage : String ) -> String {
3740 // Only match TH headers that have at least a command name on the same line
3841 // Use [ \t] instead of \s to avoid matching newlines
@@ -58,16 +61,25 @@ fn post_process_manpage(manpage: String) -> String {
5861 let line = lines[ i] . trim_end ( ) ;
5962
6063 if line == ".br" && !skip_indices. contains ( & i) {
61- // Check for consecutive .br macros
62- if i > 0 && lines[ i - 1 ] . trim_end ( ) == ".br" {
64+ // Check for .br followed by empty line
65+ if i + 1 < lines. len ( ) && lines[ i + 1 ] . trim ( ) . is_empty ( ) {
66+ // Remove the .br when it's followed by an empty line
67+ // This prevents "WARNING: skipping paragraph macro: br before sp"
6368 skip_indices. insert ( i) ;
69+
70+ // Also check if there's another .br after the empty line (common pattern)
71+ if i + 2 < lines. len ( ) && lines[ i + 2 ] . trim_end ( ) == ".br" {
72+ skip_indices. insert ( i + 2 ) ;
73+ }
6474 }
65- // Check for .br, empty line, .br pattern
66- else if i + 2 < lines. len ( )
67- && lines[ i + 1 ] . trim ( ) . is_empty ( )
68- && lines[ i + 2 ] . trim_end ( ) == ".br"
69- {
70- skip_indices. insert ( i + 2 ) ;
75+ // Check for .br preceded by empty line (empty line becomes .sp)
76+ // This prevents "WARNING: skipping paragraph macro: br after sp"
77+ else if i > 0 && lines[ i - 1 ] . trim ( ) . is_empty ( ) {
78+ skip_indices. insert ( i) ;
79+ }
80+ // Check for consecutive .br macros
81+ else if i > 0 && lines[ i - 1 ] . trim_end ( ) == ".br" {
82+ skip_indices. insert ( i) ;
7183 }
7284 }
7385 }
@@ -826,4 +838,44 @@ mod tests {
826838 let result4 = post_process_manpage ( input4. to_string ( ) ) ;
827839 assert_eq ! ( result4, expected4) ;
828840 }
841+
842+ #[ test]
843+ fn test_post_process_manpage_removes_br_before_empty_line ( ) {
844+ // Test that .br is removed when followed by empty line (which becomes .sp)
845+ let input = ".TH TEST 1\n Some text\n .br\n \n More text\n " ;
846+ let expected = ".TH TEST 1 \" 2024-01-01\" \n Some text\n \n More text\n " ;
847+
848+ let result = post_process_manpage ( input. to_string ( ) ) ;
849+ assert_eq ! ( result, expected) ;
850+ }
851+
852+ #[ test]
853+ fn test_post_process_manpage_complex_br_before_empty ( ) {
854+ // Test multiple .br before empty line patterns
855+ let input = ".TH TEST 1\n Section 1\n .br\n \n Section 2\n .br\n \n Section 3\n " ;
856+ let expected = ".TH TEST 1 \" 2024-01-01\" \n Section 1\n \n Section 2\n \n Section 3\n " ;
857+
858+ let result = post_process_manpage ( input. to_string ( ) ) ;
859+ assert_eq ! ( result, expected) ;
860+ }
861+
862+ #[ test]
863+ fn test_post_process_manpage_removes_br_after_empty_line ( ) {
864+ // Test that .br is removed when preceded by empty line (which becomes .sp)
865+ let input = ".TH TEST 1\n Some text\n \n .br\n More text\n " ;
866+ let expected = ".TH TEST 1 \" 2024-01-01\" \n Some text\n \n More text\n " ;
867+
868+ let result = post_process_manpage ( input. to_string ( ) ) ;
869+ assert_eq ! ( result, expected) ;
870+ }
871+
872+ #[ test]
873+ fn test_post_process_manpage_fixes_escape_sequences ( ) {
874+ // Test that \\\\0 and \\0 are fixed to \e0 (literal backslash-zero)
875+ let input = ".TH TEST 1\n Text with \\ \\ \\ \\ 0 and \\ \\ 0 escape\n " ;
876+ let expected = ".TH TEST 1 \" 2024-01-01\" \n Text with \\ e0 and \\ e0 escape\n " ;
877+
878+ let result = post_process_manpage ( input. to_string ( ) ) ;
879+ assert_eq ! ( result, expected) ;
880+ }
829881}
0 commit comments