xref: /freebsd/contrib/ntp/sntp/ag-tpl/0-old/mdoc2man (revision 2b15cb3d)
1*2b15cb3dSCy Schubert#!/usr/bin/perl
2*2b15cb3dSCy Schubert
3*2b15cb3dSCy Schubert### ToDo
4*2b15cb3dSCy Schubert# Properly implement -columns in the "my %lists" definition...
5*2b15cb3dSCy Schubert#
6*2b15cb3dSCy Schubert# .Xr requires at least 1 arg, the code here expects at least 2
7*2b15cb3dSCy Schubert###
8*2b15cb3dSCy Schubert
9*2b15cb3dSCy Schubertpackage mdoc2man;
10*2b15cb3dSCy Schubertuse strict;
11*2b15cb3dSCy Schubertuse warnings;
12*2b15cb3dSCy Schubertuse File::Basename;
13*2b15cb3dSCy Schubertuse lib dirname(__FILE__);
14*2b15cb3dSCy Schubertuse Mdoc qw(hs ns pp mapwords son soff stoggle gen_encloser);
15*2b15cb3dSCy Schubert
16*2b15cb3dSCy Schubert########
17*2b15cb3dSCy Schubert## Basic
18*2b15cb3dSCy Schubert########
19*2b15cb3dSCy Schubert
20*2b15cb3dSCy SchubertMdoc::def_macro( '.Sh', sub { '.SH', hs, @_ }, raw => 1);
21*2b15cb3dSCy SchubertMdoc::def_macro( '.Ss', sub { '.SS', hs, @_ }, raw => 1);
22*2b15cb3dSCy SchubertMdoc::def_macro( '.Pp', sub { ".sp \\n(Ppu\n.ne 2\n" } );
23*2b15cb3dSCy SchubertMdoc::def_macro( '.Nd', sub { "\\- @_" } );
24*2b15cb3dSCy Schubert
25*2b15cb3dSCy Schubert# Macros that enclose things
26*2b15cb3dSCy SchubertMdoc::def_macro( '.Brq', gen_encloser(qw({ }))          , greedy => 1 );
27*2b15cb3dSCy SchubertMdoc::def_macro( '.Op' , gen_encloser(qw([ ]))          , greedy => 1 );
28*2b15cb3dSCy SchubertMdoc::def_macro( '.Qq' , gen_encloser(qw(" "))          , greedy => 1 );
29*2b15cb3dSCy SchubertMdoc::def_macro( '.Dq' , gen_encloser(qw(\*[Lq] \*[Rq])), greedy => 1 );
30*2b15cb3dSCy SchubertMdoc::def_macro( '.Ql' , gen_encloser(qw(\[oq] \[cq]))  , greedy => 1 );
31*2b15cb3dSCy SchubertMdoc::def_macro( '.Sq' , gen_encloser(qw(\[oq] \[cq]))  , greedy => 1 );
32*2b15cb3dSCy SchubertMdoc::def_macro( '.Pq' , gen_encloser(qw/( )/)          , greedy => 1 );
33*2b15cb3dSCy SchubertMdoc::def_macro( '.D1' , sub { ".in +4\n", ns, @_ , ns , "\n.in -4" } , greedy => 1);
34*2b15cb3dSCy Schubert
35*2b15cb3dSCy SchubertMdoc::def_macro( 'Oo',  sub { '[', @_ } );
36*2b15cb3dSCy SchubertMdoc::def_macro( 'Oc',  sub { ']', @_ } );
37*2b15cb3dSCy Schubert
38*2b15cb3dSCy SchubertMdoc::def_macro( 'Po',  sub { '(', @_} );
39*2b15cb3dSCy SchubertMdoc::def_macro( 'Pc',  sub { ')', @_ } );
40*2b15cb3dSCy Schubert
41*2b15cb3dSCy SchubertMdoc::def_macro( 'Bro', sub { '{', ns, @_ } );
42*2b15cb3dSCy SchubertMdoc::def_macro( 'Brc', sub { '}', @_ } );
43*2b15cb3dSCy Schubert
44*2b15cb3dSCy SchubertMdoc::def_macro( '.Oo',  gen_encloser(qw([ ])), concat_until => '.Oc' );
45*2b15cb3dSCy SchubertMdoc::def_macro( '.Bro', gen_encloser(qw({ })), concat_until => '.Brc' );
46*2b15cb3dSCy SchubertMdoc::def_macro( '.Po',  gen_encloser(qw/( )/), concat_until => '.Pc' );
47*2b15cb3dSCy Schubert
48*2b15cb3dSCy SchubertMdoc::def_macro( '.Ev', sub { @_ } );
49*2b15cb3dSCy SchubertMdoc::def_macro( '.An', sub { ".NOP ", @_, "\n.br" }, raw => 1 );
50*2b15cb3dSCy SchubertMdoc::def_macro( '.Li', sub { mapwords {"\\f[C]$_\\f[]"} @_ } );
51*2b15cb3dSCy SchubertMdoc::def_macro( '.Cm', sub { mapwords {"\\f\\*[B-Font]$_\\f[]"} @_ } );
52*2b15cb3dSCy SchubertMdoc::def_macro( '.Ic', sub { mapwords {"\\f\\*[B-Font]$_\\f[]"} @_ } );
53*2b15cb3dSCy SchubertMdoc::def_macro( '.Fl', sub { mapwords {"\\f\\*[B-Font]\\-$_\\f[]"} @_ } );
54*2b15cb3dSCy SchubertMdoc::def_macro( '.Ar', sub { mapwords {"\\f\\*[I-Font]$_\\f[]"} @_ } );
55*2b15cb3dSCy SchubertMdoc::def_macro( '.Em', sub { mapwords {"\\fI$_\\f[]"} @_ } );
56*2b15cb3dSCy SchubertMdoc::def_macro( '.Va', sub { mapwords {"\\fI$_\\f[]"} @_ } );
57*2b15cb3dSCy SchubertMdoc::def_macro( '.Sx', sub { mapwords {"\\fI$_\\f[]"} @_ } );
58*2b15cb3dSCy SchubertMdoc::def_macro( '.Xr', sub { "\\fC".(shift)."\\fR(".(shift).")\\f[]", @_ } );
59*2b15cb3dSCy SchubertMdoc::def_macro( '.Fn', sub { "\\f\\*[B-Font]".(shift)."\\fR()\\f[]" } );
60*2b15cb3dSCy SchubertMdoc::def_macro( '.Fn', sub { "\\fB".(shift)."\\fR()\\f[]" } );
61*2b15cb3dSCy SchubertMdoc::def_macro( '.Fx', sub { "FreeBSD", @_ } );
62*2b15cb3dSCy SchubertMdoc::def_macro( '.Ux', sub { "UNIX", @_ } );
63*2b15cb3dSCy Schubert
64*2b15cb3dSCy SchubertMdoc::def_macro( '.No', sub { ".NOP", map { ($_, ns) } @_ } );
65*2b15cb3dSCy SchubertMdoc::def_macro( '.Pa', sub { mapwords {"\\fI$_\\f[]"} @_; } );
66*2b15cb3dSCy Schubert{
67*2b15cb3dSCy Schubert    my $name;
68*2b15cb3dSCy Schubert    Mdoc::def_macro('.Nm', sub {
69*2b15cb3dSCy Schubert        $name = shift if (!$name);
70*2b15cb3dSCy Schubert        "\\f\\*[B-Font]$name\\fP", @_
71*2b15cb3dSCy Schubert    } );
72*2b15cb3dSCy Schubert}
73*2b15cb3dSCy Schubert
74*2b15cb3dSCy Schubert########
75*2b15cb3dSCy Schubert## lists
76*2b15cb3dSCy Schubert########
77*2b15cb3dSCy Schubert
78*2b15cb3dSCy Schubertmy %lists = (
79*2b15cb3dSCy Schubert    bullet => sub {
80*2b15cb3dSCy Schubert        Mdoc::def_macro('.It', sub { '.IP \fB\(bu\fP 2' });
81*2b15cb3dSCy Schubert    },
82*2b15cb3dSCy Schubert
83*2b15cb3dSCy Schubert    column => sub {
84*2b15cb3dSCy Schubert        Mdoc::def_macro('.It', sub { '.IP \fB\(bu\fP 2' });
85*2b15cb3dSCy Schubert    },
86*2b15cb3dSCy Schubert
87*2b15cb3dSCy Schubert    tag    => sub {
88*2b15cb3dSCy Schubert        my (%opts) = @_;
89*2b15cb3dSCy Schubert
90*2b15cb3dSCy Schubert        my $width = '';
91*2b15cb3dSCy Schubert
92*2b15cb3dSCy Schubert        if (exists $opts{width}) {
93*2b15cb3dSCy Schubert            $width = ' '.((length $opts{width})+1);
94*2b15cb3dSCy Schubert        }
95*2b15cb3dSCy Schubert
96*2b15cb3dSCy Schubert        if (exists $opts{compact}) {
97*2b15cb3dSCy Schubert            my $dobrns = 0;
98*2b15cb3dSCy Schubert            Mdoc::def_macro('.It', sub {
99*2b15cb3dSCy Schubert                    my @ret = (".TP$width\n.NOP", hs);
100*2b15cb3dSCy Schubert                    if ($dobrns) {
101*2b15cb3dSCy Schubert                        ".br\n.ns\n", ns, @ret, @_;
102*2b15cb3dSCy Schubert                    }
103*2b15cb3dSCy Schubert                    else {
104*2b15cb3dSCy Schubert                        $dobrns = 1;
105*2b15cb3dSCy Schubert                        @ret, @_;
106*2b15cb3dSCy Schubert                    }
107*2b15cb3dSCy Schubert                }, raw => 1);
108*2b15cb3dSCy Schubert        }
109*2b15cb3dSCy Schubert        else {
110*2b15cb3dSCy Schubert            Mdoc::def_macro('.It', sub {
111*2b15cb3dSCy Schubert                    ".TP$width\n.NOP", hs, @_
112*2b15cb3dSCy Schubert                }, raw => 1);
113*2b15cb3dSCy Schubert        }
114*2b15cb3dSCy Schubert    },
115*2b15cb3dSCy Schubert);
116*2b15cb3dSCy Schubert
117*2b15cb3dSCy SchubertMdoc::set_Bl_callback(do { my $nested = 0; sub {
118*2b15cb3dSCy Schubert    my $type = shift;
119*2b15cb3dSCy Schubert    my %opts = Mdoc::parse_opts(@_);
120*2b15cb3dSCy Schubert    if (defined $type && $type =~ /-(\w+)/ && exists $lists{$1}) {
121*2b15cb3dSCy Schubert
122*2b15cb3dSCy Schubert        # Wrap nested lists with .RS and .RE
123*2b15cb3dSCy Schubert        Mdoc::set_El_callback(sub {
124*2b15cb3dSCy Schubert                return '.RE' if $nested-- > 1;
125*2b15cb3dSCy Schubert                return '.PP';
126*2b15cb3dSCy Schubert            });
127*2b15cb3dSCy Schubert
128*2b15cb3dSCy Schubert        $lists{$1}->(%opts);
129*2b15cb3dSCy Schubert
130*2b15cb3dSCy Schubert        if ($nested++) {
131*2b15cb3dSCy Schubert            return ".RS";
132*2b15cb3dSCy Schubert        }
133*2b15cb3dSCy Schubert        else {
134*2b15cb3dSCy Schubert            return ();
135*2b15cb3dSCy Schubert        }
136*2b15cb3dSCy Schubert    }
137*2b15cb3dSCy Schubert    else {
138*2b15cb3dSCy Schubert        die "Invalid list type <$type>";
139*2b15cb3dSCy Schubert    }
140*2b15cb3dSCy Schubert}}, raw => 1);
141*2b15cb3dSCy Schubert
142*2b15cb3dSCy Schubert# don't bother with arguments for now and do what mdoc2man'.sh' did
143*2b15cb3dSCy Schubert
144*2b15cb3dSCy SchubertMdoc::def_macro('.Bd', sub { ".br\n.in +4\n.nf" } );
145*2b15cb3dSCy SchubertMdoc::def_macro('.Ed', sub { ".in -4\n.fi" } );
146*2b15cb3dSCy Schubert
147*2b15cb3dSCy SchubertMdoc::set_Re_callback(sub {
148*2b15cb3dSCy Schubert        my ($reference) = @_;
149*2b15cb3dSCy Schubert        <<"REF";
150*2b15cb3dSCy Schubert$reference->{authors},
151*2b15cb3dSCy Schubert\\fI$reference->{title}\\fR,
152*2b15cb3dSCy Schubert$reference->{optional}\n.PP
153*2b15cb3dSCy SchubertREF
154*2b15cb3dSCy Schubert});
155*2b15cb3dSCy Schubert
156*2b15cb3dSCy Schubert# Define all macros which have the same sub for inline and standalone macro
157*2b15cb3dSCy Schubertfor (qw(Xr Em Ar Fl Ic Cm Qq Op Nm Pa Sq Li Va Brq Pq Fx Ux)) {
158*2b15cb3dSCy Schubert    my $m = Mdoc::get_macro(".$_");
159*2b15cb3dSCy Schubert    Mdoc::def_macro($_, delete $m->{run}, %$m);
160*2b15cb3dSCy Schubert}
161*2b15cb3dSCy Schubert
162*2b15cb3dSCy Schubertsub print_line {
163*2b15cb3dSCy Schubert    print shift;
164*2b15cb3dSCy Schubert    print "\n";
165*2b15cb3dSCy Schubert}
166*2b15cb3dSCy Schubert
167*2b15cb3dSCy Schubertsub run {
168*2b15cb3dSCy Schubert    print <<'DEFS';
169*2b15cb3dSCy Schubert.de1 NOP
170*2b15cb3dSCy Schubert.  it 1 an-trap
171*2b15cb3dSCy Schubert.  if \\n[.$] \,\\$*\/
172*2b15cb3dSCy Schubert..
173*2b15cb3dSCy Schubert.ie t \
174*2b15cb3dSCy Schubert.ds B-Font [CB]
175*2b15cb3dSCy Schubert.ds I-Font [CI]
176*2b15cb3dSCy Schubert.ds R-Font [CR]
177*2b15cb3dSCy Schubert.el \
178*2b15cb3dSCy Schubert.ds B-Font B
179*2b15cb3dSCy Schubert.ds I-Font I
180*2b15cb3dSCy Schubert.ds R-Font R
181*2b15cb3dSCy SchubertDEFS
182*2b15cb3dSCy Schubert
183*2b15cb3dSCy Schubert    while (my ($macro, @args) = Mdoc::parse_line(\*STDIN, \&print_line)) {
184*2b15cb3dSCy Schubert        my @ret = Mdoc::call_macro($macro, @args);
185*2b15cb3dSCy Schubert        print_line(Mdoc::to_string(@ret)) if @ret;
186*2b15cb3dSCy Schubert    }
187*2b15cb3dSCy Schubert    return 0;
188*2b15cb3dSCy Schubert}
189*2b15cb3dSCy Schubert
190*2b15cb3dSCy Schubertexit run(@ARGV) unless caller;
191*2b15cb3dSCy Schubert
192*2b15cb3dSCy Schubert1;
193*2b15cb3dSCy Schubert__END__
194