github.com/containers/podman/v5@v5.1.0-rc1/hack/man-page-table-check (about) 1 #!/usr/bin/perl 2 # 3 # man-page-table-check - workaround for go-md2man bug that screws up tables 4 # 5 package Podman::ManPage::TableCheck; 6 7 use v5.14; 8 use utf8; 9 10 use strict; 11 use warnings; 12 13 (our $ME = $0) =~ s|.*/||; 14 15 ############################################################################### 16 # BEGIN boilerplate args checking, usage messages 17 18 sub usage { 19 print <<"END_USAGE"; 20 Usage: $ME [OPTIONS] 21 22 $ME checks man pages (the *roff files produced 23 by go-md2man) for empty table cells. Reason: go-md2man cannot handle 24 markdown characters (e.g. asterisk) in tables. It produces horribly 25 broken *roff which in turn makes unreadable man pages. 26 27 If $ME finds broken tables, it will highlight them 28 and display hints on how to resolve the problem. 29 30 OPTIONS: 31 --help display this message 32 END_USAGE 33 34 exit; 35 } 36 37 # Command-line options. Note that this operates directly on @ARGV ! 38 our $debug = 0; 39 our $force = 0; 40 our $verbose = 0; 41 our $NOT = ''; # print "blahing the blah$NOT\n" if $debug 42 sub handle_opts { 43 use Getopt::Long; 44 GetOptions( 45 'debug!' => \$debug, 46 47 help => \&usage, 48 ) or die "Try `$ME --help' for help\n"; 49 } 50 51 # END boilerplate args checking, usage messages 52 ############################################################################### 53 54 ############################## CODE BEGINS HERE ############################### 55 56 # The term is "modulino". 57 __PACKAGE__->main() unless caller(); 58 59 # Main code. 60 sub main { 61 # Note that we operate directly on @ARGV, not on function parameters. 62 # This is deliberate: it's because Getopt::Long only operates on @ARGV 63 # and there's no clean way to make it use @_. 64 handle_opts(); # will set package globals 65 66 die "$ME: Too many arguments; try $ME --help\n" if @ARGV; 67 68 my $manpage_dir = 'docs/build/man'; # FIXME-hardcoding 69 opendir my $dir_fh, $manpage_dir 70 or die "$ME: Cannot opendir $manpage_dir: $!\n"; 71 my @manpages; 72 for my $ent (sort readdir $dir_fh) { 73 next unless $ent =~ /^[a-z].*\.[1-8][a-z]?$/; # groff files only 74 next if -l "$manpage_dir/$ent"; # skip links 75 push @manpages, $ent; 76 } 77 closedir $dir_fh; 78 79 @manpages 80 or die "$ME: did not find any .[1-8] files under $manpage_dir\n"; 81 82 my $errs = 0; 83 for my $file (@manpages) { 84 $errs += check_tables("$manpage_dir/$file"); 85 } 86 exit 0 if !$errs; 87 88 die "\n$ME: found empty cells in the above man page(s) 89 90 This is a bug in go-md2man: it gets really confused when it sees 91 misaligned vertical-bar signs ('|') in tables, or a left-hand 92 column with more than 31 characters. 93 94 WORKAROUND: find the above line(s) in the docs/source/markdown file, 95 then fix the issue (left as exercise for the reader). Keep regenerating 96 docs until it passes: 97 98 \$ make -C docs clean;make docs;$0 99 " 100 } 101 102 103 sub check_tables { 104 my $path = shift; 105 106 my $status = 0; 107 108 my @cmd = ('man', '-l', '--no-hyphenation', '-Tlatin1', '-'); 109 pipe my $fh_read, my $fh_write; 110 my $kidpid = fork; 111 if ($kidpid) { # we are the parent 112 close $fh_write; 113 } 114 elsif (defined $kidpid) { # we are the child 115 close $fh_read; 116 117 open my $fh_in, '<:utf8', $path 118 or die "$ME: Could not read $path: $!\n"; 119 # groff spits out nasty useless warnings 120 close STDERR; 121 open STDOUT, '>&', $fh_write; 122 open my $fh_man, '|-', @cmd 123 or die "$ME: Could not fork: $! (message will never be seen)\n"; 124 125 while (my $line = <$fh_in>) { 126 $line =~ s/✅/OK/g; 127 print { $fh_man } $line; 128 } 129 close $fh_in or die; 130 close $fh_man or die; 131 exit 0; 132 } 133 else { # fork failed 134 die "$ME: could not fork: $!"; 135 } 136 137 my $linecount = 0; 138 my $want = 0; 139 while (my $line = <$fh_read>) { 140 ++$linecount; 141 142 chomp $line; 143 # Table borders (+----------+------------+) 144 if ($line =~ /^\s*\+-+\+-+/) { 145 $want = 1; 146 next; 147 } 148 149 # Row immediately after table borders 150 elsif ($want) { 151 # print $line, "\n"; 152 # *Two* blank cells is OK, go-md2man always does this 153 # on the last row of each table. 154 if ($line !~ /^\s*\|\s+\|\s+\|/) { 155 if ($line =~ /\|\s+\|/) { 156 warn "\n$ME: $path:\n" if $status == 0; 157 warn " $line\n"; 158 $status = 1; 159 } 160 } 161 } 162 $want = 0; 163 } 164 close $fh_read; 165 die "$ME: $path: command failed: @cmd\n" if $?; 166 waitpid $kidpid, 0; 167 168 if ($linecount < 10) { 169 die "$ME: $path: nothing seen!\n"; 170 } 171 172 return $status; 173 } 174 175 176 1;