lua

A copy of the Lua development repository
Log | Files | Refs | README

2html (11915B)


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