blob: d393ae6f1476c7b743edc0d9efe94590da613d32 [file] [log] [blame]
Darren Tucker167bd9c2003-09-07 12:34:54 +10001#!/usr/bin/awk
2#
3# Version history:
Darren Tucker51e5ab02007-06-05 19:16:59 +10004# v4+ Adapted for OpenSSH Portable (see cvs Id and history)
Darren Tucker167bd9c2003-09-07 12:34:54 +10005# 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
25BEGIN {
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
Darren Tuckerd062da52004-07-02 18:43:09 +100036 breakw=0
Darren Tucker167bd9c2003-09-07 12:34:54 +100037 line=""
38}
39
40function 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
50function 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))
Damien Millera8e06ce2003-11-21 23:48:55 +110081 add(OFS)
Darren Tucker167bd9c2003-09-07 12:34:54 +100082 } else if(match(words[w],"^Xc$")) {
83 skip=1
84 ext=0
85 if(!extopt)
Damien Millera8e06ce2003-11-21 23:48:55 +110086 prenl++
Darren Tucker167bd9c2003-09-07 12:34:54 +100087 w=nwords
88 } else if(match(words[w],"^Bd$")) {
89 skip=1
90 if(match(words[w+1],"-literal")) {
Damien Millera8e06ce2003-11-21 23:48:55 +110091 literal=1
92 prenl++
93 w=nwords
Darren Tucker167bd9c2003-09-07 12:34:54 +100094 }
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)
Damien Millera8e06ce2003-11-21 23:48:55 +1100101 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000102 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],"^[\\.,]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100112 add(OFS words[++w])
Darren Tucker167bd9c2003-09-07 12:34:54 +1000113 add("''")
114 if(!nospace&&match(words[w+1],"^[\\.,]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100115 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000116 } else if(match(words[w],"^Sq|Ql$")) {
117 skip=1
118 add("`" words[++w] "'")
119 if(!nospace&&match(words[w+1],"^[\\.,]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100120 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000121 } else if(match(words[w],"^Oo$")) {
122 skip=1
123 extopt=1
124 if(!nospace)
Damien Millera8e06ce2003-11-21 23:48:55 +1100125 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000126 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))
Damien Millera8e06ce2003-11-21 23:48:55 +1100134 add(OFS)
Darren Tucker167bd9c2003-09-07 12:34:54 +1000135 if(nospace==1)
Damien Millera8e06ce2003-11-21 23:48:55 +1100136 nospace=0
Darren Tucker167bd9c2003-09-07 12:34:54 +1000137 }
138 if(match(words[w],"^Dd$")) {
Darren Tucker88bca062007-06-05 19:30:47 +1000139 if(match(words[w+1],"^\\$Mdocdate:")) {
Darren Tucker51e5ab02007-06-05 19:16:59 +1000140 w++;
141 if(match(words[w+4],"^\\$$")) {
142 words[w+4] = ""
143 }
144 }
Darren Tucker167bd9c2003-09-07 12:34:54 +1000145 date=wtail()
146 next
147 } else if(match(words[w],"^Dt$")) {
148 id=wtail()
149 next
Darren Tucker6ac91a72009-10-24 11:52:42 +1100150 } else if(match(words[w],"^Ux$")) {
151 add("UNIX")
152 skip=1
Darren Tuckerf5615962005-05-31 16:59:16 +1000153 } else if(match(words[w],"^Ox$")) {
154 add("OpenBSD")
155 skip=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000156 } 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=""
Darren Tucker0c0dc492007-06-05 20:01:16 +1000170 refreport=""
Darren Tucker167bd9c2003-09-07 12:34:54 +1000171 reference=1
172 next
173 } else if(match(words[w],"^Re$")) {
174 prenl++
175 for(i=nrefauthors-1;i>0;i--) {
Damien Millera8e06ce2003-11-21 23:48:55 +1100176 add(refauthors[i])
177 if(i>1)
178 add(", ")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000179 }
180 if(nrefauthors>1)
Damien Millera8e06ce2003-11-21 23:48:55 +1100181 add(" and ")
Darren Tucker0c0dc492007-06-05 20:01:16 +1000182 if(nrefauthors>0)
183 add(refauthors[0] ", ")
184 add("\\fI" reftitle "\\fP")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000185 if(length(refissue))
Damien Millera8e06ce2003-11-21 23:48:55 +1100186 add(", " refissue)
Darren Tucker0c0dc492007-06-05 20:01:16 +1000187 if(length(refreport)) {
188 add(", " refreport)
189 }
Darren Tucker167bd9c2003-09-07 12:34:54 +1000190 if(length(refdate))
Damien Millera8e06ce2003-11-21 23:48:55 +1100191 add(", " refdate)
Darren Tucker167bd9c2003-09-07 12:34:54 +1000192 if(length(refopt))
Damien Millera8e06ce2003-11-21 23:48:55 +1100193 add(", " refopt)
Darren Tucker167bd9c2003-09-07 12:34:54 +1000194 add(".")
195 reference=0
196 } else if(reference) {
197 if(match(words[w],"^%A$")) { refauthors[nrefauthors++]=wtail() }
198 if(match(words[w],"^%T$")) {
Damien Millera8e06ce2003-11-21 23:48:55 +1100199 reftitle=wtail()
200 sub("^\"","",reftitle)
201 sub("\"$","",reftitle)
Darren Tucker167bd9c2003-09-07 12:34:54 +1000202 }
203 if(match(words[w],"^%N$")) { refissue=wtail() }
204 if(match(words[w],"^%D$")) { refdate=wtail() }
205 if(match(words[w],"^%O$")) { refopt=wtail() }
Darren Tucker0c0dc492007-06-05 20:01:16 +1000206 if(match(words[w],"^%R$")) { refreport=wtail() }
Darren Tucker167bd9c2003-09-07 12:34:54 +1000207 } else if(match(words[w],"^Nm$")) {
208 if(synopsis) {
Damien Millera8e06ce2003-11-21 23:48:55 +1100209 add(".br")
210 prenl++
Darren Tucker167bd9c2003-09-07 12:34:54 +1000211 }
212 n=words[++w]
213 if(!length(name))
Damien Millera8e06ce2003-11-21 23:48:55 +1100214 name=n
Darren Tucker167bd9c2003-09-07 12:34:54 +1000215 if(!length(n))
Damien Millera8e06ce2003-11-21 23:48:55 +1100216 n=name
Darren Tucker167bd9c2003-09-07 12:34:54 +1000217 add("\\fB" n "\\fP")
218 if(!nospace&&match(words[w+1],"^[\\.,]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100219 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000220 } 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],"^[\\.,]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100225 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000226 } else if(match(words[w],"^Ar$")) {
227 add("\\fI")
228 if(w==nwords)
Damien Millera8e06ce2003-11-21 23:48:55 +1100229 add("file ...\\fP")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000230 else {
Damien Millera8e06ce2003-11-21 23:48:55 +1100231 add(words[++w] "\\fP")
232 while(match(words[w+1],"^\\|$"))
233 add(OFS words[++w] " \\fI" words[++w] "\\fP")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000234 }
235 if(!nospace&&match(words[w+1],"^[\\.,]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100236 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000237 } else if(match(words[w],"^Cm$")) {
238 add("\\fB" words[++w] "\\fP")
239 while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100240 add(words[++w])
Darren Tucker167bd9c2003-09-07 12:34:54 +1000241 } else if(match(words[w],"^Op$")) {
242 option=1
243 if(!nospace)
Damien Millera8e06ce2003-11-21 23:48:55 +1100244 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000245 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],"^\\."))
Damien Millera8e06ce2003-11-21 23:48:55 +1100256 add("\\&")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000257 add(words[w] "\\fP")
258 while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100259 add(words[++w])
Darren Tucker167bd9c2003-09-07 12:34:54 +1000260 } 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) {
Damien Millera8e06ce2003-11-21 23:48:55 +1100278 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)
Darren Tucker167bd9c2003-09-07 12:34:54 +1000302 }
303 sub(" $","",line)
304 if(plain)
Damien Millera8e06ce2003-11-21 23:48:55 +1100305 add("\\fP")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000306 } else if(match(words[w],"^Bl$")) {
307 oldoptlist=optlist
308 if(match(words[w+1],"-bullet"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100309 optlist=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000310 else if(match(words[w+1],"-enum")) {
Damien Millera8e06ce2003-11-21 23:48:55 +1100311 optlist=2
312 enum=0
Darren Tucker167bd9c2003-09-07 12:34:54 +1000313 } else if(match(words[w+1],"-tag"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100314 optlist=3
Darren Tucker167bd9c2003-09-07 12:34:54 +1000315 else if(match(words[w+1],"-item"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100316 optlist=4
Darren Tucker167bd9c2003-09-07 12:34:54 +1000317 else if(match(words[w+1],"-bullet"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100318 optlist=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000319 w=nwords
320 } else if(match(words[w],"^El$")) {
321 optlist=oldoptlist
Damien Miller8663e512016-09-28 07:40:33 +1000322 if(!optlist)
323 add(".PP")
Darren Tuckerd062da52004-07-02 18:43:09 +1000324 } 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
Darren Tucker167bd9c2003-09-07 12:34:54 +1000331 } else if(match(words[w],"^It$")&&optlist) {
332 if(optlist==1)
Damien Millera8e06ce2003-11-21 23:48:55 +1100333 add(".IP \\(bu")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000334 else if(optlist==2)
Damien Millera8e06ce2003-11-21 23:48:55 +1100335 add(".IP " ++enum ".")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000336 else if(optlist==3) {
Damien Millera8e06ce2003-11-21 23:48:55 +1100337 add(".TP")
338 prenl++
Darren Tucker58cef1f2004-06-28 15:45:08 +1000339 if(match(words[w+1],"^Pa$|^Ev$")) {
Damien Millera8e06ce2003-11-21 23:48:55 +1100340 add(".B")
341 w++
342 }
Darren Tucker167bd9c2003-09-07 12:34:54 +1000343 } else if(optlist==4)
Damien Millera8e06ce2003-11-21 23:48:55 +1100344 add(".IP")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000345 } else if(match(words[w],"^Sm$")) {
346 if(match(words[w+1],"off"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100347 nospace=2
Darren Tucker167bd9c2003-09-07 12:34:54 +1000348 else if(match(words[w+1],"on"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100349 nospace=0
Darren Tucker167bd9c2003-09-07 12:34:54 +1000350 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}