xref: /freebsd/contrib/ntp/sntp/ag-tpl/0-old/mdoc2texi (revision 416ba5c74546f32a993436a99516d35008e9f384)
1*2b15cb3dSCy Schubert#! /usr/bin/perl
2*2b15cb3dSCy Schubert
3*2b15cb3dSCy Schubert### To Do:
4*2b15cb3dSCy Schubert
5*2b15cb3dSCy Schubert# the Bl -column command needs work:
6*2b15cb3dSCy Schubert# - support for "-offset"
7*2b15cb3dSCy Schubert# - support for the header widths
8*2b15cb3dSCy Schubert
9*2b15cb3dSCy Schubert#
10*2b15cb3dSCy Schubert
11*2b15cb3dSCy Schubert###
12*2b15cb3dSCy Schubert
13*2b15cb3dSCy Schubertpackage mdoc2texi;
14*2b15cb3dSCy Schubertuse strict;
15*2b15cb3dSCy Schubertuse warnings;
16*2b15cb3dSCy Schubertuse File::Basename qw(dirname);
17*2b15cb3dSCy Schubertuse lib dirname(__FILE__);
18*2b15cb3dSCy Schubertuse Mdoc qw(ns pp hs mapwords gen_encloser nl);
19*2b15cb3dSCy Schubert
20*2b15cb3dSCy Schubert# Ignore commments
21*2b15cb3dSCy SchubertMdoc::def_macro( '.\"',  sub { () } );
22*2b15cb3dSCy Schubert
23*2b15cb3dSCy Schubert# Enclosers
24*2b15cb3dSCy SchubertMdoc::def_macro( '.An',  sub { @_, ns, '@*' } );
25*2b15cb3dSCy SchubertMdoc::def_macro( '.Aq',  gen_encloser(qw(< >)),   greedy => 1);
26*2b15cb3dSCy SchubertMdoc::def_macro( '.Bq',  gen_encloser(qw([ ])),   greedy => 1);
27*2b15cb3dSCy SchubertMdoc::def_macro( '.Brq', gen_encloser(qw(@{ @})), greedy => 1);
28*2b15cb3dSCy SchubertMdoc::def_macro( '.Pq',  gen_encloser(qw/( )/),   greedy => 1);
29*2b15cb3dSCy SchubertMdoc::def_macro( '.Qq',  gen_encloser(qw(" ")),   greedy => 1);
30*2b15cb3dSCy SchubertMdoc::def_macro( '.Op',  gen_encloser(qw(@code{[ ]})), greedy => 1);
31*2b15cb3dSCy SchubertMdoc::def_macro( '.Ql',  gen_encloser(qw(@quoteleft{} @quoteright{})),
32*2b15cb3dSCy Schubert    greedy => 1);
33*2b15cb3dSCy SchubertMdoc::def_macro( '.Sq',  gen_encloser(qw(@quoteleft{} @quoteright{})),
34*2b15cb3dSCy Schubert    greedy => 1);
35*2b15cb3dSCy SchubertMdoc::def_macro( '.Dq',  gen_encloser(qw(@quotedblleft{} @quotedblright{})),
36*2b15cb3dSCy Schubert    greedy => 1);
37*2b15cb3dSCy SchubertMdoc::def_macro( '.Eq', sub {
38*2b15cb3dSCy Schubert        my ($o, $c) = (shift, pop);
39*2b15cb3dSCy Schubert        gen_encloser($o, $c)->(@_)
40*2b15cb3dSCy Schubert},  greedy => 1);
41*2b15cb3dSCy SchubertMdoc::def_macro( '.D1', sub { "\@example\n", ns, @_, ns, "\n\@end example" },
42*2b15cb3dSCy Schubert    greedy => 1);
43*2b15cb3dSCy SchubertMdoc::def_macro( '.Dl', sub { "\@example\n", ns, @_, ns, "\n\@end example" },
44*2b15cb3dSCy Schubert    greedy => 1);
45*2b15cb3dSCy Schubert
46*2b15cb3dSCy SchubertMdoc::def_macro( '.Oo',  gen_encloser(qw(@code{[ ]})), concat_until => '.Oc');
47*2b15cb3dSCy SchubertMdoc::def_macro( 'Oo',   sub { '@code{[', ns, @_ } );
48*2b15cb3dSCy SchubertMdoc::def_macro( 'Oc',   sub { @_, ns, pp(']}') } );
49*2b15cb3dSCy Schubert
50*2b15cb3dSCy SchubertMdoc::def_macro( '.Bro', gen_encloser(qw(@code{@{ @}})), concat_until => '.Brc');
51*2b15cb3dSCy SchubertMdoc::def_macro( 'Bro',  sub { '@code{@{', ns, @_ } );
52*2b15cb3dSCy SchubertMdoc::def_macro( 'Brc',  sub { @_, ns, pp('@}}') } );
53*2b15cb3dSCy Schubert
54*2b15cb3dSCy SchubertMdoc::def_macro( '.Po',  gen_encloser(qw/( )/), concat_until => '.Pc');
55*2b15cb3dSCy SchubertMdoc::def_macro( 'Po',   sub { '(', @_     } );
56*2b15cb3dSCy SchubertMdoc::def_macro( 'Pc',   sub { @_, ')' } );
57*2b15cb3dSCy Schubert
58*2b15cb3dSCy SchubertMdoc::def_macro( '.Ar', sub { mapwords {"\@kbd{$_}"} @_ } );
59*2b15cb3dSCy SchubertMdoc::def_macro( '.Fl', sub { mapwords {"\@code{-$_}"} @_ } );
60*2b15cb3dSCy SchubertMdoc::def_macro( '.Cm', sub { mapwords {"\@code{-$_}"} @_ } );
61*2b15cb3dSCy SchubertMdoc::def_macro( '.Ic', sub { mapwords {"\@code{$_}"} @_ } );
62*2b15cb3dSCy SchubertMdoc::def_macro( '.Cm', sub { mapwords {"\@code{$_}"} @_ } );
63*2b15cb3dSCy SchubertMdoc::def_macro( '.Li', sub { mapwords {"\@code{$_}"} @_ } );
64*2b15cb3dSCy SchubertMdoc::def_macro( '.Va', sub { mapwords {"\@code{$_}"} @_ } );
65*2b15cb3dSCy SchubertMdoc::def_macro( '.Em', sub { mapwords {"\@emph{$_}"} @_ } );
66*2b15cb3dSCy SchubertMdoc::def_macro( '.Fn', sub { '@code{'.(shift).'()}' } );
67*2b15cb3dSCy SchubertMdoc::def_macro( '.Ss', sub { "\@subsubsection", hs, @_ });
68*2b15cb3dSCy SchubertMdoc::def_macro( '.Sh', sub {
69*2b15cb3dSCy Schubert        my $name = "@_";
70*2b15cb3dSCy Schubert        "\@node", hs, "$name\n", ns, "\@subsection", hs, $name
71*2b15cb3dSCy Schubert    });
72*2b15cb3dSCy SchubertMdoc::def_macro( '.Ss', sub { "\@subsubsection", hs, @_ });
73*2b15cb3dSCy SchubertMdoc::def_macro( '.Xr', sub { '@code{'.(shift).'('.(shift).')}', @_ } );
74*2b15cb3dSCy SchubertMdoc::def_macro( '.Sx', gen_encloser(qw(@ref{ })) );
75*2b15cb3dSCy SchubertMdoc::def_macro( '.Ux', sub { '@sc{unix}', @_ } );
76*2b15cb3dSCy SchubertMdoc::def_macro( '.Fx', sub { '@sc{freebsd}', @_ } );
77*2b15cb3dSCy Schubert{
78*2b15cb3dSCy Schubert    my $name;
79*2b15cb3dSCy Schubert    Mdoc::def_macro('.Nm', sub {
80*2b15cb3dSCy Schubert        $name = shift || $ENV{AG_DEF_PROG_NAME} || 'XXX' if (!$name);
81*2b15cb3dSCy Schubert        "\@code{$name}"
82*2b15cb3dSCy Schubert    } );
83*2b15cb3dSCy Schubert}
84*2b15cb3dSCy SchubertMdoc::def_macro( '.Pa', sub { mapwords {"\@file{$_}"} @_ } );
85*2b15cb3dSCy SchubertMdoc::def_macro( '.Pp', sub { '' } );
86*2b15cb3dSCy Schubert
87*2b15cb3dSCy Schubert# Setup references
88*2b15cb3dSCy Schubert
89*2b15cb3dSCy SchubertMdoc::def_macro( '.Rs', sub { "\@*\n", @_ } );
90*2b15cb3dSCy SchubertMdoc::set_Re_callback(sub {
91*2b15cb3dSCy Schubert        my ($reference) = @_;
92*2b15cb3dSCy Schubert        "@*\n", ns, $reference->{authors}, ',', "\@emph{$reference->{title}}",
93*2b15cb3dSCy Schubert        ',', $reference->{optional}
94*2b15cb3dSCy Schubert    });
95*2b15cb3dSCy Schubert
96*2b15cb3dSCy Schubert# Set up Bd/Ed
97*2b15cb3dSCy Schubert
98*2b15cb3dSCy Schubertmy %displays = (
99*2b15cb3dSCy Schubert    literal => [ '@verbatim', '@end verbatim' ],
100*2b15cb3dSCy Schubert);
101*2b15cb3dSCy Schubert
102*2b15cb3dSCy SchubertMdoc::def_macro( '.Bd', sub {
103*2b15cb3dSCy Schubert        (my $type = shift) =~ s/^-//;
104*2b15cb3dSCy Schubert        die "Not supported display type <$type>"
105*2b15cb3dSCy Schubert            if not exists $displays{ $type };
106*2b15cb3dSCy Schubert
107*2b15cb3dSCy Schubert        my $orig_ed = Mdoc::get_macro('.Ed');
108*2b15cb3dSCy Schubert        Mdoc::def_macro('.Ed', sub {
109*2b15cb3dSCy Schubert                Mdoc::def_macro('.Ed', delete $orig_ed->{run}, %$orig_ed);
110*2b15cb3dSCy Schubert                $displays{ $type }[1];
111*2b15cb3dSCy Schubert            });
112*2b15cb3dSCy Schubert        $displays{ $type }[0]
113*2b15cb3dSCy Schubert    });
114*2b15cb3dSCy SchubertMdoc::def_macro('.Ed', sub { die '.Ed used but .Bd was not seen' });
115*2b15cb3dSCy Schubert
116*2b15cb3dSCy Schubert# Set up Bl/El
117*2b15cb3dSCy Schubert
118*2b15cb3dSCy Schubertmy %lists = (
119*2b15cb3dSCy Schubert    bullet => [ '@itemize @bullet', '@end itemize' ],
120*2b15cb3dSCy Schubert    tag    => [ '@table @asis', '@end table' ],
121*2b15cb3dSCy Schubert    column => [ '@table @asis', '@end table' ],
122*2b15cb3dSCy Schubert);
123*2b15cb3dSCy Schubert
124*2b15cb3dSCy SchubertMdoc::set_Bl_callback(sub {
125*2b15cb3dSCy Schubert        my $type = shift;
126*2b15cb3dSCy Schubert        die "Specify a list type"             if not defined $type;
127*2b15cb3dSCy Schubert        $type =~ s/^-//;
128*2b15cb3dSCy Schubert        die "Not supported list type <$type>" if not exists $lists{ $type };
129*2b15cb3dSCy Schubert        Mdoc::set_El_callback(sub { $lists{ $type }[1] });
130*2b15cb3dSCy Schubert        $lists{ $type }[0]
131*2b15cb3dSCy Schubert    });
132*2b15cb3dSCy SchubertMdoc::def_macro('.It', sub { '@item', hs, @_ });
133*2b15cb3dSCy Schubert
134*2b15cb3dSCy Schubertfor (qw(Aq Bq Brq Pq Qq Ql Sq Dq Eq Ar Fl Ic Pa Op Cm Li Fx Ux Va)) {
135*2b15cb3dSCy Schubert    my $m = Mdoc::get_macro(".$_");
136*2b15cb3dSCy Schubert    Mdoc::def_macro($_, delete $m->{run}, %$m);
137*2b15cb3dSCy Schubert}
138*2b15cb3dSCy Schubert
139*2b15cb3dSCy Schubertsub print_line {
140*2b15cb3dSCy Schubert    my $s = shift;
141*2b15cb3dSCy Schubert    $s =~ s/\\&//g;
142*2b15cb3dSCy Schubert    print "$s\n";
143*2b15cb3dSCy Schubert}
144*2b15cb3dSCy Schubert
145*2b15cb3dSCy Schubertsub preprocess_args {
146*2b15cb3dSCy Schubert    $_ =~ s/([{}])/\@$1/g for @_;
147*2b15cb3dSCy Schubert}
148*2b15cb3dSCy Schubert
149*2b15cb3dSCy Schubertsub run {
150*2b15cb3dSCy Schubert    while (my ($macro, @args) = Mdoc::parse_line(\*STDIN, \&print_line,
151*2b15cb3dSCy Schubert            \&preprocess_args)
152*2b15cb3dSCy Schubert    ) {
153*2b15cb3dSCy Schubert        my @ret = Mdoc::call_macro($macro, @args);
154*2b15cb3dSCy Schubert        if (@ret) {
155*2b15cb3dSCy Schubert            my $s = Mdoc::to_string(@ret);
156*2b15cb3dSCy Schubert            print_line($s);
157*2b15cb3dSCy Schubert        }
158*2b15cb3dSCy Schubert    }
159*2b15cb3dSCy Schubert    return 0;
160*2b15cb3dSCy Schubert}
161*2b15cb3dSCy Schubert
162*2b15cb3dSCy Schubertexit run(@ARGV) unless caller;
163