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