]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - crypto/openssh/mdoc2man.awk
bhnd(9): Fix a few mandoc related issues
[FreeBSD/FreeBSD.git] / crypto / openssh / mdoc2man.awk
1 #!/usr/bin/awk
2 #
3 # Version history:
4 #  v4+ Adapted for OpenSSH Portable (see cvs Id and history)
5 #  v3, I put the program under a proper license
6 #      Dan Nelson <dnelson@allantgroup.com> added .An, .Aq and fixed a typo
7 #  v2, fixed to work on GNU awk --posix and MacOS X
8 #  v1, first attempt, didn't work on MacOS X
9 #
10 # Copyright (c) 2003 Peter Stuge <stuge-mdoc2man@cdy.org>
11 #
12 # Permission to use, copy, modify, and distribute this software for any
13 # purpose with or without fee is hereby granted, provided that the above
14 # copyright notice and this permission notice appear in all copies.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
17 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
19 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
24
25 BEGIN {
26   optlist=0
27   oldoptlist=0
28   nospace=0
29   synopsis=0
30   reference=0
31   block=0
32   ext=0
33   extopt=0
34   literal=0
35   prenl=0
36   breakw=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       if(match(words[w+1],"^\\$Mdocdate:")) {
140         w++;
141         if(match(words[w+4],"^\\$$")) {
142           words[w+4] = ""
143         }
144       }
145       date=wtail()
146       next
147     } else if(match(words[w],"^Dt$")) {
148       id=wtail()
149       next
150     } else if(match(words[w],"^Ux$")) {
151       add("UNIX")
152       skip=1
153     } else if(match(words[w],"^Ox$")) {
154       add("OpenBSD")
155       skip=1
156     } else if(match(words[w],"^Os$")) {
157       add(".TH " id " \"" date "\" \"" wtail() "\"")
158     } else if(match(words[w],"^Sh$")) {
159       add(".SH")
160       synopsis=match(words[w+1],"SYNOPSIS")
161     } else if(match(words[w],"^Xr$")) {
162       add("\\fB" words[++w] "\\fP(" words[++w] ")" words[++w])
163     } else if(match(words[w],"^Rs$")) {
164       split("",refauthors)
165       nrefauthors=0
166       reftitle=""
167       refissue=""
168       refdate=""
169       refopt=""
170       refreport=""
171       reference=1
172       next
173     } else if(match(words[w],"^Re$")) {
174       prenl++
175       for(i=nrefauthors-1;i>0;i--) {
176         add(refauthors[i])
177         if(i>1)
178           add(", ")
179       }
180       if(nrefauthors>1)
181         add(" and ")
182       if(nrefauthors>0)
183         add(refauthors[0] ", ")
184       add("\\fI" reftitle "\\fP")
185       if(length(refissue))
186         add(", " refissue)
187       if(length(refreport)) {
188         add(", " refreport)
189       }
190       if(length(refdate))
191         add(", " refdate)
192       if(length(refopt))
193         add(", " refopt)
194       add(".")
195       reference=0
196     } else if(reference) {
197       if(match(words[w],"^%A$")) { refauthors[nrefauthors++]=wtail() }
198       if(match(words[w],"^%T$")) {
199         reftitle=wtail()
200         sub("^\"","",reftitle)
201         sub("\"$","",reftitle)
202       }
203       if(match(words[w],"^%N$")) { refissue=wtail() }
204       if(match(words[w],"^%D$")) { refdate=wtail() }
205       if(match(words[w],"^%O$")) { refopt=wtail() }
206       if(match(words[w],"^%R$")) { refreport=wtail() }
207     } else if(match(words[w],"^Nm$")) {
208       if(synopsis) {
209         add(".br")
210         prenl++
211       }
212       n=words[++w]
213       if(!length(name))
214         name=n
215       if(!length(n))
216         n=name
217       add("\\fB" n "\\fP")
218       if(!nospace&&match(words[w+1],"^[\\.,]"))
219         nospace=1
220     } else if(match(words[w],"^Nd$")) {
221       add("\\- " wtail())
222     } else if(match(words[w],"^Fl$")) {
223       add("\\fB\\-" words[++w] "\\fP")
224       if(!nospace&&match(words[w+1],"^[\\.,]"))
225         nospace=1
226     } else if(match(words[w],"^Ar$")) {
227       add("\\fI")
228       if(w==nwords)
229         add("file ...\\fP")
230       else {
231         add(words[++w] "\\fP")
232         while(match(words[w+1],"^\\|$"))
233           add(OFS words[++w] " \\fI" words[++w] "\\fP")
234       }
235       if(!nospace&&match(words[w+1],"^[\\.,]"))
236         nospace=1
237     } else if(match(words[w],"^Cm$")) {
238       add("\\fB" words[++w] "\\fP")
239       while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
240         add(words[++w])
241     } else if(match(words[w],"^Op$")) {
242       option=1
243       if(!nospace)
244         nospace=1
245       add("[")
246     } else if(match(words[w],"^Pp$")) {
247       prenl++
248     } else if(match(words[w],"^An$")) {
249       prenl++
250     } else if(match(words[w],"^Ss$")) {
251       add(".SS")
252     } else if(match(words[w],"^Pa$")&&!option) {
253       add("\\fI")
254       w++
255       if(match(words[w],"^\\."))
256         add("\\&")
257       add(words[w] "\\fP")
258       while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
259         add(words[++w])
260     } else if(match(words[w],"^Dv$")) {
261       add(".BR")
262     } else if(match(words[w],"^Em|Ev$")) {
263       add(".IR")
264     } else if(match(words[w],"^Pq$")) {
265       add("(")
266       nospace=1
267       parens=1
268     } else if(match(words[w],"^Aq$")) {
269       add("<")
270       nospace=1
271       angles=1
272     } else if(match(words[w],"^S[xy]$")) {
273       add(".B " wtail())
274     } else if(match(words[w],"^Ic$")) {
275       plain=1
276       add("\\fB")
277       while(w<nwords) {
278         w++
279         if(match(words[w],"^Op$")) {
280           w++
281           add("[")
282           words[nwords]=words[nwords] "]"
283         }
284         if(match(words[w],"^Ar$")) {
285           add("\\fI" words[++w] "\\fP")
286         } else if(match(words[w],"^[\\.,]")) {
287           sub(" $","",line)
288           if(plain) {
289             add("\\fP")
290             plain=0
291           }
292           add(words[w])
293         } else {
294           if(!plain) {
295             add("\\fB")
296             plain=1
297           }
298           add(words[w])
299         }
300         if(!nospace)
301           add(OFS)
302       }
303       sub(" $","",line)
304       if(plain)
305         add("\\fP")
306     } else if(match(words[w],"^Bl$")) {
307       oldoptlist=optlist
308       if(match(words[w+1],"-bullet"))
309         optlist=1
310       else if(match(words[w+1],"-enum")) {
311         optlist=2
312         enum=0
313       } else if(match(words[w+1],"-tag"))
314         optlist=3
315       else if(match(words[w+1],"-item"))
316         optlist=4
317       else if(match(words[w+1],"-bullet"))
318         optlist=1
319       w=nwords
320     } else if(match(words[w],"^El$")) {
321       optlist=oldoptlist
322       if(!optlist)
323         add(".PP")
324     } else if(match(words[w],"^Bk$")) {
325       if(match(words[w+1],"-words")) {
326         w++
327         breakw=1
328       }
329     } else if(match(words[w],"^Ek$")) {
330       breakw=0
331     } else if(match(words[w],"^It$")&&optlist) {
332       if(optlist==1)
333         add(".IP \\(bu")
334       else if(optlist==2)
335         add(".IP " ++enum ".")
336       else if(optlist==3) {
337         add(".TP")
338         prenl++
339         if(match(words[w+1],"^Pa$|^Ev$")) {
340           add(".B")
341           w++
342         }
343       } else if(optlist==4)
344         add(".IP")
345     } else if(match(words[w],"^Sm$")) {
346       if(match(words[w+1],"off"))
347         nospace=2
348       else if(match(words[w+1],"on"))
349         nospace=0
350       w++
351     } else if(!skip) {
352       add(words[w])
353     }
354   }
355   if(match(line,"^\\.[^a-zA-Z]"))
356     sub("^\\.","",line)
357   if(parens)
358     add(")")
359   if(angles)
360     add(">")
361   if(option)
362     add("]")
363   if(ext&&!extopt&&!match(line," $"))
364     add(OFS)
365   if(!ext&&!extopt&&length(line)) {
366     print line
367     prenl=0
368     line=""
369   }
370 }