]> git.donarmstrong.com Git - deb_pkgs/spamass-milter.git/blob - mdoc2man.awk
[svn-inject] Installing original source of spamass-milter
[deb_pkgs/spamass-milter.git] / mdoc2man.awk
1 #!/usr/bin/awk
2 #
3 # $Id: mdoc2man.awk,v 1.3 2003/09/05 16:33:51 dnelson Exp $
4 #
5 # Version history:
6 #  v3, I put the program under a proper license
7 #      Dan Nelson <dnelson@allantgroup.com> added .An, .Aq and fixed a typo
8 #  v2, fixed to work on GNU awk --posix and MacOS X
9 #  v1, first attempt, didn't work on MacOS X
10 #
11 # Copyright (c) 2003 Peter Stuge <stuge-mdoc2man@cdy.org>
12 #
13 # Permission to use, copy, modify, and distribute this software for any
14 # purpose with or without fee is hereby granted, provided that the above
15 # copyright notice and this permission notice appear in all copies.
16 #
17 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
18 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
19 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
20 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
22 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
23 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25
26 BEGIN {
27   optlist=0
28   oldoptlist=0
29   nospace=0
30   synopsis=0
31   reference=0
32   block=0
33   ext=0
34   extopt=0
35   literal=0
36   prenl=0
37   line=""
38 }
39
40 function wtail() {
41   retval=""
42   while(w<nwords) {
43     if(length(retval))
44       retval=retval OFS
45     retval=retval words[++w]
46   }
47   return retval
48 }
49
50 function add(str) {
51   for(;prenl;prenl--)
52     line=line "\n"
53   line=line str
54 }
55
56 ! /^\./ {
57   for(;prenl;prenl--)
58     print ""
59   print
60   if(literal)
61     print ".br"
62   next
63 }
64
65 /^\.\\"/ { next }
66
67 {
68   option=0
69   parens=0
70   angles=0
71   sub("^\\.","")
72   nwords=split($0,words)
73   for(w=1;w<=nwords;w++) {
74     skip=0
75     if(match(words[w],"^Li|Pf$")) {
76       skip=1
77     } else if(match(words[w],"^Xo$")) {
78       skip=1
79       ext=1
80       if(length(line)&&!(match(line," $")||prenl))
81         add(OFS)
82     } else if(match(words[w],"^Xc$")) {
83       skip=1
84       ext=0
85       if(!extopt)
86         prenl++
87       w=nwords
88     } else if(match(words[w],"^Bd$")) {
89       skip=1
90       if(match(words[w+1],"-literal")) {
91         literal=1
92         prenl++
93         w=nwords
94       }
95     } else if(match(words[w],"^Ed$")) {
96       skip=1
97       literal=0
98     } else if(match(words[w],"^Ns$")) {
99       skip=1
100       if(!nospace)
101         nospace=1
102       sub(" $","",line)
103     } else if(match(words[w],"^No$")) {
104       skip=1
105       sub(" $","",line)
106       add(words[++w])
107     } else if(match(words[w],"^Dq$")) {
108       skip=1
109       add("``")
110       add(words[++w])
111       while(w<nwords&&!match(words[w+1],"^[\\.,]"))
112         add(OFS words[++w])
113       add("''")
114       if(!nospace&&match(words[w+1],"^[\\.,]"))
115         nospace=1
116     } else if(match(words[w],"^Sq|Ql$")) {
117       skip=1
118       add("`" words[++w] "'")
119       if(!nospace&&match(words[w+1],"^[\\.,]"))
120         nospace=1
121     } else if(match(words[w],"^Oo$")) {
122       skip=1
123       extopt=1
124       if(!nospace)
125         nospace=1
126       add("[")
127     } else if(match(words[w],"^Oc$")) {
128       skip=1
129       extopt=0
130       add("]")
131     }
132     if(!skip) {
133       if(!nospace&&length(line)&&!(match(line," $")||prenl))
134         add(OFS)
135       if(nospace==1)
136         nospace=0
137     }
138     if(match(words[w],"^Dd$")) {
139       date=wtail()
140       next
141     } else if(match(words[w],"^Dt$")) {
142       id=wtail()
143       next
144     } else if(match(words[w],"^Os$")) {
145       add(".TH " id " \"" date "\" \"" wtail() "\"")
146     } else if(match(words[w],"^Sh$")) {
147       add(".SH")
148       synopsis=match(words[w+1],"SYNOPSIS")
149     } else if(match(words[w],"^Xr$")) {
150       add("\\fB" words[++w] "\\fP(" words[++w] ")" words[++w])
151     } else if(match(words[w],"^Rs$")) {
152       split("",refauthors)
153       nrefauthors=0
154       reftitle=""
155       refissue=""
156       refdate=""
157       refopt=""
158       reference=1
159       next
160     } else if(match(words[w],"^Re$")) {
161       prenl++
162       for(i=nrefauthors-1;i>0;i--) {
163         add(refauthors[i])
164         if(i>1)
165           add(", ")
166       }
167       if(nrefauthors>1)
168         add(" and ")
169       add(refauthors[0] ", \\fI" reftitle "\\fP")
170       if(length(refissue))
171         add(", " refissue)
172       if(length(refdate))
173         add(", " refdate)
174       if(length(refopt))
175         add(", " refopt)
176       add(".")
177       reference=0
178     } else if(reference) {
179       if(match(words[w],"^%A$")) { refauthors[nrefauthors++]=wtail() }
180       if(match(words[w],"^%T$")) {
181         reftitle=wtail()
182         sub("^\"","",reftitle)
183         sub("\"$","",reftitle)
184       }
185       if(match(words[w],"^%N$")) { refissue=wtail() }
186       if(match(words[w],"^%D$")) { refdate=wtail() }
187       if(match(words[w],"^%O$")) { refopt=wtail() }
188     } else if(match(words[w],"^Nm$")) {
189       if(synopsis) {
190         add(".br")
191         prenl++
192       }
193       n=words[++w]
194       if(!length(name))
195         name=n
196       if(!length(n))
197         n=name
198       add("\\fB" n "\\fP")
199       if(!nospace&&match(words[w+1],"^[\\.,]"))
200         nospace=1
201     } else if(match(words[w],"^Nd$")) {
202       add("\\- " wtail())
203     } else if(match(words[w],"^Fl$")) {
204       add("\\fB\\-" words[++w] "\\fP")
205       if(!nospace&&match(words[w+1],"^[\\.,]"))
206         nospace=1
207     } else if(match(words[w],"^Ar$")) {
208       add("\\fI")
209       if(w==nwords)
210         add("file ...\\fP")
211       else {
212         add(words[++w] "\\fP")
213         while(match(words[w+1],"^\\|$"))
214           add(OFS words[++w] " \\fI" words[++w] "\\fP")
215       }
216       if(!nospace&&match(words[w+1],"^[\\.,]"))
217         nospace=1
218     } else if(match(words[w],"^Cm$")) {
219       add("\\fB" words[++w] "\\fP")
220       while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
221         add(words[++w])
222     } else if(match(words[w],"^Op$")) {
223       option=1
224       if(!nospace)
225         nospace=1
226       add("[")
227     } else if(match(words[w],"^Pp$")) {
228       prenl++
229     } else if(match(words[w],"^An$")) {
230       prenl++
231     } else if(match(words[w],"^Ss$")) {
232       add(".SS")
233     } else if(match(words[w],"^Pa$")&&!option) {
234       add("\\fI")
235       w++
236       if(match(words[w],"^\\."))
237         add("\\&")
238       add(words[w] "\\fP")
239       while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
240         add(words[++w])
241     } else if(match(words[w],"^Dv$")) {
242       add(".BR")
243     } else if(match(words[w],"^Em|Ev$")) {
244       add(".IR")
245     } else if(match(words[w],"^Pq$")) {
246       add("(")
247       nospace=1
248       parens=1
249     } else if(match(words[w],"^Aq$")) {
250       add("<")
251       nospace=1
252       angles=1
253     } else if(match(words[w],"^S[xy]$")) {
254       add(".B " wtail())
255     } else if(match(words[w],"^Ic$")) {
256       plain=1
257       add("\\fB")
258       while(w<nwords) {
259         w++
260         if(match(words[w],"^Op$")) {
261           w++
262           add("[")
263           words[nwords]=words[nwords] "]"
264         }
265         if(match(words[w],"^Ar$")) {
266           add("\\fI" words[++w] "\\fP")
267         } else if(match(words[w],"^[\\.,]")) {
268           sub(" $","",line)
269           if(plain) {
270             add("\\fP")
271             plain=0
272           }
273           add(words[w])
274         } else {
275           if(!plain) {
276             add("\\fB")
277             plain=1
278           }
279           add(words[w])
280         }
281         if(!nospace)
282           add(OFS)
283       }
284       sub(" $","",line)
285       if(plain)
286         add("\\fP")
287     } else if(match(words[w],"^Bl$")) {
288       oldoptlist=optlist
289       if(match(words[w+1],"-bullet"))
290         optlist=1
291       else if(match(words[w+1],"-enum")) {
292         optlist=2
293         enum=0
294       } else if(match(words[w+1],"-tag"))
295         optlist=3
296       else if(match(words[w+1],"-item"))
297         optlist=4
298       else if(match(words[w+1],"-bullet"))
299         optlist=1
300       w=nwords
301     } else if(match(words[w],"^El$")) {
302       optlist=oldoptlist
303     } else if(match(words[w],"^It$")&&optlist) {
304       if(optlist==1)
305         add(".IP \\(bu")
306       else if(optlist==2)
307         add(".IP " ++enum ".")
308       else if(optlist==3) {
309         add(".TP")
310         prenl++
311         if(match(words[w+1],"^Pa|Ev$")) {
312           add(".B")
313           w++
314         }
315       } else if(optlist==4)
316         add(".IP")
317     } else if(match(words[w],"^Sm$")) {
318       if(match(words[w+1],"off"))
319         nospace=2
320       else if(match(words[w+1],"on"))
321         nospace=0
322       w++
323     } else if(!skip) {
324       add(words[w])
325     }
326   }
327   if(match(line,"^\\.[^a-zA-Z]"))
328     sub("^\\.","",line)
329   if(parens)
330     add(")")
331   if(angles)
332     add(">")
333   if(option)
334     add("]")
335   if(ext&&!extopt&&!match(line," $"))
336     add(OFS)
337   if(!ext&&!extopt&&length(line)) {
338     print line
339     prenl=0
340     line=""
341   }
342 }