]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/ntp/sntp/ag-tpl/mdoc2man
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / ntp / sntp / ag-tpl / mdoc2man
1 #! /usr/local/bin/perl
2
3 ## mdoc2man.pl -- Convert mdoc tags to man tags
4 ##
5 ## Author:      Harlan Stenn <stenn@ntp.org>
6 ##              
7 ##
8 ##  This file is part of AutoOpts, a companion to AutoGen.
9 ##  AutoOpts is free software.
10 ##  AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
11 ##
12 ##  AutoOpts is available under any one of two licenses.  The license
13 ##  in use must be one of these two and the choice is under the control
14 ##  of the user of the license.
15 ##
16 ##   The GNU Lesser General Public License, version 3 or later
17 ##      See the files "COPYING.lgplv3" and "COPYING.gplv3"
18 ##
19 ##   The Modified Berkeley Software Distribution License
20 ##      See the file "COPYING.mbsd"
21 ##
22 ##  These files have the following sha256 sums:
23 ##
24 ##  8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95  COPYING.gplv3
25 ##  4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b  COPYING.lgplv3
26 ##  13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239  COPYING.mbsd
27
28 ### ToDo
29 # Properly implement -columns in the "my %lists" definition...
30 #
31 # .Xr requires at least 1 arg, the code here expects at least 2
32 #
33 ###
34
35 package mdoc2man;
36 use strict;
37 use warnings;
38 use File::Basename;
39 use lib dirname(__FILE__);
40 use Mdoc qw(hs ns pp mapwords son soff stoggle gen_encloser);
41
42 ########
43 ## Basic
44 ########
45
46 Mdoc::def_macro( '.Sh', sub { '.SH', hs, @_ }, raw => 1);
47 Mdoc::def_macro( '.Ss', sub { '.SS', hs, @_ }, raw => 1);
48 Mdoc::def_macro( '.Pp', sub { ".sp \\n(Ppu\n.ne 2\n" } );
49 Mdoc::def_macro( '.Nd', sub { "\\- @_" } );
50
51 # Macros that enclose things
52 Mdoc::def_macro( '.Brq', gen_encloser(qw({ }))          , greedy => 1 );
53 Mdoc::def_macro( '.Op' , gen_encloser(qw([ ]))          , greedy => 1 );
54 Mdoc::def_macro( '.Qq' , gen_encloser(qw(" "))          , greedy => 1 );
55 Mdoc::def_macro( '.Dq' , gen_encloser(qw(\*[Lq] \*[Rq])), greedy => 1 );
56 Mdoc::def_macro( '.Ql' , gen_encloser(qw(\[oq] \[cq]))  , greedy => 1 );
57 Mdoc::def_macro( '.Sq' , gen_encloser(qw(\[oq] \[cq]))  , greedy => 1 );
58 Mdoc::def_macro( '.Pq' , gen_encloser(qw/( )/)          , greedy => 1 );
59 Mdoc::def_macro( '.D1' , sub { ".in +4\n", ns, @_ , ns , "\n.in -4" } , greedy => 1);
60
61 Mdoc::def_macro( 'Oo',  sub { '[', @_ } );
62 Mdoc::def_macro( 'Oc',  sub { ']', @_ } );
63
64 Mdoc::def_macro( 'Po',  sub { '(', @_} );
65 Mdoc::def_macro( 'Pc',  sub { ')', @_ } );
66
67 Mdoc::def_macro( 'Bro', sub { '{', ns, @_ } );
68 Mdoc::def_macro( 'Brc', sub { '}', @_ } );
69
70 Mdoc::def_macro( '.Oo',  gen_encloser(qw([ ])), concat_until => '.Oc' );
71 Mdoc::def_macro( '.Bro', gen_encloser(qw({ })), concat_until => '.Brc' );
72 Mdoc::def_macro( '.Po',  gen_encloser(qw/( )/), concat_until => '.Pc' );
73
74 Mdoc::def_macro( '.Ev', sub { @_ } );
75 Mdoc::def_macro( '.An', sub { ".NOP ", @_, "\n.br" }, raw => 1 );
76 Mdoc::def_macro( '.Li', sub { mapwords {"\\f[C]$_\\f[]"} @_ } );
77 Mdoc::def_macro( '.Cm', sub { mapwords {"\\f\\*[B-Font]$_\\f[]"} @_ } );
78 Mdoc::def_macro( '.Ic', sub { mapwords {"\\f\\*[B-Font]$_\\f[]"} @_ } );
79 Mdoc::def_macro( '.Fl', sub { mapwords {"\\f\\*[B-Font]\\-$_\\f[]"} @_ } );
80 Mdoc::def_macro( '.Ar', sub { mapwords {"\\f\\*[I-Font]$_\\f[]"} @_ } );
81 Mdoc::def_macro( '.Em', sub { mapwords {"\\fI$_\\f[]"} @_ } );
82 Mdoc::def_macro( '.Va', sub { mapwords {"\\fI$_\\f[]"} @_ } );
83 Mdoc::def_macro( '.Sx', sub { mapwords {"\\fI$_\\f[]"} @_ } );
84 Mdoc::def_macro( '.Xr', sub { "\\fC".(shift)."\\f[]\\fR(".(shift).")\\f[]", @_ } );
85 Mdoc::def_macro( '.Fn', sub { "\\f\\*[B-Font]".(shift)."\\f[]\\fR()\\f[]" } );
86 Mdoc::def_macro( '.Fn', sub { "\\fB".(shift)."\\f[]\\fR()\\f[]" } );
87 Mdoc::def_macro( '.Fx', sub { "FreeBSD", @_ } );
88 Mdoc::def_macro( '.Ux', sub { "UNIX", @_ } );
89
90 Mdoc::def_macro( '.No', sub { ".NOP", map { ($_, ns) } @_ } );
91 Mdoc::def_macro( '.Pa', sub { mapwords {"\\fI$_\\f[]"} @_; } );
92 {
93     my $name;
94     Mdoc::def_macro('.Nm', sub {
95         $name = shift if (!$name);
96         "\\f\\*[B-Font]$name\\fP", @_
97     } );
98 }
99
100 ########
101 ## lists
102 ########
103
104 my %lists = (
105     bullet => sub {
106         Mdoc::def_macro('.It', sub { '.IP \fB\(bu\fP 2' });
107     },
108
109     column => sub {
110         Mdoc::def_macro('.It', sub { '.IP \fB\(bu\fP 2' });
111     },
112
113     tag    => sub {
114         my (%opts) = @_;
115
116         my $width = '';
117
118         if (exists $opts{width}) {
119             $width = ' '.((length $opts{width})+1);
120         }
121
122         if (exists $opts{compact}) {
123             my $dobrns = 0;
124             Mdoc::def_macro('.It', sub {
125                     my @ret = (".TP$width\n.NOP", hs);
126                     if ($dobrns) {
127                         ".br\n.ns\n", ns, @ret, @_;
128                     }
129                     else {
130                         $dobrns = 1;
131                         @ret, @_;
132                     }
133                 }, raw => 1);
134         }
135         else {
136             Mdoc::def_macro('.It', sub {
137                     ".TP$width\n.NOP", hs, @_
138                 }, raw => 1);
139         }
140     },
141 );
142
143 Mdoc::set_Bl_callback(do { my $nested = 0; sub {
144     my $type = shift;
145     my %opts = Mdoc::parse_opts(@_);
146     if (defined $type && $type =~ /-(\w+)/ && exists $lists{$1}) {
147
148         # Wrap nested lists with .RS and .RE
149         Mdoc::set_El_callback(sub { 
150                 return '.RE' if $nested-- > 1;
151                 return '.PP';
152             });
153
154         $lists{$1}->(%opts);
155
156         if ($nested++) {
157             return ".RS";
158         }
159         else {
160             return ();
161         }
162     }
163     else {
164         die "Invalid list type <$type>";
165     }
166 }}, raw => 1);
167
168 # don't bother with arguments for now and do what mdoc2man'.sh' did
169
170 Mdoc::def_macro('.Bd', sub { ".br\n.in +4\n.nf" } );
171 Mdoc::def_macro('.Ed', sub { ".in -4\n.fi" } );
172
173 Mdoc::set_Re_callback(sub { 
174         my ($reference) = @_;
175         <<"REF";
176 $reference->{authors},
177 \\fI$reference->{title}\\fR,
178 $reference->{optional}\n.PP
179 REF
180 });
181
182 # Define all macros which have the same sub for inline and standalone macro
183 for (qw(Xr Em Ar Fl Ic Cm Qq Op Nm Pa Sq Li Va Brq Pq Fx Ux)) {
184     my $m = Mdoc::get_macro(".$_");
185     Mdoc::def_macro($_, delete $m->{run}, %$m);
186 }
187
188 sub print_line {
189     print shift;
190     print "\n";
191 }
192
193 sub run {
194     print <<'DEFS';
195 .de1 NOP
196 .  it 1 an-trap
197 .  if \\n[.$] \,\\$*\/
198 ..
199 .ie t \
200 .ds B-Font [CB]
201 .ds I-Font [CI]
202 .ds R-Font [CR]
203 .el \
204 .ds B-Font B
205 .ds I-Font I
206 .ds R-Font R
207 DEFS
208
209     while (my ($macro, @args) = Mdoc::parse_line(\*STDIN, \&print_line)) {
210         my @ret = Mdoc::call_macro($macro, @args);
211         print_line(Mdoc::to_string(@ret)) if @ret;
212     }
213     return 0;
214 }
215
216 exit run(@ARGV) unless caller;
217
218 1;
219 __END__