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