hxtools/sdevel/man2html

235 lines
4.4 KiB
Perl
Executable File

#!/usr/bin/perl
# SPDX-License-Identifier: MIT
#
# man2html (yet another one)
# written by Jan Engelhardt, 2011
#
# Most of the man2html converters on the net are either totally
# outdated or more complex than I needed.
use Text::CSV_XS;
use strict;
my $csv = Text::CSV_XS->new({eol => $/, sep_char => ' '});
my $mode = 0;
my @index;
while (<>) {
chomp($_);
my($cmd) = split(/\s/, $_);
if ($cmd eq ".\\\"" || $cmd eq ".RS" || $cmd eq ".RE") {
;
} elsif ($cmd eq ".TH") {
header($_);
} elsif ($cmd eq ".SH") {
p_end();
push(@index, [1, substr($_, 4)]);
print "<h1><a name=\"", $#index, "\"></a>",
ehtml(substr($_, 4)), "</h1>\n\n";
} elsif ($cmd eq ".SS") {
p_end();
push(@index, [2, substr($_, 4)]);
print "<h2><a name=\"", $#index, "\"></a>",
ehtml(substr($_, 4)), "</h2>\n\n";
} elsif ($cmd eq ".br") {
print "<br />\n";
} elsif ($_ eq ".B") {
p_start();
chomp(my $text = <>);
print "<b>", ehtml($text), "</b> ";
tp_adv();
} elsif ($cmd eq ".B") {
p_start();
print "<b>", ehtml(stripq(substr($_, 3))), "</b> ";
tp_adv();
} elsif ($cmd eq ".BR") {
p_start();
my(undef, $text1, $text2) = csv_split($_);
print "<b>", ehtml($text1), "</b>", ehtml($text2), " ";
tp_adv();
} elsif ($cmd eq ".BI") {
p_start();
my(undef, $text1, $text2) = csv_split($_);
print "<b>", ehtml($text1), "</b><i>", ehtml($text2), "</i> ";
tp_adv();
} elsif ($cmd eq ".IR") {
p_start();
my(undef, $text1, $text2) = csv_split($_);
print "<i>", ehtml($text1), "</i>", ehtml($text2), " ";
tp_adv();
} elsif ($_ eq ".I") {
p_start();
chomp(my $text = <>);
print "<i>", ehtml($text), "</i> ";
tp_adv();
} elsif ($cmd eq ".I") {
p_start();
print "<i>", ehtml(stripq(substr($_, 3))), "</i> ";
tp_adv();
} elsif ($cmd eq ".P" || $cmd eq ".PP") {
p_end();
pp_start();
} elsif ($cmd eq ".TP") {
p_end();
tp_start();
} elsif ($cmd eq ".IP") {
p_end();
ip_start();
} elsif ($cmd eq ".nf") {
print "<table><tr><td class=\"pre\">";
} elsif ($cmd eq ".fi") {
print "</td></tr></table>";
} elsif ($cmd eq ".ns") {
tp_adv();
} elsif ($_ ne "") {
p_start();
print ehtml($_), "\n";
tp_adv();
} else {
print "<br />\n<br />\n";
}
}
p_end();
if (scalar(@index) > 0) {
my $level = 0;
print "<h1>Index</h1>\n\n";
for (my $idx = 0; $idx <= $#index; ++$idx) {
my $entry = $index[$idx];
if ($level < $entry->[0]) {
print "<ol>\n";
++$level;
} elsif ($level > $entry->[0]) {
print "</ol>\n";
--$level;
}
print "<li><a href=\"#$idx\">", ehtml($entry->[1]),
"</a></li>";
}
print "</ol>\n";
}
print "</body>\n";
print "</html>\n";
sub csv_split
{
my $a = shift @_;
if ($csv->parse($a)) {
return $csv->fields();
}
}
sub p_end
{
if ($mode > 0) {
print "</p>\n\n";
$mode = 0;
}
}
sub p_start
{
if ($mode == 0) {
pp_start();
}
}
sub pp_start
{
if ($mode != 1) {
p_end();
print "<p class=\"pp j\">";
$mode = 1;
}
}
sub tp_start
{
if ($mode != 2) {
p_end();
print "<p class=\"tp1\">";
$mode = 2;
}
}
sub tp_adv
{
if ($mode == 2) {
ip_start();
}
}
sub ip_start
{
if ($mode != 3) {
p_end();
print "<p class=\"tp2 j\">";
$mode = 3;
}
}
sub ehtml
{
my $s = shift @_;
# unman
$s =~ s/\\-/-/gs;
# html
$s =~ s/&/&amp;/gs;
$s =~ s/</&lt;/gs;
$s =~ s/>/&gt;/gs;
if ($_[1]) {
$s =~ s/\"/&quot;/gs;
}
# unman2
$s =~ s{\\fI(.*?)\\f[RP]}{<i>$1</i>}gs;
$s =~ s{\\fB(.*?)\\f[RP]}{<b>$1</b>}gs;
return $s;
}
sub stripq
{
my $s = shift @_;
$s =~ s/^\s+//gs;
$s =~ s/^\"(.*)\"$/$1/gs;
return $s;
}
sub header
{
my(undef, $name, $section, $date, $author, $title) =
csv_split(shift @_);
print "<html>\n";
print "<head>\n";
print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
print "<title>", ehtml($name), "(", ehtml($section), ") - ", ehtml($title), "</title>\n";
print <<EOF;
<style type="text/css">
h1 { font-size: 100%; margin-top: 2em; margin-bottom: 0; }
h2 { font-size: 100%; margin-left: 4ex; margin-top: 2em; margin-bottom: 0; }
p { margin-top: 1ex; margin-bottom: 1ex; }
.j { text-align: justify; }
.pp { margin-left: 8ex; }
.tp1 { margin-left: 12ex; }
.tp2 { margin-left: 16ex; }
.pre { font-family: monospace; }
</style>
</head>
<body>
<table width="98%">
<tr>
EOF
print "\t\t<td>", ehtml($name), "(", ehtml($section), ")</td>\n";
print "\t\t<td align=\"center\">", ehtml($author), "</td>\n\n";
print "\t\t<td>", ehtml($name), "(", ehtml($section), ")</td>\n\n";
print "\t\t</tr>\n</table>\n\n";
}