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