Blame autoopts/tpl/mdoc2man.pl

Packit Service 96b5d3
#!/usr/bin/perl
Packit Service 96b5d3
Packit Service 96b5d3
## mdoc2man.pl -- Convert mdoc tags to man tags
Packit Service 96b5d3
##
Packit Service 96b5d3
## Author:	Harlan Stenn <stenn@ntp.org>
Packit Service 96b5d3
##		
Packit Service 96b5d3
##
Packit Service 96b5d3
##  This file is part of AutoOpts, a companion to AutoGen.
Packit Service 96b5d3
##  AutoOpts is free software.
Packit Service 96b5d3
##  AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
Packit Service 96b5d3
##
Packit Service 96b5d3
##  AutoOpts is available under any one of two licenses.  The license
Packit Service 96b5d3
##  in use must be one of these two and the choice is under the control
Packit Service 96b5d3
##  of the user of the license.
Packit Service 96b5d3
##
Packit Service 96b5d3
##   The GNU Lesser General Public License, version 3 or later
Packit Service 96b5d3
##      See the files "COPYING.lgplv3" and "COPYING.gplv3"
Packit Service 96b5d3
##
Packit Service 96b5d3
##   The Modified Berkeley Software Distribution License
Packit Service 96b5d3
##      See the file "COPYING.mbsd"
Packit Service 96b5d3
##
Packit Service 96b5d3
##  These files have the following sha256 sums:
Packit Service 96b5d3
##
Packit Service 96b5d3
##  8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95  COPYING.gplv3
Packit Service 96b5d3
##  4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b  COPYING.lgplv3
Packit Service 96b5d3
##  13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239  COPYING.mbsd
Packit Service 96b5d3
Packit Service 96b5d3
### ToDo
Packit Service 96b5d3
# Properly implement -columns in the "my %lists" definition...
Packit Service 96b5d3
#
Packit Service 96b5d3
# .Xr requires at least 1 arg, the code here expects at least 2
Packit Service 96b5d3
#
Packit Service 96b5d3
###
Packit Service 96b5d3
Packit Service 96b5d3
package mdoc2man;
Packit Service 96b5d3
use strict;
Packit Service 96b5d3
use warnings;
Packit Service 96b5d3
use File::Basename;
Packit Service 96b5d3
use lib dirname(__FILE__);
Packit Service 96b5d3
use Mdoc qw(hs ns pp mapwords son soff stoggle gen_encloser);
Packit Service 96b5d3
Packit Service 96b5d3
########
Packit Service 96b5d3
## Basic
Packit Service 96b5d3
########
Packit Service 96b5d3
Packit Service 96b5d3
Mdoc::def_macro( '.Sh', sub { '.SH', hs, @_ }, raw => 1);
Packit Service 96b5d3
Mdoc::def_macro( '.Ss', sub { '.SS', hs, @_ }, raw => 1);
Packit Service 96b5d3
Mdoc::def_macro( '.Pp', sub { ".sp \\n(Ppu\n.ne 2\n" } );
Packit Service 96b5d3
Mdoc::def_macro( '.Nd', sub { "\\- @_" } );
Packit Service 96b5d3
Packit Service 96b5d3
# Macros that enclose things
Packit Service 96b5d3
Mdoc::def_macro( '.Brq', gen_encloser(qw({ }))          , greedy => 1 );
Packit Service 96b5d3
Mdoc::def_macro( '.Op' , gen_encloser(qw([ ]))          , greedy => 1 );
Packit Service 96b5d3
Mdoc::def_macro( '.Qq' , gen_encloser(qw(" "))          , greedy => 1 );
Packit Service 96b5d3
Mdoc::def_macro( '.Dq' , gen_encloser(qw(\*[Lq] \*[Rq])), greedy => 1 );
Packit Service 96b5d3
Mdoc::def_macro( '.Ql' , gen_encloser(qw(\[oq] \[cq]))  , greedy => 1 );
Packit Service 96b5d3
Mdoc::def_macro( '.Sq' , gen_encloser(qw(\[oq] \[cq]))  , greedy => 1 );
Packit Service 96b5d3
Mdoc::def_macro( '.Pq' , gen_encloser(qw/( )/)          , greedy => 1 );
Packit Service 96b5d3
Mdoc::def_macro( '.D1' , sub { ".in +4\n", ns, @_ , ns , "\n.in -4" } , greedy => 1);
Packit Service 96b5d3
Packit Service 96b5d3
Mdoc::def_macro( 'Oo',  sub { '[', @_ } );
Packit Service 96b5d3
Mdoc::def_macro( 'Oc',  sub { ']', @_ } );
Packit Service 96b5d3
Packit Service 96b5d3
Mdoc::def_macro( 'Po',  sub { '(', @_} );
Packit Service 96b5d3
Mdoc::def_macro( 'Pc',  sub { ')', @_ } );
Packit Service 96b5d3
Packit Service 96b5d3
Mdoc::def_macro( 'Bro', sub { '{', ns, @_ } );
Packit Service 96b5d3
Mdoc::def_macro( 'Brc', sub { '}', @_ } );
Packit Service 96b5d3
Packit Service 96b5d3
Mdoc::def_macro( '.Oo',  gen_encloser(qw([ ])), concat_until => '.Oc' );
Packit Service 96b5d3
Mdoc::def_macro( '.Bro', gen_encloser(qw({ })), concat_until => '.Brc' );
Packit Service 96b5d3
Mdoc::def_macro( '.Po',  gen_encloser(qw/( )/), concat_until => '.Pc' );
Packit Service 96b5d3
Packit Service 96b5d3
Mdoc::def_macro( '.Ev', sub { @_ } );
Packit Service 96b5d3
Mdoc::def_macro( '.An', sub { ".NOP ", @_, "\n.br" }, raw => 1 );
Packit Service 96b5d3
Mdoc::def_macro( '.Li', sub { mapwords {"\\f[C]$_\\f[]"} @_ } );
Packit Service 96b5d3
Mdoc::def_macro( '.Cm', sub { mapwords {"\\f\\*[B-Font]$_\\f[]"} @_ } );
Packit Service 96b5d3
Mdoc::def_macro( '.Ic', sub { mapwords {"\\f\\*[B-Font]$_\\f[]"} @_ } );
Packit Service 96b5d3
Mdoc::def_macro( '.Fl', sub { mapwords {"\\f\\*[B-Font]\\-$_\\f[]"} @_ } );
Packit Service 96b5d3
Mdoc::def_macro( '.Ar', sub { mapwords {"\\f\\*[I-Font]$_\\f[]"} @_ } );
Packit Service 96b5d3
Mdoc::def_macro( '.Em', sub { mapwords {"\\fI$_\\f[]"} @_ } );
Packit Service 96b5d3
Mdoc::def_macro( '.Va', sub { mapwords {"\\fI$_\\f[]"} @_ } );
Packit Service 96b5d3
Mdoc::def_macro( '.Sx', sub { mapwords {"\\fI$_\\f[]"} @_ } );
Packit Service 96b5d3
Mdoc::def_macro( '.Xr', sub { "\\fC".(shift)."\\f[]\\fR(".(shift).")\\f[]", @_ } );
Packit Service 96b5d3
Mdoc::def_macro( '.Fn', sub { "\\f\\*[B-Font]".(shift)."\\f[]\\fR()\\f[]" } );
Packit Service 96b5d3
Mdoc::def_macro( '.Fn', sub { "\\fB".(shift)."\\f[]\\fR()\\f[]" } );
Packit Service 96b5d3
Mdoc::def_macro( '.Fx', sub { "FreeBSD", @_ } );
Packit Service 96b5d3
Mdoc::def_macro( '.Ux', sub { "UNIX", @_ } );
Packit Service 96b5d3
Packit Service 96b5d3
Mdoc::def_macro( '.No', sub { ".NOP", map { ($_, ns) } @_ } );
Packit Service 96b5d3
Mdoc::def_macro( '.Pa', sub { mapwords {"\\fI$_\\f[]"} @_; } );
Packit Service 96b5d3
{
Packit Service 96b5d3
    my $name;
Packit Service 96b5d3
    Mdoc::def_macro('.Nm', sub {
Packit Service 96b5d3
        $name = shift if (!$name);
Packit Service 96b5d3
        "\\f\\*[B-Font]$name\\fP", @_
Packit Service 96b5d3
    } );
Packit Service 96b5d3
}
Packit Service 96b5d3
Packit Service 96b5d3
########
Packit Service 96b5d3
## lists
Packit Service 96b5d3
########
Packit Service 96b5d3
Packit Service 96b5d3
my %lists = (
Packit Service 96b5d3
    bullet => sub {
Packit Service 96b5d3
        Mdoc::def_macro('.It', sub { '.IP \fB\(bu\fP 2' });
Packit Service 96b5d3
    },
Packit Service 96b5d3
Packit Service 96b5d3
    column => sub {
Packit Service 96b5d3
        Mdoc::def_macro('.It', sub { '.IP \fB\(bu\fP 2' });
Packit Service 96b5d3
    },
Packit Service 96b5d3
Packit Service 96b5d3
    tag    => sub {
Packit Service 96b5d3
        my (%opts) = @_;
Packit Service 96b5d3
Packit Service 96b5d3
        my $width = '';
Packit Service 96b5d3
Packit Service 96b5d3
        if (exists $opts{width}) {
Packit Service 96b5d3
            $width = ' '.((length $opts{width})+1);
Packit Service 96b5d3
        }
Packit Service 96b5d3
Packit Service 96b5d3
        if (exists $opts{compact}) {
Packit Service 96b5d3
            my $dobrns = 0;
Packit Service 96b5d3
            Mdoc::def_macro('.It', sub {
Packit Service 96b5d3
                    my @ret = (".TP$width\n.NOP", hs);
Packit Service 96b5d3
                    if ($dobrns) {
Packit Service 96b5d3
                        ".br\n.ns\n", ns, @ret, @_;
Packit Service 96b5d3
                    }
Packit Service 96b5d3
                    else {
Packit Service 96b5d3
                        $dobrns = 1;
Packit Service 96b5d3
                        @ret, @_;
Packit Service 96b5d3
                    }
Packit Service 96b5d3
                }, raw => 1);
Packit Service 96b5d3
        }
Packit Service 96b5d3
        else {
Packit Service 96b5d3
            Mdoc::def_macro('.It', sub {
Packit Service 96b5d3
                    ".TP$width\n.NOP", hs, @_
Packit Service 96b5d3
                }, raw => 1);
Packit Service 96b5d3
        }
Packit Service 96b5d3
    },
Packit Service 96b5d3
);
Packit Service 96b5d3
Packit Service 96b5d3
Mdoc::set_Bl_callback(do { my $nested = 0; sub {
Packit Service 96b5d3
    my $type = shift;
Packit Service 96b5d3
    my %opts = Mdoc::parse_opts(@_);
Packit Service 96b5d3
    if (defined $type && $type =~ /-(\w+)/ && exists $lists{$1}) {
Packit Service 96b5d3
Packit Service 96b5d3
        # Wrap nested lists with .RS and .RE
Packit Service 96b5d3
        Mdoc::set_El_callback(sub { 
Packit Service 96b5d3
                return '.RE' if $nested-- > 1;
Packit Service 96b5d3
                return '.PP';
Packit Service 96b5d3
            });
Packit Service 96b5d3
Packit Service 96b5d3
        $lists{$1}->(%opts);
Packit Service 96b5d3
Packit Service 96b5d3
        if ($nested++) {
Packit Service 96b5d3
            return ".RS";
Packit Service 96b5d3
        }
Packit Service 96b5d3
        else {
Packit Service 96b5d3
            return ();
Packit Service 96b5d3
        }
Packit Service 96b5d3
    }
Packit Service 96b5d3
    else {
Packit Service 96b5d3
        die "Invalid list type <$type>";
Packit Service 96b5d3
    }
Packit Service 96b5d3
}}, raw => 1);
Packit Service 96b5d3
Packit Service 96b5d3
# don't bother with arguments for now and do what mdoc2man'.sh' did
Packit Service 96b5d3
Packit Service 96b5d3
Mdoc::def_macro('.Bd', sub { ".br\n.in +4\n.nf" } );
Packit Service 96b5d3
Mdoc::def_macro('.Ed', sub { ".in -4\n.fi" } );
Packit Service 96b5d3
Packit Service 96b5d3
Mdoc::set_Re_callback(sub { 
Packit Service 96b5d3
        my ($reference) = @_;
Packit Service 96b5d3
        <<"REF";
Packit Service 96b5d3
$reference->{authors},
Packit Service 96b5d3
\\fI$reference->{title}\\fR,
Packit Service 96b5d3
$reference->{optional}\n.PP
Packit Service 96b5d3
REF
Packit Service 96b5d3
});
Packit Service 96b5d3
Packit Service 96b5d3
# Define all macros which have the same sub for inline and standalone macro
Packit Service 96b5d3
for (qw(Xr Em Ar Fl Ic Cm Qq Op Nm Pa Sq Li Va Brq Pq Fx Ux)) {
Packit Service 96b5d3
    my $m = Mdoc::get_macro(".$_");
Packit Service 96b5d3
    Mdoc::def_macro($_, delete $m->{run}, %$m);
Packit Service 96b5d3
}
Packit Service 96b5d3
Packit Service 96b5d3
sub print_line {
Packit Service 96b5d3
    print shift;
Packit Service 96b5d3
    print "\n";
Packit Service 96b5d3
}
Packit Service 96b5d3
Packit Service 96b5d3
sub run {
Packit Service 96b5d3
    print <<'DEFS';
Packit Service 96b5d3
.de1 NOP
Packit Service 96b5d3
.  it 1 an-trap
Packit Service 96b5d3
.  if \\n[.$] \,\\$*\/
Packit Service 96b5d3
..
Packit Service 96b5d3
.ie t \
Packit Service 96b5d3
.ds B-Font [CB]
Packit Service 96b5d3
.ds I-Font [CI]
Packit Service 96b5d3
.ds R-Font [CR]
Packit Service 96b5d3
.el \
Packit Service 96b5d3
.ds B-Font B
Packit Service 96b5d3
.ds I-Font I
Packit Service 96b5d3
.ds R-Font R
Packit Service 96b5d3
DEFS
Packit Service 96b5d3
Packit Service 96b5d3
    while (my ($macro, @args) = Mdoc::parse_line(\*STDIN, \&print_line)) {
Packit Service 96b5d3
        my @ret = Mdoc::call_macro($macro, @args);
Packit Service 96b5d3
        print_line(Mdoc::to_string(@ret)) if @ret;
Packit Service 96b5d3
    }
Packit Service 96b5d3
    return 0;
Packit Service 96b5d3
}
Packit Service 96b5d3
Packit Service 96b5d3
exit run(@ARGV) unless caller;
Packit Service 96b5d3
Packit Service 96b5d3
1;
Packit Service 96b5d3
__END__