blob: ff771a9db1819cfc8ab6c99972cc70fc65c44ff0 [file] [log] [blame]
Darren Tucker167bd9c2003-09-07 12:34:54 +10001#!/usr/bin/awk
2#
Darren Tucker88bca062007-06-05 19:30:47 +10003# $Id: mdoc2man.awk,v 1.7 2007/06/05 09:30:48 dtucker Exp $
Darren Tucker51e5ab02007-06-05 19:16:59 +10004#
Darren Tucker167bd9c2003-09-07 12:34:54 +10005# Version history:
Darren Tucker51e5ab02007-06-05 19:16:59 +10006# v4+ Adapted for OpenSSH Portable (see cvs Id and history)
Darren Tucker167bd9c2003-09-07 12:34:54 +10007# 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
27BEGIN {
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
Darren Tuckerd062da52004-07-02 18:43:09 +100038 breakw=0
Darren Tucker167bd9c2003-09-07 12:34:54 +100039 line=""
40}
41
42function 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
52function 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))
Damien Millera8e06ce2003-11-21 23:48:55 +110083 add(OFS)
Darren Tucker167bd9c2003-09-07 12:34:54 +100084 } else if(match(words[w],"^Xc$")) {
85 skip=1
86 ext=0
87 if(!extopt)
Damien Millera8e06ce2003-11-21 23:48:55 +110088 prenl++
Darren Tucker167bd9c2003-09-07 12:34:54 +100089 w=nwords
90 } else if(match(words[w],"^Bd$")) {
91 skip=1
92 if(match(words[w+1],"-literal")) {
Damien Millera8e06ce2003-11-21 23:48:55 +110093 literal=1
94 prenl++
95 w=nwords
Darren Tucker167bd9c2003-09-07 12:34:54 +100096 }
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)
Damien Millera8e06ce2003-11-21 23:48:55 +1100103 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000104 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],"^[\\.,]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100114 add(OFS words[++w])
Darren Tucker167bd9c2003-09-07 12:34:54 +1000115 add("''")
116 if(!nospace&&match(words[w+1],"^[\\.,]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100117 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000118 } else if(match(words[w],"^Sq|Ql$")) {
119 skip=1
120 add("`" words[++w] "'")
121 if(!nospace&&match(words[w+1],"^[\\.,]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100122 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000123 } else if(match(words[w],"^Oo$")) {
124 skip=1
125 extopt=1
126 if(!nospace)
Damien Millera8e06ce2003-11-21 23:48:55 +1100127 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000128 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))
Damien Millera8e06ce2003-11-21 23:48:55 +1100136 add(OFS)
Darren Tucker167bd9c2003-09-07 12:34:54 +1000137 if(nospace==1)
Damien Millera8e06ce2003-11-21 23:48:55 +1100138 nospace=0
Darren Tucker167bd9c2003-09-07 12:34:54 +1000139 }
140 if(match(words[w],"^Dd$")) {
Darren Tucker88bca062007-06-05 19:30:47 +1000141 if(match(words[w+1],"^\\$Mdocdate:")) {
Darren Tucker51e5ab02007-06-05 19:16:59 +1000142 w++;
143 if(match(words[w+4],"^\\$$")) {
144 words[w+4] = ""
145 }
146 }
Darren Tucker167bd9c2003-09-07 12:34:54 +1000147 date=wtail()
148 next
149 } else if(match(words[w],"^Dt$")) {
150 id=wtail()
151 next
Darren Tuckerf5615962005-05-31 16:59:16 +1000152 } else if(match(words[w],"^Ox$")) {
153 add("OpenBSD")
154 skip=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000155 } 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--) {
Damien Millera8e06ce2003-11-21 23:48:55 +1100174 add(refauthors[i])
175 if(i>1)
176 add(", ")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000177 }
178 if(nrefauthors>1)
Damien Millera8e06ce2003-11-21 23:48:55 +1100179 add(" and ")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000180 add(refauthors[0] ", \\fI" reftitle "\\fP")
181 if(length(refissue))
Damien Millera8e06ce2003-11-21 23:48:55 +1100182 add(", " refissue)
Darren Tucker167bd9c2003-09-07 12:34:54 +1000183 if(length(refdate))
Damien Millera8e06ce2003-11-21 23:48:55 +1100184 add(", " refdate)
Darren Tucker167bd9c2003-09-07 12:34:54 +1000185 if(length(refopt))
Damien Millera8e06ce2003-11-21 23:48:55 +1100186 add(", " refopt)
Darren Tucker167bd9c2003-09-07 12:34:54 +1000187 add(".")
188 reference=0
189 } else if(reference) {
190 if(match(words[w],"^%A$")) { refauthors[nrefauthors++]=wtail() }
191 if(match(words[w],"^%T$")) {
Damien Millera8e06ce2003-11-21 23:48:55 +1100192 reftitle=wtail()
193 sub("^\"","",reftitle)
194 sub("\"$","",reftitle)
Darren Tucker167bd9c2003-09-07 12:34:54 +1000195 }
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) {
Damien Millera8e06ce2003-11-21 23:48:55 +1100201 add(".br")
202 prenl++
Darren Tucker167bd9c2003-09-07 12:34:54 +1000203 }
204 n=words[++w]
205 if(!length(name))
Damien Millera8e06ce2003-11-21 23:48:55 +1100206 name=n
Darren Tucker167bd9c2003-09-07 12:34:54 +1000207 if(!length(n))
Damien Millera8e06ce2003-11-21 23:48:55 +1100208 n=name
Darren Tucker167bd9c2003-09-07 12:34:54 +1000209 add("\\fB" n "\\fP")
210 if(!nospace&&match(words[w+1],"^[\\.,]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100211 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000212 } 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],"^[\\.,]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100217 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000218 } else if(match(words[w],"^Ar$")) {
219 add("\\fI")
220 if(w==nwords)
Damien Millera8e06ce2003-11-21 23:48:55 +1100221 add("file ...\\fP")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000222 else {
Damien Millera8e06ce2003-11-21 23:48:55 +1100223 add(words[++w] "\\fP")
224 while(match(words[w+1],"^\\|$"))
225 add(OFS words[++w] " \\fI" words[++w] "\\fP")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000226 }
227 if(!nospace&&match(words[w+1],"^[\\.,]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100228 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000229 } else if(match(words[w],"^Cm$")) {
230 add("\\fB" words[++w] "\\fP")
231 while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100232 add(words[++w])
Darren Tucker167bd9c2003-09-07 12:34:54 +1000233 } else if(match(words[w],"^Op$")) {
234 option=1
235 if(!nospace)
Damien Millera8e06ce2003-11-21 23:48:55 +1100236 nospace=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000237 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],"^\\."))
Damien Millera8e06ce2003-11-21 23:48:55 +1100248 add("\\&")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000249 add(words[w] "\\fP")
250 while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100251 add(words[++w])
Darren Tucker167bd9c2003-09-07 12:34:54 +1000252 } 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) {
Damien Millera8e06ce2003-11-21 23:48:55 +1100270 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)
Darren Tucker167bd9c2003-09-07 12:34:54 +1000294 }
295 sub(" $","",line)
296 if(plain)
Damien Millera8e06ce2003-11-21 23:48:55 +1100297 add("\\fP")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000298 } else if(match(words[w],"^Bl$")) {
299 oldoptlist=optlist
300 if(match(words[w+1],"-bullet"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100301 optlist=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000302 else if(match(words[w+1],"-enum")) {
Damien Millera8e06ce2003-11-21 23:48:55 +1100303 optlist=2
304 enum=0
Darren Tucker167bd9c2003-09-07 12:34:54 +1000305 } else if(match(words[w+1],"-tag"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100306 optlist=3
Darren Tucker167bd9c2003-09-07 12:34:54 +1000307 else if(match(words[w+1],"-item"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100308 optlist=4
Darren Tucker167bd9c2003-09-07 12:34:54 +1000309 else if(match(words[w+1],"-bullet"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100310 optlist=1
Darren Tucker167bd9c2003-09-07 12:34:54 +1000311 w=nwords
312 } else if(match(words[w],"^El$")) {
313 optlist=oldoptlist
Darren Tuckerd062da52004-07-02 18:43:09 +1000314 } 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
Darren Tucker167bd9c2003-09-07 12:34:54 +1000321 } else if(match(words[w],"^It$")&&optlist) {
322 if(optlist==1)
Damien Millera8e06ce2003-11-21 23:48:55 +1100323 add(".IP \\(bu")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000324 else if(optlist==2)
Damien Millera8e06ce2003-11-21 23:48:55 +1100325 add(".IP " ++enum ".")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000326 else if(optlist==3) {
Damien Millera8e06ce2003-11-21 23:48:55 +1100327 add(".TP")
328 prenl++
Darren Tucker58cef1f2004-06-28 15:45:08 +1000329 if(match(words[w+1],"^Pa$|^Ev$")) {
Damien Millera8e06ce2003-11-21 23:48:55 +1100330 add(".B")
331 w++
332 }
Darren Tucker167bd9c2003-09-07 12:34:54 +1000333 } else if(optlist==4)
Damien Millera8e06ce2003-11-21 23:48:55 +1100334 add(".IP")
Darren Tucker167bd9c2003-09-07 12:34:54 +1000335 } else if(match(words[w],"^Sm$")) {
336 if(match(words[w+1],"off"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100337 nospace=2
Darren Tucker167bd9c2003-09-07 12:34:54 +1000338 else if(match(words[w+1],"on"))
Damien Millera8e06ce2003-11-21 23:48:55 +1100339 nospace=0
Darren Tucker167bd9c2003-09-07 12:34:54 +1000340 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}