📄 pod2man.pl
字号:
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u". ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'. ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10'. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m'. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10'.\}. \" troff and (daisy-wheel) nroff accents.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'.ds 8 \h'\*(#H'\(*b\h'-\*(#H'.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#].ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u'.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u'.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#].ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#].ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#].ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#].ds ae a\h'-(\w'a'u*4/10)'e.ds Ae A\h'-(\w'A'u*4/10)'E.ds oe o\h'-(\w'o'u*4/10)'e.ds Oe O\h'-(\w'O'u*4/10)'E. \" corrections for vroff.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'. \" for low resolution devices (crt and lpr).if \n(.H>23 .if \n(.V>19 \\{\. ds : e. ds 8 ss. ds v \h'-1'\o'\(aa\(ga'. ds _ \h'-1'^. ds . \h'-1'.. ds 3 3. ds o a. ds d- d\h'-1'\(ga. ds D- D\h'-1'\(hy. ds th \o'bp'. ds Th \o'LP'. ds ae ae. ds Ae AE. ds oe oe. ds Oe OE.\}.rm #[ #] #H #V #F CEND$indent = 0;$begun = "";# Unrolling [^A-Z>]|[A-Z](?!<) gives: // MRE pp 165.my $nonest = '(?:[^A-Z>]*(?:[A-Z](?!<)[^A-Z>]*)*)';while (<>) { if ($cutting) { next unless /^=/; $cutting = 0; } if ($begun) { if (/^=end\s+$begun/) { $begun = ""; } elsif ($begun =~ /^(roff|man)$/) { print STDOUT $_; } next; } chomp; # Translate verbatim paragraph if (/^\s/) { @lines = split(/\n/); for (@lines) { 1 while s {^( [^\t]* ) \t ( \t* ) } { $1 . ' ' x (8 - (length($1)%8) + 8 * (length($2))) }ex; s/\\/\\e/g; s/\A/\\&/s; } $lines = @lines; makespace() unless $verbatim++; print ".Vb $lines\n"; print join("\n", @lines), "\n"; print ".Ve\n"; $needspace = 0; next; } $verbatim = 0; if (/^=for\s+(\S+)\s*/s) { if ($1 eq "man" or $1 eq "roff") { print STDOUT $',"\n\n"; } else { # ignore unknown for } next; } elsif (/^=begin\s+(\S+)\s*/s) { $begun = $1; if ($1 eq "man" or $1 eq "roff") { print STDOUT $'."\n\n"; } next; } # check for things that'll hosed our noremap scheme; affects $_ init_noremap(); if (!/^=item/) { # trofficate backslashes; must do it before what happens below s/\\/noremap('\\e')/ge; # protect leading periods and quotes against *roff # mistaking them for directives s/^(?:[A-Z]<)?[.']/\\&$&/gm; # first hide the escapes in case we need to # intuit something and get it wrong due to fmting 1 while s/([A-Z]<$nonest>)/noremap($1)/ge; # func() is a reference to a perl function s{ \b ( [:\w]+ \(\) ) } {I<$1>}gx; # func(n) is a reference to a perl function or a man page s{ ([:\w]+) ( \( [^\051]+ \) ) } {I<$1>\\|$2}gx; # convert simple variable references s/(\s+)([\$\@%][\w:]+)(?!\()/${1}C<$2>/g; if (m{ ( [\-\w]+ \( [^\051]*? [\@\$,] [^\051]*? \) ) }x && $` !~ /([LCI]<[^<>]*|-)$/ && !/^=\w/) { warn "$0: bad option in paragraph $. of $ARGV: ``$1'' should be [LCI]<$1>\n"; $oops++; } while (/(-[a-zA-Z])\b/g && $` !~ /[\w\-]$/) { warn "$0: bad option in paragraph $. of $ARGV: ``$1'' should be [CB]<$1>\n"; $oops++; } # put it back so we get the <> processed again; clear_noremap(0); # 0 means leave the E's } else { # trofficate backslashes s/\\/noremap('\\e')/ge; } # need to hide E<> first; they're processed in clear_noremap s/(E<[^<>]+>)/noremap($1)/ge; $maxnest = 10; while ($maxnest-- && /[A-Z]</) { # can't do C font here s/([BI])<($nonest)>/font($1) . $2 . font('R')/eg; # files and filelike refs in italics s/F<($nonest)>/I<$1>/g; # no break -- usually we want C<> for this s/S<($nonest)>/nobreak($1)/eg; # LREF: a la HREF L<show this text|man/section> s:L<([^|>]+)\|[^>]+>:$1:g; # LREF: a manpage(3f) s:L<([a-zA-Z][^\s\/]+)(\([^\)]+\))?>:the I<$1>$2 manpage:g; # LREF: an =item on another manpage s{ L< ([^/]+) / ( [:\w]+ (\(\))? ) > } {the C<$2> entry in the I<$1> manpage}gx; # LREF: an =item on this manpage s{ ((?: L< / ( [:\w]+ (\(\))? ) > (,?\s+(and\s+)?)? )+) } { internal_lrefs($1) }gex; # LREF: a =head2 (head1?), maybe on a manpage, maybe right here # the "func" can disambiguate s{ L< (?: ([a-zA-Z]\S+?) / )? "?(.*?)"? > }{ do { $1 # if no $1, assume it means on this page. ? "the section on I<$2> in the I<$1> manpage" : "the section on I<$2>" } }gesx; # s in case it goes over multiple lines, so . matches \n s/Z<>/\\&/g; # comes last because not subject to reprocessing s/C<($nonest)>/noremap("${CFont_embed}${1}\\fR")/eg; } if (s/^=//) { $needspace = 0; # Assume this. s/\n/ /g; ($Cmd, $_) = split(' ', $_, 2); $dotlevel = 1; if ($Cmd eq 'head1') { $dotlevel = 1; } elsif ($Cmd eq 'head2') { $dotlevel = 1; } elsif ($Cmd eq 'item') { $dotlevel = 2; } if (defined $_) { &escapes($dotlevel); s/"/""/g; } clear_noremap(1); if ($Cmd eq 'cut') { $cutting = 1; } elsif ($Cmd eq 'head1') { s/\s+$//; delete $wanna_see{$_} if exists $wanna_see{$_}; print qq{.SH "$_"\n}; push(@Indices, qq{.IX Header "$_"\n}); } elsif ($Cmd eq 'head2') { print qq{.Sh "$_"\n}; push(@Indices, qq{.IX Subsection "$_"\n}); } elsif ($Cmd eq 'over') { push(@indent,$indent); $indent += ($_ + 0) || 5; } elsif ($Cmd eq 'back') { $indent = pop(@indent); warn "$0: Unmatched =back in paragraph $. of $ARGV\n" unless defined $indent; $needspace = 1; } elsif ($Cmd eq 'item') { s/^\*( |$)/\\(bu$1/g; # if you know how to get ":s please do s/\\\*\(L"([^"]+?)\\\*\(R"/'$1'/g; s/\\\*\(L"([^"]+?)""/'$1'/g; s/[^"]""([^"]+?)""[^"]/'$1'/g; # here do something about the $" in perlvar? print STDOUT qq{.Ip "$_" $indent\n}; push(@Indices, qq{.IX Item "$_"\n}); } elsif ($Cmd eq 'pod') { # this is just a comment } else { warn "$0: Unrecognized pod directive in paragraph $. of $ARGV: $Cmd\n"; } } else { if ($needspace) { &makespace; } &escapes(0); clear_noremap(1); print $_, "\n"; $needspace = 1; }}print <<"END";.rn }` ''ENDif (%wanna_see && !$lax) { @missing = keys %wanna_see; warn "$0: $Filename is missing required section" . (@missing > 1 && "s") . ": @missing\n"; $oops++;}foreach (@Indices) { print "$_\n"; }exit;#exit ($oops != 0);#########################################################################sub nobreak { my $string = shift; $string =~ s/ /\\ /g; $string;}sub escapes { my $indot = shift; s/X<(.*?)>/mkindex($1)/ge; # translate the minus in foo-bar into foo\-bar for roff s/([^0-9a-z-])-([^-])/$1\\-$2/g; # make -- into the string version \*(-- (defined above) s/\b--\b/\\*(--/g; s/"--([^"])/"\\*(--$1/g; # should be a better way s/([^"])--"/$1\\*(--"/g; # fix up quotes; this is somewhat tricky my $dotmacroL = 'L'; my $dotmacroR = 'R'; if ( $indot == 1 ) { $dotmacroL = 'M'; $dotmacroR = 'S'; } elsif ( $indot >= 2 ) { $dotmacroL = 'N'; $dotmacroR = 'T'; } if (!/""/) { s/(^|\s)(['"])/noremap("$1\\*($dotmacroL$2")/ge; s/(['"])($|[\-\s,;\\!?.])/noremap("\\*($dotmacroR$1$2")/ge; } #s/(?!")(?:.)--(?!")(?:.)/\\*(--/g; #s/(?:(?!")(?:.)--(?:"))|(?:(?:")--(?!")(?:.))/\\*(--/g; # make sure that func() keeps a bit a space tween the parens ### s/\b\(\)/\\|()/g; ### s/\b\(\)/(\\|)/g; # make C++ into \*C+, which is a squinched version (defined above) s/\bC\+\+/\\*(C+/g; # make double underbars have a little tiny space between them s/__/_\\|_/g; # PI goes to \*(PI (defined above) s/\bPI\b/noremap('\\*(PI')/ge; # make all caps a teeny bit smaller, but don't muck with embedded code literals my $hidCFont = font('C'); if ($Cmd !~ /^head1/) { # SH already makes smaller # /g isn't enough; 1 while or we'll be off# 1 while s{# (?!$hidCFont)(..|^.|^)# \b# (# [A-Z][\/A-Z+:\-\d_$.]+# )# (s?) # \b# } {$1\\s-1$2\\s0}gmox; 1 while s{ (?!$hidCFont)(..|^.|^) ( \b[A-Z]{2,}[\/A-Z+:\-\d_\$]*\b ) } { $1 . noremap( '\\s-1' . $2 . '\\s0' ) }egmox; }}# make troff just be normal, but make small nroff get quoted# decided to just put the quotes in the text; sigh;sub ccvt { local($_,$prev) = @_; noremap(qq{.CQ "$_" \n\\&});}sub makespace { if ($indent) { print ".Sp\n"; } else { print ".PP\n"; }}sub mkindex { my ($entry) = @_; my @entries = split m:\s*/\s*:, $entry; push @Indices, ".IX Xref " . join ' ', map {qq("$_")} @entries; return '';}sub font { local($font) = shift; return '\\f' . noremap($font);}sub noremap { local($thing_to_hide) = shift; $thing_to_hide =~ tr/\000-\177/\200-\377/; return $thing_to_hide;}sub init_noremap { # escape high bit characters in input stream s/([\200-\377])/"E<".ord($1).">"/ge;}sub clear_noremap { my $ready_to_print = $_[0]; tr/\200-\377/\000-\177/; # trofficate backslashes # s/(?!\\e)(?:..|^.|^)\\/\\e/g; # now for the E<>s, which have been hidden until now # otherwise the interative \w<> processing would have # been hosed by the E<gt> s { E< ( ( \d + ) | ( [A-Za-z]+ ) ) > } { do { defined $2 ? chr($2) : exists $HTML_Escapes{$3} ? do { $HTML_Escapes{$3} } : do { warn "$0: Unknown escape in paragraph $. of $ARGV: ``$&''\n"; "E<$1>"; } } }egx if $ready_to_print;}sub internal_lrefs { local($_) = shift; local $trailing_and = s/and\s+$// ? "and " : ""; s{L</([^>]+)>}{$1}g; my(@items) = split( /(?:,?\s+(?:and\s+)?)/ ); my $retstr = "the "; my $i; for ($i = 0; $i <= $#items; $i++) { $retstr .= "C<$items[$i]>"; $retstr .= ", " if @items > 2 && $i != $#items; $retstr .= " and " if $i+2 == @items; } $retstr .= " entr" . ( @items > 1 ? "ies" : "y" ) . " elsewhere in this document"; # terminal space to avoid words running together (pattern used # strips terminal spaces) $retstr .= " " if length $trailing_and; $retstr .= $trailing_and; return $retstr;}BEGIN {%HTML_Escapes = ( 'amp' => '&', # ampersand 'lt' => '<', # left chevron, less-than 'gt' => '>', # right chevron, greater-than 'quot' => '"', # double quote "Aacute" => "A\\*'", # capital A, acute accent "aacute" => "a\\*'", # small a, acute accent "Acirc" => "A\\*^", # capital A, circumflex accent "acirc" => "a\\*^", # small a, circumflex accent "AElig" => '\*(AE', # capital AE diphthong (ligature) "aelig" => '\*(ae', # small ae diphthong (ligature) "Agrave" => "A\\*`", # capital A, grave accent "agrave" => "A\\*`", # small a, grave accent "Aring" => 'A\\*o', # capital A, ring "aring" => 'a\\*o', # small a, ring "Atilde" => 'A\\*~', # capital A, tilde "atilde" => 'a\\*~', # small a, tilde "Auml" => 'A\\*:', # capital A, dieresis or umlaut mark "auml" => 'a\\*:', # small a, dieresis or umlaut mark "Ccedil" => 'C\\*,', # capital C, cedilla "ccedil" => 'c\\*,', # small c, cedilla "Eacute" => "E\\*'", # capital E, acute accent "eacute" => "e\\*'", # small e, acute accent "Ecirc" => "E\\*^", # capital E, circumflex accent "ecirc" => "e\\*^", # small e, circumflex accent "Egrave" => "E\\*`", # capital E, grave accent "egrave" => "e\\*`", # small e, grave accent "ETH" => '\\*(D-', # capital Eth, Icelandic "eth" => '\\*(d-', # small eth, Icelandic "Euml" => "E\\*:", # capital E, dieresis or umlaut mark "euml" => "e\\*:", # small e, dieresis or umlaut mark "Iacute" => "I\\*'", # capital I, acute accent "iacute" => "i\\*'", # small i, acute accent "Icirc" => "I\\*^", # capital I, circumflex accent "icirc" => "i\\*^", # small i, circumflex accent "Igrave" => "I\\*`", # capital I, grave accent "igrave" => "i\\*`", # small i, grave accent "Iuml" => "I\\*:", # capital I, dieresis or umlaut mark "iuml" => "i\\*:", # small i, dieresis or umlaut mark "Ntilde" => 'N\*~', # capital N, tilde "ntilde" => 'n\*~', # small n, tilde "Oacute" => "O\\*'", # capital O, acute accent "oacute" => "o\\*'", # small o, acute accent "Ocirc" => "O\\*^", # capital O, circumflex accent "ocirc" => "o\\*^", # small o, circumflex accent "Ograve" => "O\\*`", # capital O, grave accent "ograve" => "o\\*`", # small o, grave accent "Oslash" => "O\\*/", # capital O, slash "oslash" => "o\\*/", # small o, slash "Otilde" => "O\\*~", # capital O, tilde "otilde" => "o\\*~", # small o, tilde "Ouml" => "O\\*:", # capital O, dieresis or umlaut mark "ouml" => "o\\*:", # small o, dieresis or umlaut mark "szlig" => '\*8', # small sharp s, German (sz ligature) "THORN" => '\\*(Th', # capital THORN, Icelandic "thorn" => '\\*(th',, # small thorn, Icelandic "Uacute" => "U\\*'", # capital U, acute accent "uacute" => "u\\*'", # small u, acute accent "Ucirc" => "U\\*^", # capital U, circumflex accent "ucirc" => "u\\*^", # small u, circumflex accent "Ugrave" => "U\\*`", # capital U, grave accent "ugrave" => "u\\*`", # small u, grave accent "Uuml" => "U\\*:", # capital U, dieresis or umlaut mark "uuml" => "u\\*:", # small u, dieresis or umlaut mark "Yacute" => "Y\\*'", # capital Y, acute accent "yacute" => "y\\*'", # small y, acute accent "yuml" => "y\\*:", # small y, dieresis or umlaut mark);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -