#! /usr/bin/perl -w # Script to find the command line options in the Exim spec, and turn them # into a man page, because people like that. ################################################## # De-markup one line # ################################################## sub process { my($x) = $_[0]; # Hide SGCAL escapes $x =~ s/\@\@/&&a/g; # @@ $x =~ s/\@\\/&&b/g; # @\ $x =~ s/\@/&&g/g; # @> $x =~ s/\@\{/&&c/g; # @{ $x =~ s/\@\}/&&d/g; # @} $x =~ s/\@#/&&s/g; # @# $x =~ s/\@(.)/$1/g; # all other @s # Convert SGCAL markup $x =~ s/#/ /g; # turn # into a space $x =~ s/\$~//g; # turn $~ into nothing $x =~ s/__/_/g; # turn __ into _ $x =~ s/\$sc\{([^\}]*?)\}/$1/g; # turn $sc{xxx} into xxx $x =~ s/\$st\{([^\}]*?)\}/$1/g; # turn $st{xxx} into xxx $x =~ s/\$si\{([^\}]*?)\}/$1/g; # turn $si{xxx} into xxx $x =~ s/\$tt\{([^\}]*?)\}/$1/g; # turn $tt{xxx} into xxx $x =~ s/\$it\{([^\}]*?)\}/$1/g; # turn $it{xxx} into xxx $x =~ s/\$bf\{([^\}]*?)\}/$1/g; # turn $bf{xxx} into xxx $x =~ s/\$rm\{([^\}]*?)\}/$1/g; # turn $rm{xxx} into xxx $x =~ s/\$cb\{([^\}]*?)\}/$1/g; # turn $cb{xxx} into xxx $x =~ s/\\\\([^\\]*?)\\\\/\U$1/g; # turn \\xxx\\ into XXX $x =~ s/\\\(([^)]*?)\)\\/$1/g; # turn \(xxx)\ into xxx $x =~ s/\\\"([^\"]*?)\"\\/$1/g; # turn \"xxx"\ into xxx $x =~ s/\\\%([^\%]*?)\%\\/"$1"/g; # turn \%xxx%\ into "xxx" $x =~ s/\\\?([^?]*?)\?\\/$1/g; # turn \?URL?\ into URL $x =~ s/<<([^>]*?)>>/<$1>/g; # turn <> into $x =~ s/\\\$([^\$]*?)\$\\/\$$1/g; # turn \$xxx$\ into $xxx $x =~ s/\\\-([^\\]*?)\-\\/\-$1/g; # turn \-xxx-\ into -xxx $x =~ s/\\\*\*([^*]*?)\*\*\\/$1/g; # turn \**xxx**\ into xxx $x =~ s/\[\(([\w\/]*)\)\]//g; # remove inline HTML $x =~ s/\\\*([^*]*?)\*\\/$1/g; # turn \*xxx*\ into xxx $x =~ s/\\([^\\]*?)\\/"$1"/g; # turn \xxx\ into "xxx" $x =~ s/\$\*\$/\*/g; # turn $*$ into * $x =~ s/\$t\b//g; # turn $t into nothing $x =~ s/::([^:]+)::/$1:/g; # turn ::xxx:: into xxx: # Put back escaped SGCAL specials $x =~ s/&&a/\@/g; # @@ => @ $x =~ s/&&b/\\/g; # @\ => \ $x =~ s/&&l/ < $x =~ s/&&g/>/g; # @> => > $x =~ s/&&c/\@{/g; # @{ => @{ # $x =~ s/&&rc/{/g; # # $x =~ s/&&rd/}/g; # $x =~ s/&&d/\@}/g; # @} => @} $x =~ s/&&s/#/g; # @# # Remove any null flags ($$) $x =~ s/\$\$//g; $x; } ################################################## # De-reference a paragraph # ################################################## # Remove sentences or parenthetical comments that contain references. sub deref { my($t) = $_[0]; $t =~ s/^(\n*)[^.()]+~~[^.]+\.\s*/$1/; $t =~ s/\s?\.[^.()]+~~[^.]+\././g; $t =~ s/\s?\([^~).]+~~[^)]+\)//g; $t; } ################################################## # Quote what needs quoting # ################################################## # This is for anything that must be quoted in the final output, independent # of whether it is in "asis" text or not. sub mustquote { my($t) = $_[0]; $t =~ s/(?exim.8" ) || die "Can't open exim.8\n"; print OUT <) { last if /^\.startoptions/; } die "Can't find start of options\n" if ! defined $_; # Find the start of the first option while () { last if /^\.option/; } die "Can't find start of first option\n" if ! defined $_; # Loop for each individual option while (/^\.option (.*)/) { $nlpending = 0; $itemtext = ""; printf OUT ("\\fB\\-%s\\fR\n", &mustquote(&process($1))); # Process the data for the option while () { last if /^\.(?:option|endoptions)/; next if /^\.index/; next if /^\.em\s*$/; next if /^\.nem\s*$/; if (/^\.display(?:\s+flow)?(?:\s+rm)?\s*$/) { print OUT &mustquote(&deref($itemtext)); $itemtext = ""; print OUT "\n"; while (($_ = ) !~ /^\.endd/) { print OUT " ", &mustquote(&deref(&process($_))) if ! /^\./; } $nlpending = 1; } elsif (/^\.display asis\s*$/) { print OUT &mustquote(&deref($itemtext)); $itemtext = ""; print OUT "\n"; while (($_ = ) !~ /^\.endd/) { print OUT &mustquote(" $_"); } $nlpending = 1; } elsif (/^\s*$/) { print OUT &mustquote(&deref($itemtext)); $itemtext = ""; $nlpending++; } else { while ($nlpending > 0) { $itemtext .= "\n"; $nlpending--; } $itemtext .= &process($_); } } print OUT &mustquote(&deref($itemtext)); print OUT ".TP\n"; } # End of g2man