mdoc2man.awk revision 272461
1163953Srrs#!/usr/bin/awk 2185694Srrs# 3218269Srrs# $Id: mdoc2man.awk,v 1.9 2009/10/24 00:52:42 dtucker Exp $ 4218269Srrs# 5163953Srrs# Version history: 6163953Srrs# v4+ Adapted for OpenSSH Portable (see cvs Id and history) 7163953Srrs# v3, I put the program under a proper license 8163953Srrs# Dan Nelson <dnelson@allantgroup.com> added .An, .Aq and fixed a typo 9163953Srrs# v2, fixed to work on GNU awk --posix and MacOS X 10228653Stuexen# v1, first attempt, didn't work on MacOS X 11163953Srrs# 12163953Srrs# Copyright (c) 2003 Peter Stuge <stuge-mdoc2man@cdy.org> 13163953Srrs# 14228653Stuexen# Permission to use, copy, modify, and distribute this software for any 15163953Srrs# purpose with or without fee is hereby granted, provided that the above 16163953Srrs# copyright notice and this permission notice appear in all copies. 17163953Srrs# 18163953Srrs# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 19163953Srrs# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 20163953Srrs# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 21163953Srrs# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 22163953Srrs# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 23163953Srrs# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 24163953Srrs# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 25163953Srrs 26163953Srrs 27163953SrrsBEGIN { 28163953Srrs optlist=0 29163953Srrs oldoptlist=0 30163953Srrs nospace=0 31163953Srrs synopsis=0 32163953Srrs reference=0 33163953Srrs block=0 34163953Srrs ext=0 35163953Srrs extopt=0 36163953Srrs literal=0 37163953Srrs prenl=0 38163953Srrs breakw=0 39163953Srrs line="" 40167598Srrs} 41163953Srrs 42163953Srrsfunction wtail() { 43163953Srrs retval="" 44163953Srrs while(w<nwords) { 45163953Srrs if(length(retval)) 46163953Srrs retval=retval OFS 47163953Srrs retval=retval words[++w] 48163953Srrs } 49170091Srrs return retval 50172091Srrs} 51188067Srrs 52179157Srrsfunction add(str) { 53218211Srrs for(;prenl;prenl--) 54163953Srrs line=line "\n" 55163953Srrs line=line str 56163953Srrs} 57163953Srrs 58163953Srrs! /^\./ { 59163953Srrs for(;prenl;prenl--) 60163953Srrs print "" 61163953Srrs print 62165220Srrs if(literal) 63165220Srrs print ".br" 64165220Srrs next 65165220Srrs} 66165220Srrs 67163953Srrs/^\.\\"/ { next } 68163953Srrs 69165220Srrs{ 70163953Srrs option=0 71163953Srrs parens=0 72163953Srrs angles=0 73165220Srrs sub("^\\.","") 74165220Srrs nwords=split($0,words) 75165220Srrs for(w=1;w<=nwords;w++) { 76165220Srrs skip=0 77165220Srrs if(match(words[w],"^Li|Pf$")) { 78165220Srrs skip=1 79163953Srrs } else if(match(words[w],"^Xo$")) { 80163953Srrs skip=1 81163953Srrs ext=1 82163953Srrs if(length(line)&&!(match(line," $")||prenl)) 83163953Srrs add(OFS) 84163953Srrs } else if(match(words[w],"^Xc$")) { 85163953Srrs skip=1 86163953Srrs ext=0 87228653Stuexen if(!extopt) 88163953Srrs prenl++ 89163953Srrs w=nwords 90163953Srrs } else if(match(words[w],"^Bd$")) { 91163953Srrs skip=1 92169420Srrs if(match(words[w+1],"-literal")) { 93169420Srrs literal=1 94172396Srrs prenl++ 95172396Srrs w=nwords 96172396Srrs } 97229774Stuexen } else if(match(words[w],"^Ed$")) { 98163953Srrs skip=1 99163953Srrs literal=0 100169352Srrs } else if(match(words[w],"^Ns$")) { 101179157Srrs skip=1 102168299Srrs if(!nospace) 103168299Srrs nospace=1 104172396Srrs sub(" $","",line) 105163953Srrs } else if(match(words[w],"^No$")) { 106163953Srrs skip=1 107229774Stuexen sub(" $","",line) 108163953Srrs add(words[++w]) 109163953Srrs } else if(match(words[w],"^Dq$")) { 110163953Srrs skip=1 111169352Srrs add("``") 112179157Srrs add(words[++w]) 113168299Srrs while(w<nwords&&!match(words[w+1],"^[\\.,]")) 114168299Srrs add(OFS words[++w]) 115172396Srrs add("''") 116163953Srrs if(!nospace&&match(words[w+1],"^[\\.,]")) 117163953Srrs nospace=1 118163953Srrs } else if(match(words[w],"^Sq|Ql$")) { 119163953Srrs skip=1 120169352Srrs add("`" words[++w] "'") 121179157Srrs if(!nospace&&match(words[w+1],"^[\\.,]")) 122171440Srrs nospace=1 123171440Srrs } else if(match(words[w],"^Oo$")) { 124172396Srrs skip=1 125163953Srrs extopt=1 126163953Srrs if(!nospace) 127163953Srrs nospace=1 128163953Srrs add("[") 129169352Srrs } else if(match(words[w],"^Oc$")) { 130179157Srrs skip=1 131168299Srrs extopt=0 132168299Srrs add("]") 133172396Srrs } 134163953Srrs if(!skip) { 135163953Srrs if(!nospace&&length(line)&&!(match(line," $")||prenl)) 136163953Srrs add(OFS) 137163953Srrs if(nospace==1) 138169352Srrs nospace=0 139179157Srrs } 140168299Srrs if(match(words[w],"^Dd$")) { 141168299Srrs if(match(words[w+1],"^\\$Mdocdate:")) { 142172396Srrs w++; 143163953Srrs if(match(words[w+4],"^\\$$")) { 144163953Srrs words[w+4] = "" 145229774Stuexen } 146163953Srrs } 147179157Srrs date=wtail() 148168299Srrs next 149168299Srrs } else if(match(words[w],"^Dt$")) { 150172396Srrs id=wtail() 151163953Srrs next 152229774Stuexen } else if(match(words[w],"^Ux$")) { 153229774Stuexen add("UNIX") 154229774Stuexen skip=1 155229774Stuexen } else if(match(words[w],"^Ox$")) { 156229774Stuexen add("OpenBSD") 157229774Stuexen skip=1 158229774Stuexen } else if(match(words[w],"^Os$")) { 159229774Stuexen add(".TH " id " \"" date "\" \"" wtail() "\"") 160229774Stuexen } else if(match(words[w],"^Sh$")) { 161229774Stuexen add(".SH") 162229774Stuexen synopsis=match(words[w+1],"SYNOPSIS") 163229774Stuexen } else if(match(words[w],"^Xr$")) { 164229774Stuexen add("\\fB" words[++w] "\\fP(" words[++w] ")" words[++w]) 165229774Stuexen } else if(match(words[w],"^Rs$")) { 166229774Stuexen split("",refauthors) 167229774Stuexen nrefauthors=0 168229774Stuexen reftitle="" 169229774Stuexen refissue="" 170229774Stuexen refdate="" 171229774Stuexen refopt="" 172229774Stuexen refreport="" 173229805Stuexen reference=1 174229805Stuexen next 175229805Stuexen } else if(match(words[w],"^Re$")) { 176229774Stuexen prenl++ 177229774Stuexen for(i=nrefauthors-1;i>0;i--) { 178229774Stuexen add(refauthors[i]) 179229774Stuexen if(i>1) 180229774Stuexen add(", ") 181229774Stuexen } 182229774Stuexen if(nrefauthors>1) 183229774Stuexen add(" and ") 184229774Stuexen if(nrefauthors>0) 185229774Stuexen add(refauthors[0] ", ") 186229774Stuexen add("\\fI" reftitle "\\fP") 187229774Stuexen if(length(refissue)) 188172396Srrs add(", " refissue) 189172396Srrs if(length(refreport)) { 190172396Srrs add(", " refreport) 191172396Srrs } 192163953Srrs if(length(refdate)) 193163953Srrs add(", " refdate) 194163953Srrs if(length(refopt)) 195163953Srrs add(", " refopt) 196163953Srrs add(".") 197171158Srrs reference=0 198171158Srrs } else if(reference) { 199221627Stuexen if(match(words[w],"^%A$")) { refauthors[nrefauthors++]=wtail() } 200221627Stuexen if(match(words[w],"^%T$")) { 201221627Stuexen reftitle=wtail() 202221627Stuexen sub("^\"","",reftitle) 203221627Stuexen sub("\"$","",reftitle) 204171158Srrs } 205171158Srrs if(match(words[w],"^%N$")) { refissue=wtail() } 206217760Stuexen if(match(words[w],"^%D$")) { refdate=wtail() } 207217760Stuexen if(match(words[w],"^%O$")) { refopt=wtail() } 208171158Srrs if(match(words[w],"^%R$")) { refreport=wtail() } 209171158Srrs } else if(match(words[w],"^Nm$")) { 210171158Srrs if(synopsis) { 211171158Srrs add(".br") 212171158Srrs prenl++ 213171158Srrs } 214171158Srrs n=words[++w] 215171158Srrs if(!length(name)) 216171158Srrs name=n 217171158Srrs if(!length(n)) 218217760Stuexen n=name 219217760Stuexen add("\\fB" n "\\fP") 220217760Stuexen if(!nospace&&match(words[w+1],"^[\\.,]")) 221217760Stuexen nospace=1 222217760Stuexen } else if(match(words[w],"^Nd$")) { 223217760Stuexen add("\\- " wtail()) 224217760Stuexen } else if(match(words[w],"^Fl$")) { 225217760Stuexen add("\\fB\\-" words[++w] "\\fP") 226171158Srrs if(!nospace&&match(words[w+1],"^[\\.,]")) 227171158Srrs nospace=1 228171158Srrs } else if(match(words[w],"^Ar$")) { 229171158Srrs add("\\fI") 230171158Srrs if(w==nwords) 231171158Srrs add("file ...\\fP") 232171158Srrs else { 233171158Srrs add(words[++w] "\\fP") 234171158Srrs while(match(words[w+1],"^\\|$")) 235171158Srrs add(OFS words[++w] " \\fI" words[++w] "\\fP") 236171158Srrs } 237171158Srrs if(!nospace&&match(words[w+1],"^[\\.,]")) 238171158Srrs nospace=1 239171158Srrs } else if(match(words[w],"^Cm$")) { 240171158Srrs add("\\fB" words[++w] "\\fP") 241171158Srrs while(w<nwords&&match(words[w+1],"^[\\.,:;)]")) 242217760Stuexen add(words[++w]) 243217760Stuexen } else if(match(words[w],"^Op$")) { 244212712Stuexen option=1 245212712Stuexen if(!nospace) 246212712Stuexen nospace=1 247212712Stuexen add("[") 248171158Srrs } else if(match(words[w],"^Pp$")) { 249171158Srrs prenl++ 250171158Srrs } else if(match(words[w],"^An$")) { 251171158Srrs prenl++ 252221627Stuexen } else if(match(words[w],"^Ss$")) { 253171158Srrs add(".SS") 254171158Srrs } else if(match(words[w],"^Pa$")&&!option) { 255216822Stuexen add("\\fI") 256171158Srrs w++ 257171158Srrs if(match(words[w],"^\\.")) 258171158Srrs add("\\&") 259171158Srrs add(words[w] "\\fP") 260171158Srrs while(w<nwords&&match(words[w+1],"^[\\.,:;)]")) 261171158Srrs add(words[++w]) 262171158Srrs } else if(match(words[w],"^Dv$")) { 263163953Srrs add(".BR") 264228653Stuexen } else if(match(words[w],"^Em|Ev$")) { 265163953Srrs add(".IR") 266163953Srrs } else if(match(words[w],"^Pq$")) { 267163953Srrs add("(") 268163953Srrs nospace=1 269163953Srrs parens=1 270163953Srrs } else if(match(words[w],"^Aq$")) { 271163953Srrs add("<") 272163953Srrs nospace=1 273163953Srrs angles=1 274163953Srrs } else if(match(words[w],"^S[xy]$")) { 275163953Srrs add(".B " wtail()) 276218129Srrs } else if(match(words[w],"^Ic$")) { 277218129Srrs plain=1 278218129Srrs add("\\fB") 279212712Stuexen while(w<nwords) { 280163953Srrs w++ 281163953Srrs if(match(words[w],"^Op$")) { 282163953Srrs w++ 283179783Srrs add("[") 284170744Srrs words[nwords]=words[nwords] "]" 285170744Srrs } 286163953Srrs if(match(words[w],"^Ar$")) { 287163953Srrs add("\\fI" words[++w] "\\fP") 288164181Srrs } else if(match(words[w],"^[\\.,]")) { 289163953Srrs sub(" $","",line) 290163953Srrs if(plain) { 291163953Srrs add("\\fP") 292216822Stuexen plain=0 293216822Stuexen } 294163953Srrs add(words[w]) 295196260Stuexen } else { 296163953Srrs if(!plain) { 297216822Stuexen add("\\fB") 298216822Stuexen plain=1 299216822Stuexen } 300216822Stuexen add(words[w]) 301216822Stuexen } 302216822Stuexen if(!nospace) 303235416Stuexen add(OFS) 304235416Stuexen } 305216822Stuexen sub(" $","",line) 306216822Stuexen if(plain) 307216822Stuexen add("\\fP") 308196260Stuexen } else if(match(words[w],"^Bl$")) { 309196260Stuexen oldoptlist=optlist 310221627Stuexen if(match(words[w+1],"-bullet")) 311216822Stuexen optlist=1 312196260Stuexen else if(match(words[w+1],"-enum")) { 313196260Stuexen optlist=2 314163953Srrs enum=0 315163953Srrs } else if(match(words[w+1],"-tag")) 316163953Srrs optlist=3 317216822Stuexen else if(match(words[w+1],"-item")) 318196260Stuexen optlist=4 319163953Srrs else if(match(words[w+1],"-bullet")) 320163953Srrs optlist=1 321235416Stuexen w=nwords 322163953Srrs } else if(match(words[w],"^El$")) { 323163953Srrs optlist=oldoptlist 324163953Srrs } else if(match(words[w],"^Bk$")) { 325163953Srrs if(match(words[w+1],"-words")) { 326212712Stuexen w++ 327212712Stuexen breakw=1 328212712Stuexen } 329212712Stuexen } else if(match(words[w],"^Ek$")) { 330163953Srrs breakw=0 331221627Stuexen } else if(match(words[w],"^It$")&&optlist) { 332169655Srrs if(optlist==1) 333163953Srrs add(".IP \\(bu") 334163953Srrs else if(optlist==2) 335163953Srrs add(".IP " ++enum ".") 336196260Stuexen else if(optlist==3) { 337163953Srrs add(".TP") 338163953Srrs prenl++ 339164181Srrs if(match(words[w+1],"^Pa$|^Ev$")) { 340188854Srrs add(".B") 341218129Srrs w++ 342185694Srrs } 343185694Srrs } else if(optlist==4) 344179783Srrs add(".IP") 345170744Srrs } else if(match(words[w],"^Sm$")) { 346170744Srrs if(match(words[w+1],"off")) 347163953Srrs nospace=2 348163953Srrs else if(match(words[w+1],"on")) 349163953Srrs nospace=0 350163953Srrs w++ 351180955Srrs } else if(!skip) { 352218129Srrs add(words[w]) 353163953Srrs } 354163953Srrs } 355170091Srrs if(match(line,"^\\.[^a-zA-Z]")) 356163953Srrs sub("^\\.","",line) 357163953Srrs if(parens) 358216822Stuexen add(")") 359164181Srrs if(angles) 360164181Srrs add(">") 361216822Stuexen if(option) 362164181Srrs add("]") 363164181Srrs if(ext&&!extopt&&!match(line," $")) 364171158Srrs add(OFS) 365164181Srrs if(!ext&&!extopt&&length(line)) { 366164181Srrs print line 367164181Srrs prenl=0 368164181Srrs line="" 369164181Srrs } 370170091Srrs} 371163953Srrs