#!/usr/bin/perl ### ### Quick usage: mdoc2man.pl < mdoc_manpage.8 > doc_manpage.8 ### ### ### Copyright (c) 2001 University of Illinois Board of Trustees ### Copyright (c) 2001 Mark D. Roth ### All rights reserved. ### ### Redistribution and use in source and binary forms, with or without ### modification, are permitted provided that the following conditions ### are met: ### 1. Redistributions of source code must retain the above copyright ### notice, this list of conditions and the following disclaimer. ### 2. Redistributions in binary form must reproduce the above copyright ### notice, this list of conditions and the following disclaimer in the ### documentation and/or other materials provided with the distribution. ### 3. All advertising materials mentioning features or use of this software ### must display the following acknowledgement: ### This product includes software developed by the University of ### Illinois at Urbana, and their contributors. ### 4. The University nor the names of their ### contributors may be used to endorse or promote products derived from ### this software without specific prior written permission. ### ### THIS SOFTWARE IS PROVIDED BY THE TRUSTEES AND CONTRIBUTORS ``AS IS'' AND ### ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ### IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ### ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES OR CONTRIBUTORS BE LIABLE ### FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ### DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ### OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ### HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ### LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ### OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ### SUCH DAMAGE. ### use strict; my ($name, $date, $id); my ($line); my ($optlist, $nospace, $enum, $synopsis); $optlist = 0; ### 1 = bullet, 2 = enum, 3 = tag $nospace = 0; $synopsis = 0; while ($line = ) { if ($line !~ /^\./) { print $line; next; } $line =~ s/^\.//; next if ($line =~ m/\\"/); $line = ParseMacro($line); print($line) if (defined $line); } sub ParseMacro # ($line) { my ($line) = @_; my (@words, $retval, $option, $parens, $arg); @words = split(/\s+/, $line); $retval = ''; $option = 0; $parens = 0; $arg = 0; # print('@words = ', scalar(@words), ': ', join(' ', @words), "\n"); while ($_ = shift @words) { # print "WORD: $_\n"; next if (/^(Li|Pf|X[oc])$/); if (/^Ns/) { $nospace = 1 if (! $nospace); $retval =~ s/ $//; next; } if (/^No/) { $retval =~ s/ $//; $retval .= shift @words; next; } if (/^Dq$/) { $retval .= '``' . (shift @words) . '\'\''; $nospace = 1 if (! $nospace && $words[0] =~ m/^[\.,]/); next; } if (/^(Sq|Ql)$/) { $retval .= '`' . (shift @words) . '\''; $nospace = 1 if (! $nospace && $words[0] =~ m/^[\.,]/); next; } $retval .= ' ' if (! $nospace && $retval ne '' && $retval !~ m/[\n ]$/); $nospace = 0 if ($nospace == 1); if (/^Dd$/) { $date = join(' ', @words); return undef; } if (/^Dt$/) { $id = join(' ', @words); return undef; } if (/^Os$/) { $retval .= '.TH ' . $id . " \"$date\" \"" . join(' ', @words) . "\""; last; } if (/^Sh$/) { $retval .= '.SH'; if ($words[0] eq 'SYNOPSIS') { $synopsis = 1; } else { $synopsis = 0; } next; } if (/^Xr$/) { $retval .= '\\fB' . (shift @words) . '\\fR(' . (shift @words) . ')' . (shift @words); last; } if (/^Nm$/) { $name = shift @words if (@words > 0); $retval .= ".br\n" if ($synopsis); $retval .= "\\fB$name\\fR"; $nospace = 1 if (! $nospace && $words[0] =~ m/^[\.,]/); next; } if (/^Nd$/) { $retval .= '\\-'; next; } if (/^Fl$/) { $retval .= '\\fB\\-' . (shift @words) . '\\fR'; $nospace = 1 if (! $nospace && $words[0] =~ m/^[\.,]/); next; } if (/^Ar$/) { $retval .= '\\fI'; if (! defined $words[0]) { $retval .= 'file ...\\fR'; } $arg = 1; $nospace = 1 if (! $nospace); next; } if (/^Cm$/) { $retval .= '\\fB' . (shift @words) . '\\fR'; next; } if (/^Op$/) { $option = 1; $nospace = 1 if (! $nospace); $retval .= '['; next; } if (/^Oo$/) { $retval .= "[\\c\n"; next; } if (/^Oc$/) { $retval .= ']'; next; } if (/^Pp$/) { if ($optlist) { $retval .= "\n"; } else { $retval .= '.LP'; } next; } if (/^Ss$/) { $retval .= '.SS'; next; } if (/^Pa$/ && ! $option) { $retval .= '\\fI'; $retval .= '\\&' if ($words[0] =~ m/^\./); $retval .= (shift @words) . '\\fR'; $nospace = 1 if (! $nospace && $words[0] =~ m/^[\.,]/); next; } if (/^Dv$/) { $retval .= '.BR'; next; } if (/^(Em|Ev)$/) { $retval .= '.IR'; next; } if (/^Pq$/) { $retval .= '('; $nospace = 1; $parens = 1; next; } if (/^(S[xy])$/) { $retval .= '.B ' . join(' ', @words); last; } if (/^Ic$/) { $retval .= '\\fB'; while (defined $words[0] && $words[0] !~ m/^[\.,]/) { $retval .= shift @words; $retval .= ' ' if (! $nospace); } $retval =~ s/ $//; $retval .= '\\fR'; $retval .= shift @words if (defined $words[0]); last; } if (/^Bl$/) { if ($words[0] eq '-bullet') { $optlist = 1; } elsif ($words[0] eq '-enum') { $optlist = 2; $enum = 0; } elsif ($words[0] eq '-tag') { $optlist = 3; } last; } if (/^El$/) { $optlist = 0; next; } if ($optlist && /^It$/) { if ($optlist == 1) { # bullets $retval .= '.IP \\(bu'; next; } if ($optlist == 2) { # enum $retval .= '.IP ' . (++$enum) . '.'; next; } if ($optlist == 3) { # tags $retval .= ".TP\n"; if ($words[0] =~ m/^(Pa|Ev)$/) { shift @words; $retval .= '.B'; } next; } next; } if (/^Sm$/) { if ($words[0] eq 'off') { $nospace = 2; } elsif ($words[0] eq 'on') { $retval .= "\n"; $nospace = 0; } shift @words; next; } $retval .= "$_"; } return undef if ($retval eq '.'); $retval =~ s/^\.([^a-zA-Z])/$1/; $retval =~ s/ $//; $retval .= ')' if ($parens == 1); $retval .= ']' if ($option == 1); $retval .= '\\fR' if ($arg); $retval .= '\\c' if ($nospace && $retval ne '' && $retval !~ m/\n$/); $retval .= "\n" if ($retval ne '' && $retval !~ m/\n$/); return $retval; }