xref: /openssh-portable/mdoc2man.awk (revision 265d88d4)
1167bd9cfSDarren Tucker#!/usr/bin/awk
2167bd9cfSDarren Tucker#
3167bd9cfSDarren Tucker# Version history:
451e5ab06SDarren Tucker#  v4+ Adapted for OpenSSH Portable (see cvs Id and history)
5167bd9cfSDarren Tucker#  v3, I put the program under a proper license
6167bd9cfSDarren Tucker#      Dan Nelson <dnelson@allantgroup.com> added .An, .Aq and fixed a typo
7167bd9cfSDarren Tucker#  v2, fixed to work on GNU awk --posix and MacOS X
8167bd9cfSDarren Tucker#  v1, first attempt, didn't work on MacOS X
9167bd9cfSDarren Tucker#
10167bd9cfSDarren Tucker# Copyright (c) 2003 Peter Stuge <stuge-mdoc2man@cdy.org>
11167bd9cfSDarren Tucker#
12167bd9cfSDarren Tucker# Permission to use, copy, modify, and distribute this software for any
13167bd9cfSDarren Tucker# purpose with or without fee is hereby granted, provided that the above
14167bd9cfSDarren Tucker# copyright notice and this permission notice appear in all copies.
15167bd9cfSDarren Tucker#
16167bd9cfSDarren Tucker# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
17167bd9cfSDarren Tucker# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18167bd9cfSDarren Tucker# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
19167bd9cfSDarren Tucker# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20167bd9cfSDarren Tucker# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21167bd9cfSDarren Tucker# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22167bd9cfSDarren Tucker# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23167bd9cfSDarren Tucker
24167bd9cfSDarren Tucker
25167bd9cfSDarren TuckerBEGIN {
26167bd9cfSDarren Tucker  optlist=0
27167bd9cfSDarren Tucker  oldoptlist=0
28167bd9cfSDarren Tucker  nospace=0
29167bd9cfSDarren Tucker  synopsis=0
30167bd9cfSDarren Tucker  reference=0
31167bd9cfSDarren Tucker  block=0
32167bd9cfSDarren Tucker  ext=0
33167bd9cfSDarren Tucker  extopt=0
34167bd9cfSDarren Tucker  literal=0
35167bd9cfSDarren Tucker  prenl=0
36d062da53SDarren Tucker  breakw=0
37167bd9cfSDarren Tucker  line=""
38167bd9cfSDarren Tucker}
39167bd9cfSDarren Tucker
40167bd9cfSDarren Tuckerfunction wtail() {
41167bd9cfSDarren Tucker  retval=""
42167bd9cfSDarren Tucker  while(w<nwords) {
43167bd9cfSDarren Tucker    if(length(retval))
44167bd9cfSDarren Tucker      retval=retval OFS
45167bd9cfSDarren Tucker    retval=retval words[++w]
46167bd9cfSDarren Tucker  }
47167bd9cfSDarren Tucker  return retval
48167bd9cfSDarren Tucker}
49167bd9cfSDarren Tucker
50167bd9cfSDarren Tuckerfunction add(str) {
51167bd9cfSDarren Tucker  for(;prenl;prenl--)
52167bd9cfSDarren Tucker    line=line "\n"
53167bd9cfSDarren Tucker  line=line str
54167bd9cfSDarren Tucker}
55167bd9cfSDarren Tucker
56167bd9cfSDarren Tucker! /^\./ {
57167bd9cfSDarren Tucker  for(;prenl;prenl--)
58167bd9cfSDarren Tucker    print ""
59167bd9cfSDarren Tucker  print
60167bd9cfSDarren Tucker  if(literal)
61167bd9cfSDarren Tucker    print ".br"
62167bd9cfSDarren Tucker  next
63167bd9cfSDarren Tucker}
64167bd9cfSDarren Tucker
65167bd9cfSDarren Tucker/^\.\\"/ { next }
66167bd9cfSDarren Tucker
67167bd9cfSDarren Tucker{
68167bd9cfSDarren Tucker  option=0
69167bd9cfSDarren Tucker  parens=0
70167bd9cfSDarren Tucker  angles=0
71167bd9cfSDarren Tucker  sub("^\\.","")
72167bd9cfSDarren Tucker  nwords=split($0,words)
73167bd9cfSDarren Tucker  for(w=1;w<=nwords;w++) {
74167bd9cfSDarren Tucker    skip=0
75167bd9cfSDarren Tucker    if(match(words[w],"^Li|Pf$")) {
76167bd9cfSDarren Tucker      skip=1
77167bd9cfSDarren Tucker    } else if(match(words[w],"^Xo$")) {
78167bd9cfSDarren Tucker      skip=1
79167bd9cfSDarren Tucker      ext=1
80167bd9cfSDarren Tucker      if(length(line)&&!(match(line," $")||prenl))
81167bd9cfSDarren Tucker	add(OFS)
82167bd9cfSDarren Tucker    } else if(match(words[w],"^Xc$")) {
83167bd9cfSDarren Tucker      skip=1
84167bd9cfSDarren Tucker      ext=0
85167bd9cfSDarren Tucker      if(!extopt)
86167bd9cfSDarren Tucker	prenl++
87167bd9cfSDarren Tucker      w=nwords
88167bd9cfSDarren Tucker    } else if(match(words[w],"^Bd$")) {
89167bd9cfSDarren Tucker      skip=1
90167bd9cfSDarren Tucker      if(match(words[w+1],"-literal")) {
91167bd9cfSDarren Tucker	literal=1
92167bd9cfSDarren Tucker	prenl++
93167bd9cfSDarren Tucker	w=nwords
94167bd9cfSDarren Tucker      }
95167bd9cfSDarren Tucker    } else if(match(words[w],"^Ed$")) {
96167bd9cfSDarren Tucker      skip=1
97167bd9cfSDarren Tucker      literal=0
98167bd9cfSDarren Tucker    } else if(match(words[w],"^Ns$")) {
99167bd9cfSDarren Tucker      skip=1
100167bd9cfSDarren Tucker      if(!nospace)
101167bd9cfSDarren Tucker	nospace=1
102167bd9cfSDarren Tucker      sub(" $","",line)
103167bd9cfSDarren Tucker    } else if(match(words[w],"^No$")) {
104167bd9cfSDarren Tucker      skip=1
105167bd9cfSDarren Tucker      sub(" $","",line)
106167bd9cfSDarren Tucker      add(words[++w])
107167bd9cfSDarren Tucker    } else if(match(words[w],"^Dq$")) {
108167bd9cfSDarren Tucker      skip=1
109167bd9cfSDarren Tucker      add("``")
110167bd9cfSDarren Tucker      add(words[++w])
111167bd9cfSDarren Tucker      while(w<nwords&&!match(words[w+1],"^[\\.,]"))
112167bd9cfSDarren Tucker	add(OFS words[++w])
113167bd9cfSDarren Tucker      add("''")
114167bd9cfSDarren Tucker      if(!nospace&&match(words[w+1],"^[\\.,]"))
115167bd9cfSDarren Tucker	nospace=1
116167bd9cfSDarren Tucker    } else if(match(words[w],"^Sq|Ql$")) {
117167bd9cfSDarren Tucker      skip=1
118167bd9cfSDarren Tucker      add("`" words[++w] "'")
119167bd9cfSDarren Tucker      if(!nospace&&match(words[w+1],"^[\\.,]"))
120167bd9cfSDarren Tucker	nospace=1
121167bd9cfSDarren Tucker    } else if(match(words[w],"^Oo$")) {
122167bd9cfSDarren Tucker      skip=1
123167bd9cfSDarren Tucker      extopt=1
124167bd9cfSDarren Tucker      if(!nospace)
125167bd9cfSDarren Tucker	nospace=1
126167bd9cfSDarren Tucker      add("[")
127167bd9cfSDarren Tucker    } else if(match(words[w],"^Oc$")) {
128167bd9cfSDarren Tucker      skip=1
129167bd9cfSDarren Tucker      extopt=0
130167bd9cfSDarren Tucker      add("]")
131167bd9cfSDarren Tucker    }
132167bd9cfSDarren Tucker    if(!skip) {
133167bd9cfSDarren Tucker      if(!nospace&&length(line)&&!(match(line," $")||prenl))
134167bd9cfSDarren Tucker	add(OFS)
135167bd9cfSDarren Tucker      if(nospace==1)
136167bd9cfSDarren Tucker	nospace=0
137167bd9cfSDarren Tucker    }
138167bd9cfSDarren Tucker    if(match(words[w],"^Dd$")) {
13988bca064SDarren Tucker      if(match(words[w+1],"^\\$Mdocdate:")) {
14051e5ab06SDarren Tucker        w++;
14151e5ab06SDarren Tucker        if(match(words[w+4],"^\\$$")) {
14251e5ab06SDarren Tucker          words[w+4] = ""
14351e5ab06SDarren Tucker        }
14451e5ab06SDarren Tucker      }
145167bd9cfSDarren Tucker      date=wtail()
146167bd9cfSDarren Tucker      next
147167bd9cfSDarren Tucker    } else if(match(words[w],"^Dt$")) {
148167bd9cfSDarren Tucker      id=wtail()
149167bd9cfSDarren Tucker      next
1506ac91a7cSDarren Tucker    } else if(match(words[w],"^Ux$")) {
1516ac91a7cSDarren Tucker      add("UNIX")
1526ac91a7cSDarren Tucker      skip=1
153f5615962SDarren Tucker    } else if(match(words[w],"^Ox$")) {
154f5615962SDarren Tucker      add("OpenBSD")
155f5615962SDarren Tucker      skip=1
156167bd9cfSDarren Tucker    } else if(match(words[w],"^Os$")) {
157167bd9cfSDarren Tucker      add(".TH " id " \"" date "\" \"" wtail() "\"")
158167bd9cfSDarren Tucker    } else if(match(words[w],"^Sh$")) {
159167bd9cfSDarren Tucker      add(".SH")
160167bd9cfSDarren Tucker      synopsis=match(words[w+1],"SYNOPSIS")
161167bd9cfSDarren Tucker    } else if(match(words[w],"^Xr$")) {
162167bd9cfSDarren Tucker      add("\\fB" words[++w] "\\fP(" words[++w] ")" words[++w])
163167bd9cfSDarren Tucker    } else if(match(words[w],"^Rs$")) {
164167bd9cfSDarren Tucker      split("",refauthors)
165167bd9cfSDarren Tucker      nrefauthors=0
166167bd9cfSDarren Tucker      reftitle=""
167167bd9cfSDarren Tucker      refissue=""
168167bd9cfSDarren Tucker      refdate=""
169167bd9cfSDarren Tucker      refopt=""
1700c0dc49bSDarren Tucker      refreport=""
171167bd9cfSDarren Tucker      reference=1
172167bd9cfSDarren Tucker      next
173167bd9cfSDarren Tucker    } else if(match(words[w],"^Re$")) {
174167bd9cfSDarren Tucker      prenl++
175167bd9cfSDarren Tucker      for(i=nrefauthors-1;i>0;i--) {
176167bd9cfSDarren Tucker	add(refauthors[i])
177167bd9cfSDarren Tucker	if(i>1)
178167bd9cfSDarren Tucker	  add(", ")
179167bd9cfSDarren Tucker      }
180167bd9cfSDarren Tucker      if(nrefauthors>1)
181167bd9cfSDarren Tucker	add(" and ")
1820c0dc49bSDarren Tucker      if(nrefauthors>0)
1830c0dc49bSDarren Tucker        add(refauthors[0] ", ")
1840c0dc49bSDarren Tucker      add("\\fI" reftitle "\\fP")
185167bd9cfSDarren Tucker      if(length(refissue))
186167bd9cfSDarren Tucker	add(", " refissue)
1870c0dc49bSDarren Tucker      if(length(refreport)) {
1880c0dc49bSDarren Tucker	add(", " refreport)
1890c0dc49bSDarren Tucker      }
190167bd9cfSDarren Tucker      if(length(refdate))
191167bd9cfSDarren Tucker	add(", " refdate)
192167bd9cfSDarren Tucker      if(length(refopt))
193167bd9cfSDarren Tucker	add(", " refopt)
194167bd9cfSDarren Tucker      add(".")
195167bd9cfSDarren Tucker      reference=0
196167bd9cfSDarren Tucker    } else if(reference) {
197167bd9cfSDarren Tucker      if(match(words[w],"^%A$")) { refauthors[nrefauthors++]=wtail() }
198167bd9cfSDarren Tucker      if(match(words[w],"^%T$")) {
199167bd9cfSDarren Tucker	reftitle=wtail()
200167bd9cfSDarren Tucker	sub("^\"","",reftitle)
201167bd9cfSDarren Tucker	sub("\"$","",reftitle)
202167bd9cfSDarren Tucker      }
203167bd9cfSDarren Tucker      if(match(words[w],"^%N$")) { refissue=wtail() }
204167bd9cfSDarren Tucker      if(match(words[w],"^%D$")) { refdate=wtail() }
205167bd9cfSDarren Tucker      if(match(words[w],"^%O$")) { refopt=wtail() }
2060c0dc49bSDarren Tucker      if(match(words[w],"^%R$")) { refreport=wtail() }
207167bd9cfSDarren Tucker    } else if(match(words[w],"^Nm$")) {
208167bd9cfSDarren Tucker      if(synopsis) {
209167bd9cfSDarren Tucker	add(".br")
210167bd9cfSDarren Tucker	prenl++
211167bd9cfSDarren Tucker      }
212167bd9cfSDarren Tucker      n=words[++w]
213167bd9cfSDarren Tucker      if(!length(name))
214167bd9cfSDarren Tucker	name=n
215167bd9cfSDarren Tucker      if(!length(n))
216167bd9cfSDarren Tucker	n=name
217167bd9cfSDarren Tucker      add("\\fB" n "\\fP")
218167bd9cfSDarren Tucker      if(!nospace&&match(words[w+1],"^[\\.,]"))
219167bd9cfSDarren Tucker	nospace=1
220167bd9cfSDarren Tucker    } else if(match(words[w],"^Nd$")) {
221167bd9cfSDarren Tucker      add("\\- " wtail())
222167bd9cfSDarren Tucker    } else if(match(words[w],"^Fl$")) {
223167bd9cfSDarren Tucker      add("\\fB\\-" words[++w] "\\fP")
224167bd9cfSDarren Tucker      if(!nospace&&match(words[w+1],"^[\\.,]"))
225167bd9cfSDarren Tucker	nospace=1
226167bd9cfSDarren Tucker    } else if(match(words[w],"^Ar$")) {
227167bd9cfSDarren Tucker      add("\\fI")
228167bd9cfSDarren Tucker      if(w==nwords)
229167bd9cfSDarren Tucker	add("file ...\\fP")
230167bd9cfSDarren Tucker      else {
231167bd9cfSDarren Tucker	add(words[++w] "\\fP")
232167bd9cfSDarren Tucker	while(match(words[w+1],"^\\|$"))
233167bd9cfSDarren Tucker	  add(OFS words[++w] " \\fI" words[++w] "\\fP")
234167bd9cfSDarren Tucker      }
235167bd9cfSDarren Tucker      if(!nospace&&match(words[w+1],"^[\\.,]"))
236167bd9cfSDarren Tucker	nospace=1
237167bd9cfSDarren Tucker    } else if(match(words[w],"^Cm$")) {
238167bd9cfSDarren Tucker      add("\\fB" words[++w] "\\fP")
239167bd9cfSDarren Tucker      while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
240167bd9cfSDarren Tucker	add(words[++w])
241167bd9cfSDarren Tucker    } else if(match(words[w],"^Op$")) {
242167bd9cfSDarren Tucker      option=1
243167bd9cfSDarren Tucker      if(!nospace)
244167bd9cfSDarren Tucker	nospace=1
245167bd9cfSDarren Tucker      add("[")
246167bd9cfSDarren Tucker    } else if(match(words[w],"^Pp$")) {
247167bd9cfSDarren Tucker      prenl++
248167bd9cfSDarren Tucker    } else if(match(words[w],"^An$")) {
249167bd9cfSDarren Tucker      prenl++
250167bd9cfSDarren Tucker    } else if(match(words[w],"^Ss$")) {
251167bd9cfSDarren Tucker      add(".SS")
252167bd9cfSDarren Tucker    } else if(match(words[w],"^Pa$")&&!option) {
253167bd9cfSDarren Tucker      add("\\fI")
254167bd9cfSDarren Tucker      w++
255167bd9cfSDarren Tucker      if(match(words[w],"^\\."))
256167bd9cfSDarren Tucker	add("\\&")
257167bd9cfSDarren Tucker      add(words[w] "\\fP")
258167bd9cfSDarren Tucker      while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
259167bd9cfSDarren Tucker	add(words[++w])
260167bd9cfSDarren Tucker    } else if(match(words[w],"^Dv$")) {
261167bd9cfSDarren Tucker      add(".BR")
262167bd9cfSDarren Tucker    } else if(match(words[w],"^Em|Ev$")) {
263167bd9cfSDarren Tucker      add(".IR")
264167bd9cfSDarren Tucker    } else if(match(words[w],"^Pq$")) {
265167bd9cfSDarren Tucker      add("(")
266167bd9cfSDarren Tucker      nospace=1
267167bd9cfSDarren Tucker      parens=1
268167bd9cfSDarren Tucker    } else if(match(words[w],"^Aq$")) {
269167bd9cfSDarren Tucker      add("<")
270167bd9cfSDarren Tucker      nospace=1
271167bd9cfSDarren Tucker      angles=1
272167bd9cfSDarren Tucker    } else if(match(words[w],"^S[xy]$")) {
273167bd9cfSDarren Tucker      add(".B " wtail())
274167bd9cfSDarren Tucker    } else if(match(words[w],"^Ic$")) {
275167bd9cfSDarren Tucker      plain=1
276167bd9cfSDarren Tucker      add("\\fB")
277167bd9cfSDarren Tucker      while(w<nwords) {
278167bd9cfSDarren Tucker	w++
279167bd9cfSDarren Tucker	if(match(words[w],"^Op$")) {
280167bd9cfSDarren Tucker	  w++
281167bd9cfSDarren Tucker	  add("[")
282167bd9cfSDarren Tucker	  words[nwords]=words[nwords] "]"
283167bd9cfSDarren Tucker	}
284167bd9cfSDarren Tucker	if(match(words[w],"^Ar$")) {
285167bd9cfSDarren Tucker	  add("\\fI" words[++w] "\\fP")
286167bd9cfSDarren Tucker	} else if(match(words[w],"^[\\.,]")) {
287167bd9cfSDarren Tucker	  sub(" $","",line)
288167bd9cfSDarren Tucker	  if(plain) {
289167bd9cfSDarren Tucker	    add("\\fP")
290167bd9cfSDarren Tucker	    plain=0
291167bd9cfSDarren Tucker	  }
292167bd9cfSDarren Tucker	  add(words[w])
293167bd9cfSDarren Tucker	} else {
294167bd9cfSDarren Tucker	  if(!plain) {
295167bd9cfSDarren Tucker	    add("\\fB")
296167bd9cfSDarren Tucker	    plain=1
297167bd9cfSDarren Tucker	  }
298167bd9cfSDarren Tucker	  add(words[w])
299167bd9cfSDarren Tucker	}
300167bd9cfSDarren Tucker	if(!nospace)
301167bd9cfSDarren Tucker	  add(OFS)
302167bd9cfSDarren Tucker      }
303167bd9cfSDarren Tucker      sub(" $","",line)
304167bd9cfSDarren Tucker      if(plain)
305167bd9cfSDarren Tucker	add("\\fP")
306167bd9cfSDarren Tucker    } else if(match(words[w],"^Bl$")) {
307167bd9cfSDarren Tucker      oldoptlist=optlist
308167bd9cfSDarren Tucker      if(match(words[w+1],"-bullet"))
309167bd9cfSDarren Tucker	optlist=1
310167bd9cfSDarren Tucker      else if(match(words[w+1],"-enum")) {
311167bd9cfSDarren Tucker	optlist=2
312167bd9cfSDarren Tucker	enum=0
313167bd9cfSDarren Tucker      } else if(match(words[w+1],"-tag"))
314167bd9cfSDarren Tucker	optlist=3
315167bd9cfSDarren Tucker      else if(match(words[w+1],"-item"))
316167bd9cfSDarren Tucker	optlist=4
317167bd9cfSDarren Tucker      else if(match(words[w+1],"-bullet"))
318167bd9cfSDarren Tucker	optlist=1
319167bd9cfSDarren Tucker      w=nwords
320167bd9cfSDarren Tucker    } else if(match(words[w],"^El$")) {
321167bd9cfSDarren Tucker      optlist=oldoptlist
322*8663e51cSDamien Miller      if(!optlist)
323*8663e51cSDamien Miller        add(".PP")
324d062da53SDarren Tucker    } else if(match(words[w],"^Bk$")) {
325d062da53SDarren Tucker      if(match(words[w+1],"-words")) {
326d062da53SDarren Tucker	w++
327d062da53SDarren Tucker	breakw=1
328d062da53SDarren Tucker      }
329d062da53SDarren Tucker    } else if(match(words[w],"^Ek$")) {
330d062da53SDarren Tucker      breakw=0
331167bd9cfSDarren Tucker    } else if(match(words[w],"^It$")&&optlist) {
332167bd9cfSDarren Tucker      if(optlist==1)
333167bd9cfSDarren Tucker	add(".IP \\(bu")
334167bd9cfSDarren Tucker      else if(optlist==2)
335167bd9cfSDarren Tucker	add(".IP " ++enum ".")
336167bd9cfSDarren Tucker      else if(optlist==3) {
337167bd9cfSDarren Tucker	add(".TP")
338167bd9cfSDarren Tucker	prenl++
33958cef1f0SDarren Tucker	if(match(words[w+1],"^Pa$|^Ev$")) {
340167bd9cfSDarren Tucker	  add(".B")
341167bd9cfSDarren Tucker	  w++
342167bd9cfSDarren Tucker	}
343167bd9cfSDarren Tucker      } else if(optlist==4)
344167bd9cfSDarren Tucker	add(".IP")
345167bd9cfSDarren Tucker    } else if(match(words[w],"^Sm$")) {
346167bd9cfSDarren Tucker      if(match(words[w+1],"off"))
347167bd9cfSDarren Tucker	nospace=2
348167bd9cfSDarren Tucker      else if(match(words[w+1],"on"))
349167bd9cfSDarren Tucker	nospace=0
350167bd9cfSDarren Tucker      w++
351167bd9cfSDarren Tucker    } else if(!skip) {
352167bd9cfSDarren Tucker      add(words[w])
353167bd9cfSDarren Tucker    }
354167bd9cfSDarren Tucker  }
355167bd9cfSDarren Tucker  if(match(line,"^\\.[^a-zA-Z]"))
356167bd9cfSDarren Tucker    sub("^\\.","",line)
357167bd9cfSDarren Tucker  if(parens)
358167bd9cfSDarren Tucker    add(")")
359167bd9cfSDarren Tucker  if(angles)
360167bd9cfSDarren Tucker    add(">")
361167bd9cfSDarren Tucker  if(option)
362167bd9cfSDarren Tucker    add("]")
363167bd9cfSDarren Tucker  if(ext&&!extopt&&!match(line," $"))
364167bd9cfSDarren Tucker    add(OFS)
365167bd9cfSDarren Tucker  if(!ext&&!extopt&&length(line)) {
366167bd9cfSDarren Tucker    print line
367167bd9cfSDarren Tucker    prenl=0
368167bd9cfSDarren Tucker    line=""
369167bd9cfSDarren Tucker  }
370167bd9cfSDarren Tucker}
371