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