PageRenderTime 58ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/archivers/libarchive/files/doc/mdoc2wiki.awk

https://github.com/jsonn/pkgsrc
AWK | 488 lines | 434 code | 18 blank | 36 comment | 0 complexity | 080dc56b899dee83dd105db013da8dbe MD5 | raw file
  1. #!/usr/bin/awk
  2. #
  3. # Copyright (c) 2003 Peter Stuge <stuge-mdoc2man@cdy.org>
  4. #
  5. # Permission to use, copy, modify, and distribute this software for any
  6. # purpose with or without fee is hereby granted, provided that the above
  7. # copyright notice and this permission notice appear in all copies.
  8. #
  9. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. # Dramatically overhauled by Tim Kientzle. This version almost
  17. # handles library-style pages with Fn, Ft, etc commands. Still
  18. # a lot of problems...
  19. BEGIN {
  20. displaylines = 0
  21. listdepth = 0
  22. trailer = ""
  23. out = ""
  24. sep = ""
  25. nextsep = " "
  26. spaces = " "
  27. NORMAL_STATE = 0
  28. PRETAG_STATE = 1
  29. STATE = NORMAL_STATE
  30. }
  31. # Add a word with appropriate preceding whitespace
  32. # Maintain a short queue of the expected upcoming word separators.
  33. function add(str) {
  34. out=out sep str
  35. sep = nextsep
  36. nextsep = " "
  37. }
  38. # Add a word with no following whitespace
  39. # Use for opening punctuation such as '('
  40. function addopen(str) {
  41. add(str)
  42. sep = ""
  43. }
  44. # Add a word with no preceding whitespace
  45. # Use for closing punctuation such as ')' or '.'
  46. function addclose(str) {
  47. sep = ""
  48. add(str)
  49. }
  50. # Add a word with no space before or after
  51. # Use for separating punctuation such as '='
  52. function addpunct(str) {
  53. sep = ""
  54. add(str)
  55. sep = ""
  56. }
  57. # Emit the current line so far
  58. function endline() {
  59. addclose(trailer)
  60. trailer = ""
  61. if(length(out) > 0) {
  62. if (STATE == PRETAG_STATE) {
  63. print out
  64. } else {
  65. print out " "
  66. }
  67. out=""
  68. }
  69. if(displaylines > 0) {
  70. displaylines = displaylines - 1
  71. if (displaylines == 0)
  72. dispend()
  73. }
  74. # First word on next line has no preceding whitespace
  75. sep = ""
  76. }
  77. function linecmd(cmd) {
  78. endline()
  79. add(cmd)
  80. endline()
  81. }
  82. function breakline() {
  83. linecmd("<br>")
  84. }
  85. function crossref(name, sect, other) {
  86. if (name == "cpio" && sect == 1) {
  87. n = "ManPageBsdcpio1"
  88. } else if (name == "cpio" && sect == 5) {
  89. n = "ManPageCpio5"
  90. } else if (name == "mtree" && sect == 5) {
  91. n = "ManPageMtree5"
  92. } else if (name == "tar" && sect == 1) {
  93. n = "ManPageBsdtar1"
  94. } else if (name == "tar" && sect == 5) {
  95. n = "ManPageTar5"
  96. } else if (!match(name, "^archive") && !match(name, "^libarchive")) {
  97. n = name "(" sect ")|http://www.freebsd.org/cgi/man.cgi?query=" name "&sektion=" sect
  98. } else {
  99. n = "ManPage"
  100. numbits = split(name, namebits, "[_-]")
  101. for (i = 1; i <= numbits; ++i) {
  102. p = namebits[i]
  103. n = n toupper(substr(p, 0, 1)) substr(p, 2)
  104. }
  105. n = n sect
  106. }
  107. n = "[[" n "]]"
  108. if (length other > 0)
  109. n = n other
  110. return n
  111. }
  112. # Start an indented display
  113. function dispstart() {
  114. endline()
  115. print "```text"
  116. }
  117. # End an indented display
  118. function dispend() {
  119. endline()
  120. print "```"
  121. }
  122. # Collect rest of input line
  123. function wtail() {
  124. retval=""
  125. while(w<nwords) {
  126. if(length(retval))
  127. retval=retval " "
  128. retval=retval words[++w]
  129. }
  130. return retval
  131. }
  132. function splitwords(l, dest, n, o, w) {
  133. n = 1
  134. delete dest
  135. while (length(l) > 0) {
  136. sub("^[ \t]*", "", l)
  137. if (match(l, "^\"")) {
  138. l = substr(l, 2)
  139. o = index(l, "\"")
  140. if (o > 0) {
  141. w = substr(l, 1, o-1)
  142. l = substr(l, o+1)
  143. dest[n++] = w
  144. } else {
  145. dest[n++] = l
  146. l = ""
  147. }
  148. } else {
  149. o = match(l, "[ \t]")
  150. if (o > 0) {
  151. w = substr(l, 1, o-1)
  152. l = substr(l, o+1)
  153. dest[n++] = w
  154. } else {
  155. dest[n++] = l
  156. l = ""
  157. }
  158. }
  159. }
  160. return n-1
  161. }
  162. ! /^\./ {
  163. out = $0
  164. endline()
  165. next
  166. }
  167. /^\.\\"/ { next }
  168. {
  169. gsub("\\\\e", "\\")
  170. sub("^\\.","")
  171. nwords=splitwords($0, words)
  172. # TODO: Instead of iterating 'w' over the array, have a separate
  173. # function that returns 'next word' and use that. This will allow
  174. # proper handling of double-quoted arguments as well.
  175. for(w=1;w<=nwords;w++) {
  176. if(match(words[w],"^Li$")) { # Literal; rest of line is unformatted
  177. dispstart()
  178. displaylines = 1
  179. } else if(match(words[w],"^Dl$")) { # Display literal
  180. dispstart()
  181. displaylines = 1
  182. } else if(match(words[w],"^Bd$")) { # Begin display
  183. STATE = PRETAG_STATE
  184. if(match(words[w+1],"-literal")) {
  185. dispstart()
  186. displaylines=10000
  187. w=nwords
  188. }
  189. } else if(match(words[w],"^Ed$")) { # End display
  190. displaylines = 0
  191. dispend()
  192. STATE = NORMAL_STATE
  193. } else if(match(words[w],"^Ns$")) { # Suppress space before next word
  194. sep=""
  195. } else if(match(words[w],"^No$")) { # Normal text
  196. add(words[++w])
  197. } else if(match(words[w],"^Dq$")) { # Quote
  198. addopen("\"")
  199. add(words[++w])
  200. while(w<nwords&&!match(words[w+1],"^[\\.,]"))
  201. add(words[++w])
  202. addclose("\"")
  203. } else if(match(words[w],"^Do$")) {
  204. addopen("\"")
  205. } else if(match(words[w],"^Dc$")) {
  206. addclose("\"")
  207. } else if(match(words[w],"^Oo$")) {
  208. addopen("<nowiki>[</nowiki>")
  209. } else if(match(words[w],"^Oc$")) {
  210. addclose("<nowiki>]</nowiki>")
  211. } else if(match(words[w],"^Ao$")) {
  212. addopen("&lt;")
  213. } else if(match(words[w],"^Ac$")) {
  214. addclose("&gt;")
  215. } else if(match(words[w],"^Dd$")) {
  216. date=wtail()
  217. next
  218. } else if(match(words[w],"^Dt$")) {
  219. id=words[++w] "(" words[++w] ")"
  220. next
  221. } else if(match(words[w],"^Ox$")) {
  222. add("OpenBSD")
  223. } else if(match(words[w],"^Fx$")) {
  224. add("FreeBSD")
  225. } else if(match(words[w],"^Bx$")) {
  226. add("BSD")
  227. } else if(match(words[w],"^Nx$")) {
  228. add("NetBSD")
  229. } else if(match(words[w],"^St$")) {
  230. if (match(words[w+1], "^-p1003.1$")) {
  231. w++
  232. add("<nowiki>IEEE Std 1003.1 (``POSIX.1'')</nowiki>")
  233. } else if(match(words[w+1], "^-p1003.1-96$")) {
  234. w++
  235. add("<nowiki>ISO/IEC 9945-1:1996 (``POSIX.1'')</nowiki>")
  236. } else if(match(words[w+1], "^-p1003.1-88$")) {
  237. w++
  238. add("<nowiki>IEEE Std 1003.1-1988 (``POSIX.1'')</nowiki>")
  239. } else if(match(words[w+1], "^-p1003.1-2001$")) {
  240. w++
  241. add("<nowiki>IEEE Std 1003.1-2001 (``POSIX.1'')</nowiki>")
  242. } else if(match(words[w+1], "^-susv2$")) {
  243. w++
  244. add("<nowiki>Version 2 of the Single UNIX Specification (``SUSv2'')</nowiki>")
  245. }
  246. } else if(match(words[w],"^Ex$")) {
  247. if (match(words[w+1], "^-std$")) {
  248. w++
  249. add("The '''" name "''' utility exits 0 on success, and &gt;0 if an error occurs.")
  250. }
  251. } else if(match(words[w],"^Os$")) {
  252. add(id " manual page")
  253. } else if(match(words[w],"^Sh$")) {
  254. section=wtail()
  255. linecmd("== " section " ==")
  256. } else if(match(words[w],"^Xr$")) {
  257. add(crossref(words[w+1], words[w+2], words[w+3]))
  258. w = w + 3
  259. } else if(match(words[w],"^Nm$")) {
  260. if(match(section,"SYNOPSIS"))
  261. breakline()
  262. if(w >= nwords)
  263. n=name
  264. else if (match(words[w+1], "^[A-Z][a-z]$"))
  265. n=name
  266. else if (match(words[w+1], "^[.,;:]$"))
  267. n=name
  268. else {
  269. n=words[++w]
  270. if(!length(name))
  271. name=n
  272. }
  273. if(!length(n))
  274. n=name
  275. if (displaylines == 0)
  276. add("'''" n "'''")
  277. else
  278. add(n)
  279. } else if(match(words[w],"^Nd$")) {
  280. add("- " wtail())
  281. } else if(match(words[w],"^Fl$")) {
  282. addopen("-")
  283. } else if(match(words[w],"^Ar$")) {
  284. if(w==nwords)
  285. add("''file ...''")
  286. else {
  287. ++w
  288. gsub("<", "\\&lt;", words[w])
  289. if (displaylines > 0)
  290. add(words[w])
  291. else
  292. add("''" words[w] "''")
  293. }
  294. } else if(match(words[w],"^Cm$")) {
  295. ++w
  296. if (displaylines == 0) {
  297. add("'''" words[w] "'''")
  298. } else
  299. add(words[w])
  300. } else if(match(words[w],"^Op$")) {
  301. addopen("<nowiki>[</nowiki>")
  302. option=1
  303. trailer="<nowiki>]</nowiki>" trailer
  304. } else if(match(words[w],"^Pp$")) {
  305. ++w
  306. endline()
  307. print ""
  308. } else if(match(words[w],"^An$")) {
  309. if (match(words[w+1],"-nosplit"))
  310. ++w
  311. endline()
  312. } else if(match(words[w],"^Ss$")) {
  313. add("===")
  314. trailer="==="
  315. } else if(match(words[w],"^Ft$")) {
  316. if (match(section, "SYNOPSIS")) {
  317. breakline()
  318. }
  319. l = wtail()
  320. add("''" l "''")
  321. if (match(section, "SYNOPSIS")) {
  322. breakline()
  323. }
  324. } else if(match(words[w],"^Fn$")) {
  325. ++w
  326. F = "'''" words[w] "'''("
  327. Fsep = ""
  328. while(w<nwords) {
  329. ++w
  330. if (match(words[w], "^[.,:]$")) {
  331. --w
  332. break
  333. }
  334. F = F Fsep "''" words[w] "''"
  335. Fsep = ", "
  336. }
  337. add(F ")")
  338. if (match(section, "SYNOPSIS")) {
  339. addclose(";")
  340. }
  341. } else if(match(words[w],"^Fo$")) {
  342. w++
  343. F = "'''" words[w] "'''("
  344. Fsep = ""
  345. } else if(match(words[w],"^Fa$")) {
  346. w++
  347. F = F Fsep "''" words[w] "''"
  348. Fsep = ", "
  349. } else if(match(words[w],"^Fc$")) {
  350. add(F ")")
  351. if (match(section, "SYNOPSIS")) {
  352. addclose(";")
  353. }
  354. } else if(match(words[w],"^Va$")) {
  355. w++
  356. add("''" words[w] "''")
  357. } else if(match(words[w],"^In$")) {
  358. w++
  359. add("'''<nowiki>#include <" words[w] "></nowiki>'''")
  360. } else if(match(words[w],"^Pa$")) {
  361. w++
  362. # if(match(words[w],"^\\."))
  363. # add("\\&")
  364. if (displaylines == 0)
  365. add("''" words[w] "''")
  366. else
  367. add(words[w])
  368. } else if(match(words[w],"^Dv$")) {
  369. linecmd()
  370. } else if(match(words[w],"^Em|Ev$")) {
  371. add(".IR")
  372. } else if(match(words[w],"^Pq$")) {
  373. addopen("(")
  374. trailer=")" trailer
  375. } else if(match(words[w],"^Aq$")) {
  376. addopen(" &lt;")
  377. trailer="&gt;" trailer
  378. } else if(match(words[w],"^Brq$")) {
  379. addopen("<nowiki>{</nowiki>")
  380. trailer="<nowiki>}</nowiki>" trailer
  381. } else if(match(words[w],"^S[xy]$")) {
  382. add(".B " wtail())
  383. } else if(match(words[w],"^Tn$")) {
  384. n=wtail()
  385. add("'''" n "'''")
  386. } else if(match(words[w],"^Ic$")) {
  387. add("''")
  388. trailer="''" trailer
  389. } else if(match(words[w],"^Bl$")) {
  390. ++listdepth
  391. listnext[listdepth]=""
  392. if(match(words[w+1],"-bullet")) {
  393. optlist[listdepth]=1
  394. addopen("<ul>")
  395. listclose[listdepth]="</ul>"
  396. } else if(match(words[w+1],"-enum")) {
  397. optlist[listdepth]=2
  398. enum=0
  399. addopen("<ol>")
  400. listclose[listdepth]="</ol>"
  401. } else if(match(words[w+1],"-tag")) {
  402. optlist[listdepth]=3
  403. addopen("<dl>")
  404. listclose[listdepth]="</dl>"
  405. } else if(match(words[w+1],"-item")) {
  406. optlist[listdepth]=4
  407. addopen("<ul>")
  408. listclose[listdepth]="</ul>"
  409. }
  410. w=nwords
  411. } else if(match(words[w],"^El$")) {
  412. addclose(listnext[listdepth])
  413. addclose(listclose[listdepth])
  414. listclose[listdepth]=""
  415. listdepth--
  416. } else if(match(words[w],"^It$")) {
  417. addclose(listnext[listdepth])
  418. if(optlist[listdepth]==1) {
  419. addpunct("<li>")
  420. listnext[listdepth] = "</li>"
  421. } else if(optlist[listdepth]==2) {
  422. addpunct("<li>")
  423. listnext[listdepth] = "</li>"
  424. } else if(optlist[listdepth]==3) {
  425. addpunct("<dt>")
  426. listnext[listdepth] = "</dt>"
  427. if(match(words[w+1],"^Xo$")) {
  428. # Suppress trailer
  429. w++
  430. } else if(match(words[w+1],"^Pa$|^Ev$")) {
  431. addopen("'''")
  432. w++
  433. add(words[++w] "'''")
  434. trailer = listnext[listdepth] "<dd>" trailer
  435. listnext[listdepth] = "</dd>"
  436. } else {
  437. trailer = listnext[listdepth] "<dd>" trailer
  438. listnext[listdepth] = "</dd>"
  439. }
  440. } else if(optlist[listdepth]==4) {
  441. addpunct("<li>")
  442. listnext[listdepth] = "</li>"
  443. }
  444. } else if(match(words[w], "^Vt$")) {
  445. w++
  446. add("''" words[w] "''")
  447. } else if(match(words[w],"^Xo$")) {
  448. # TODO: Figure out how to handle this
  449. } else if(match(words[w],"^Xc$")) {
  450. # TODO: Figure out how to handle this
  451. if (optlist[listdepth] == 3) {
  452. addclose(listnext[listdepth])
  453. addopen("<dd>")
  454. listnext[listdepth] = "</dd>"
  455. }
  456. } else if(match(words[w],"^[=]$")) {
  457. addpunct(words[w])
  458. } else if(match(words[w],"^[[{(]$")) {
  459. addopen(words[w])
  460. } else if(match(words[w],"^[\\])}.,;:]$")) {
  461. addclose(words[w])
  462. } else {
  463. sub("\\\\&", "", words[w])
  464. add(words[w])
  465. }
  466. }
  467. if(match(out,"^\\.[^a-zA-Z]"))
  468. sub("^\\.","",out)
  469. endline()
  470. }