2html 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. #!/usr/bin/env lua5.3
  2. -- special marks:
  3. -- \1 - paragraph (empty line)
  4. -- \4 - remove spaces around it
  5. -- \3 - ref (followed by label|)
  6. ---------------------------------------------------------------
  7. header = [[
  8. <!DOCTYPE html>
  9. <html>
  10. <head>
  11. <title>Lua 5.5 Reference Manual</title>
  12. <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  13. <link rel="stylesheet" href="lua.css">
  14. <link rel="stylesheet" href="manual.css">
  15. </head>
  16. <body bgcolor="#FFFFFF">
  17. <hr>
  18. <h1>
  19. <a href="http://www.lua.org/home.html"><img src="logo.gif" alt="[Lua logo]" border="0"></a>
  20. Lua 5.5 Reference Manual
  21. </h1>
  22. by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
  23. <p>
  24. <small>
  25. <a href="http://www.lua.org/copyright.html">Copyright</a>
  26. &copy; 2025 Lua.org, PUC-Rio. All rights reserved.
  27. </small>
  28. <hr>
  29. <!-- ====================================================================== -->
  30. <p>
  31. ]]
  32. footer = "\n\n</body></html>\n\n"
  33. local seefmt = '(see %s)'
  34. if arg[1] == 'port' then
  35. seefmt = '(ver %s)'
  36. header = string.gsub(header, "by (.-)\n",
  37. "%1\n<p>Tradu&ccedil;&atilde;o: S&eacute;rgio Queiroz de Medeiros", 1)
  38. header = string.gsub(header, "Lua (%d+.%d+) Reference Manual",
  39. "Manual de Refer&ecirc;ncia de Lua %1")
  40. header = string.gsub(header, "All rights reserved",
  41. "Todos os direitos reservados")
  42. end
  43. ---------------------------------------------------------------
  44. local function compose (f,g)
  45. assert(f and g)
  46. return function (s) return g(f(s)) end
  47. end
  48. local function concat (f, g)
  49. assert(f and g)
  50. return function (s) return f(s) .. g(s) end
  51. end
  52. local Tag = {}
  53. setmetatable(Tag, {
  54. __index = function (t, tag)
  55. local v = function (n, att)
  56. local e = ""
  57. if type(att) == "table" then
  58. for k,v in pairs(att) do e = string.format('%s %s="%s"', e, k, v) end
  59. end
  60. if n then
  61. return string.format("<%s%s>%s</%s>", tag, e, n, tag)
  62. else
  63. return string.format("<%s%s>", tag, e)
  64. end
  65. end
  66. t[tag] = v
  67. return v
  68. end
  69. })
  70. ---------------------------------------------------------------
  71. local labels = {}
  72. local function anchor (text, label, link, textlink)
  73. if labels[label] then
  74. error("label " .. label .. " already defined")
  75. end
  76. labels[label] = {text = textlink, link = link}
  77. return Tag.a(text, {name=link})
  78. end
  79. local function makeref (label)
  80. assert(not string.find(label, "|"))
  81. return string.format("\3%s\3", label)
  82. end
  83. local function ref (label)
  84. local l = labels[label]
  85. if not l then
  86. io.stderr:write("label ", label, " undefined\n")
  87. return "@@@@@@@"
  88. else
  89. return Tag.a(l.text, {href="#"..l.link})
  90. end
  91. end
  92. ---------------------------------------------------------------
  93. local function nopara (t)
  94. t = string.gsub(t, "\1", "\n\n")
  95. t = string.gsub(t, "<p>%s*</p>", "")
  96. return t
  97. end
  98. local function fixpara (t)
  99. t = string.gsub(t, "\1", "\n</p>\n\n<p>\n")
  100. t = string.gsub(t, "<p>%s*</p>", "")
  101. return t
  102. end
  103. local function antipara (t)
  104. return "</p>\n" .. t .. "<p>"
  105. end
  106. Tag.pre = compose(Tag.pre, antipara)
  107. Tag.ul = compose(Tag.ul, antipara)
  108. ---------------------------------------------------------------
  109. local Gfoots = 0
  110. local footnotes = {}
  111. local line = Tag.hr(nil)
  112. local function dischargefoots ()
  113. if #footnotes == 0 then return "" end
  114. local fn = table.concat(footnotes)
  115. footnotes = {}
  116. return line .. Tag.h3"footnotes:" .. fn .. line
  117. end
  118. local Glists = 0
  119. local listings = {}
  120. local function dischargelist ()
  121. if #listings == 0 then return "" end
  122. local l = listings
  123. listings = {}
  124. return line .. table.concat(l, line..line) .. line
  125. end
  126. ---------------------------------------------------------------
  127. local counters = {
  128. h1 = {val = 1},
  129. h2 = {father = "h1", val = 1},
  130. h3 = {father = "h2", val = 1},
  131. listing = {father = "h1", val = 1},
  132. }
  133. local function inccounter (count)
  134. counters[count].val = counters[count].val + 1
  135. for c, v in pairs(counters) do
  136. if v.father == count then v.val = 1 end
  137. end
  138. end
  139. local function getcounter (count)
  140. local c = counters[count]
  141. if c.father then
  142. return getcounter(c.father) .. "." .. c.val
  143. else
  144. return c.val .. ""
  145. end
  146. end
  147. ---------------------------------------------------------------
  148. local function fixed (x)
  149. return function () return x end
  150. end
  151. local function id (x) return x end
  152. local function prepos (x, y)
  153. assert(x and y)
  154. return function (s) return string.format("%s%s%s", x, s, y) end
  155. end
  156. local rw = Tag.b
  157. local function LuaName (name)
  158. return Tag.code(name)
  159. end
  160. local function getparam (s)
  161. local i, e = string.find(s, "^[^%s@|]+|")
  162. if not i then return nil, s
  163. else return string.sub(s, i, e - 1), string.sub(s, e + 1)
  164. end
  165. end
  166. local function gettitle (h)
  167. local title, p = assert(string.match(h, "<title>(.-)</title>()"))
  168. return title, string.sub(h, p)
  169. end
  170. local function getparamtitle (what, h, nonum)
  171. local label, title, c, count
  172. label, h = getparam(h)
  173. title, h = gettitle(h)
  174. if not nonum then
  175. count = getcounter(what)
  176. inccounter(what)
  177. c = string.format("%s &ndash; ", count)
  178. else
  179. c = ""
  180. end
  181. label = label or count
  182. if label then
  183. title = anchor(title, label, count, "&sect;"..count)
  184. end
  185. title = string.format("%s%s", c, title)
  186. return title, h
  187. end
  188. local function section (what, nonum)
  189. return function (h)
  190. local title
  191. title, h = getparamtitle(what, h, nonum)
  192. local fn = what == "h1" and dischargefoots() or ""
  193. h = fixpara(Tag.p(h))
  194. return "</p>\n" .. Tag[what](title) .. h .. fn ..
  195. dischargelist() .. "<p>"
  196. end
  197. end
  198. local function verbatim (s)
  199. s = nopara(s)
  200. s = string.gsub(s, "\n", "\n ")
  201. s = string.gsub(s, "\n%s*$", "\n")
  202. return Tag.pre(s)
  203. end
  204. local function verb (s)
  205. return Tag.code(s)
  206. end
  207. local function lua2link (e)
  208. return string.find(e, "luaL?_") and e or "pdf-"..e
  209. end
  210. local verbfixed = verb
  211. local Tex = {
  212. ANSI = function (func)
  213. return "ISO&nbsp;C function " .. Tag.code(func)
  214. end,
  215. At = fixed"@",
  216. B = Tag.b,
  217. bigskip = fixed"",
  218. bignum = id,
  219. C = fixed"",
  220. Ci = prepos("<!-- ", " -->"),
  221. CId = function (func)
  222. return "C&nbsp;function " .. Tag.code(func)
  223. end,
  224. chapter = section"h1",
  225. Char = compose(verbfixed, prepos("'", "'")),
  226. Cdots = fixed"&middot;&middot;&middot;",
  227. Close = fixed"}",
  228. col = Tag.td,
  229. defid = function (name)
  230. local l = lua2link(name)
  231. local c = Tag.code(name)
  232. return anchor(c, l, l, c)
  233. end,
  234. def = Tag.em,
  235. description = compose(nopara, Tag.ul),
  236. Em = fixed("\4" .. "&mdash;" .. "\4"),
  237. emph = Tag.em,
  238. emphx = Tag.em, -- emphasis plus index (if there was an index)
  239. En = fixed("&ndash;"),
  240. format = fixed"",
  241. ["false"] = fixed(Tag.b"false"),
  242. id = Tag.code,
  243. idx = Tag.code,
  244. index = fixed"",
  245. Lidx = fixed"", -- Tag.code,
  246. ldots = fixed"...",
  247. x = id,
  248. itemize = compose(nopara, Tag.ul),
  249. leq = fixed"&le;",
  250. Lid = function (s)
  251. return makeref(lua2link(s))
  252. end,
  253. M = Tag.em,
  254. N = function (s) return (string.gsub(s, " ", "&nbsp;")) end,
  255. NE = id, -- tag"foreignphrase",
  256. num = id,
  257. ["nil"] = fixed(Tag.b"nil"),
  258. fail = fixed(Tag.b"fail"),
  259. Open = fixed"{",
  260. part = section("h1", true),
  261. Pat = compose(verbfixed, prepos("'", "'")),
  262. preface = section("h1", true),
  263. psect = section("h2", true),
  264. Q = prepos('"', '"'),
  265. refchp = makeref,
  266. refcode = makeref,
  267. refsec = makeref,
  268. pi = fixed"&pi;",
  269. rep = Tag.em, -- compose(prepos("&lt;", "&gt;"), Tag.em),
  270. Rw = rw,
  271. rw = rw,
  272. sb = Tag.sub,
  273. sp = Tag.sup,
  274. St = compose(verbfixed, prepos('"', '"')),
  275. sect1 = section"h1",
  276. sect2 = section"h2",
  277. sect3 = section"h3",
  278. sect4 = section("h4", true),
  279. simplesect = id,
  280. Tab2 = function (s) return Tag.table(s, {border=1}) end,
  281. row = Tag.tr,
  282. title = Tag.title,
  283. todo = Tag.todo,
  284. ["true"] = fixed(Tag.b"true"),
  285. T = verb,
  286. item = function (s)
  287. local t, p = string.match(s, "^([^\n|]+)|()")
  288. if t then
  289. s = string.sub(s, p)
  290. s = Tag.b(t) ..": " .. s
  291. end
  292. return Tag.li(fixpara(s))
  293. end,
  294. verbatim = verbatim,
  295. manual = id,
  296. -- for the manual
  297. link =function (s)
  298. local l, t = getparam(s)
  299. assert(l)
  300. return string.format("%s (%s)", t, makeref(l))
  301. end,
  302. see = function (s) return string.format(seefmt, makeref(s)) end,
  303. See = makeref,
  304. seeC = function (s)
  305. return string.format(seefmt, makeref(s))
  306. end,
  307. seeF = function (s)
  308. return string.format(seefmt, makeref(lua2link(s)))
  309. end,
  310. APIEntry = function (e)
  311. local h, name
  312. h, e = string.match(e, "^%s*(.-)%s*|(.*)$")
  313. name = string.match(h, "(luaL?_[%w_]+)%)? +%(") or
  314. string.match(h, "luaL?_[%w_]+")
  315. local a = anchor(Tag.code(name), name, name, Tag.code(name))
  316. local apiicmd, ne = string.match(e, "^(.-</span>)(.*)")
  317. --io.stderr:write(e)
  318. if not apiicmd then
  319. return antipara(Tag.hr() .. Tag.h3(a)) .. Tag.pre(h) .. e
  320. else
  321. return antipara(Tag.hr() .. Tag.h3(a)) .. apiicmd .. Tag.pre(h) .. ne
  322. end
  323. end,
  324. LibEntry = function (e)
  325. local h, name
  326. h, e = string.match(e, "^(.-)|(.*)$")
  327. name = string.gsub(h, " (.+", "")
  328. local l = lua2link(name)
  329. local a = anchor(Tag.code(h), l, l, Tag.code(name))
  330. return Tag.hr() .. Tag.h3(a) .. e
  331. end,
  332. Produc = compose(nopara, Tag.pre),
  333. producname = prepos("\t", " ::= "),
  334. Or = fixed" | ",
  335. VerBar = fixed"&#124;", -- vertical bar
  336. OrNL = fixed" | \4",
  337. bnfNter = prepos("", ""),
  338. bnfopt = prepos("[", "]"),
  339. bnfrep = prepos("{", "}"),
  340. bnfter = compose(Tag.b, prepos("&lsquo;", "&rsquo;")),
  341. producbody = function (s)
  342. s = string.gsub(s, "%s+", " ")
  343. s = string.gsub(s, "\4", "\n\t\t")
  344. return s
  345. end,
  346. apii = function (s)
  347. local pop,push,err = string.match(s, "^(.-),(.-),(.*)$")
  348. if pop ~= "?" and string.find(pop, "%W") then
  349. pop = "(" .. pop .. ")"
  350. end
  351. if push ~= "?" and string.find(push, "%W") then
  352. push = "(" .. push .. ")"
  353. end
  354. err = (err == "-") and "&ndash;" or Tag.em(err)
  355. return Tag.span(
  356. string.format("[-%s, +%s, %s]", pop, push, err),
  357. {class="apii"}
  358. )
  359. end,
  360. }
  361. local others = prepos("?? "," ??")
  362. local function trata (t)
  363. t = string.gsub(t, "@(%w+)(%b{})", function (w, f)
  364. f = trata(string.sub(f, 2, -2))
  365. if type(Tex[w]) ~= "function" then
  366. io.stderr:write(w .. "\n")
  367. return others(f)
  368. else
  369. return Tex[w](f, w)
  370. end
  371. end)
  372. return t
  373. end
  374. ---------------------------------------------------------------------
  375. ---------------------------------------------------------------------
  376. -- read whole book
  377. t = io.read"*a"
  378. t = string.gsub(t, "[<>&\128-\255]",
  379. {["<"] = "&lt;",
  380. [">"] = "&gt;",
  381. ["&"] = "&amp;",
  382. ["\170"] = "&ordf;",
  383. ["\186"] = "&ordm;",
  384. ["\192"] = "&Agrave;",
  385. ["\193"] = "&Aacute;",
  386. ["\194"] = "&Acirc;",
  387. ["\195"] = "&Atilde;",
  388. ["\199"] = "&Ccedil;",
  389. ["\201"] = "&Eacute;",
  390. ["\202"] = "&Ecirc;",
  391. ["\205"] = "&Iacute;",
  392. ["\211"] = "&Oacute;",
  393. ["\212"] = "&Ocirc;",
  394. ["\218"] = "&Uacute;",
  395. ["\224"] = "&agrave;",
  396. ["\225"] = "&aacute;",
  397. ["\226"] = "&acirc;",
  398. ["\227"] = "&atilde;",
  399. ["\231"] = "&ccedil;",
  400. ["\233"] = "&eacute;",
  401. ["\234"] = "&ecirc;",
  402. ["\237"] = "&iacute;",
  403. ["\243"] = "&oacute;",
  404. ["\244"] = "&ocirc;",
  405. ["\245"] = "&otilde;",
  406. ["\250"] = "&uacute;",
  407. ["\252"] = "&uuml;"
  408. })
  409. t = string.gsub(t, "\n\n+", "\1")
  410. -- complete macros with no arguments
  411. t = string.gsub(t, "(@%w+)([^{%w])", "%1{}%2")
  412. t = trata(t)
  413. -- correct references
  414. t = string.gsub(t, "\3(.-)\3", ref)
  415. -- remove extra space (??)
  416. t = string.gsub(t, "%s*\4%s*", "")
  417. t = nopara(t)
  418. -- HTML 3.2 does not need </p> (but complains when it is in wrong places :)
  419. t = string.gsub(t, "</p>", "")
  420. io.write(header, t, footer)