/山火-ヤギの咆哮-/lib/lua/lua/luadoc/doclet/html.lua

https://gitlab.com/kokeiro001/YamabiYagiNoHoko · Lua · 267 lines · 200 code · 25 blank · 42 comment · 18 complexity · c63a93196104fa96865b52e2ac53a5a3 MD5 · raw file

  1. -------------------------------------------------------------------------------
  2. -- Doclet that generates HTML output. This doclet generates a set of html files
  3. -- based on a group of templates. The main templates are:
  4. -- <ul>
  5. -- <li>index.lp: index of modules and files;</li>
  6. -- <li>file.lp: documentation for a lua file;</li>
  7. -- <li>module.lp: documentation for a lua module;</li>
  8. -- <li>function.lp: documentation for a lua function. This is a
  9. -- sub-template used by the others.</li>
  10. -- </ul>
  11. --
  12. -- @release $Id: html.lua,v 1.29 2007/12/21 17:50:48 tomas Exp $
  13. -------------------------------------------------------------------------------
  14. local assert, getfenv, ipairs, loadstring, pairs, setfenv, tostring, tonumber, type = assert, getfenv, ipairs, loadstring, pairs, setfenv, tostring, tonumber, type
  15. local io = require"io"
  16. local lfs = require "lfs"
  17. local lp = require "luadoc.lp"
  18. local luadoc = require"luadoc"
  19. local package = package
  20. local string = require"string"
  21. local table = require"table"
  22. module "luadoc.doclet.html"
  23. -------------------------------------------------------------------------------
  24. -- Looks for a file `name' in given path. Removed from compat-5.1
  25. -- @param path String with the path.
  26. -- @param name String with the name to look for.
  27. -- @return String with the complete path of the file found
  28. -- or nil in case the file is not found.
  29. local function search (path, name)
  30. for c in string.gfind(path, "[^;]+") do
  31. c = string.gsub(c, "%?", name)
  32. local f = io.open(c)
  33. if f then -- file exist?
  34. f:close()
  35. return c
  36. end
  37. end
  38. return nil -- file not found
  39. end
  40. -------------------------------------------------------------------------------
  41. -- Include the result of a lp template into the current stream.
  42. function include (template, env)
  43. -- template_dir is relative to package.path
  44. local templatepath = options.template_dir .. template
  45. -- search using package.path (modified to search .lp instead of .lua
  46. local search_path = string.gsub(package.path, "%.lua", "")
  47. local templatepath = search(search_path, templatepath)
  48. assert(templatepath, string.format("template `%s' not found", template))
  49. env = env or {}
  50. env.table = table
  51. env.io = io
  52. env.lp = lp
  53. env.ipairs = ipairs
  54. env.tonumber = tonumber
  55. env.tostring = tostring
  56. env.type = type
  57. env.luadoc = luadoc
  58. env.options = options
  59. return lp.include(templatepath, env)
  60. end
  61. -------------------------------------------------------------------------------
  62. -- Returns a link to a html file, appending "../" to the link to make it right.
  63. -- @param html Name of the html file to link to
  64. -- @return link to the html file
  65. function link (html, from)
  66. local h = html
  67. from = from or ""
  68. string.gsub(from, "/", function () h = "../" .. h end)
  69. return h
  70. end
  71. -------------------------------------------------------------------------------
  72. -- Returns the name of the html file to be generated from a module.
  73. -- Files with "lua" or "luadoc" extensions are replaced by "html" extension.
  74. -- @param modulename Name of the module to be processed, may be a .lua file or
  75. -- a .luadoc file.
  76. -- @return name of the generated html file for the module
  77. function module_link (modulename, doc, from)
  78. -- TODO: replace "." by "/" to create directories?
  79. -- TODO: how to deal with module names with "/"?
  80. assert(modulename)
  81. assert(doc)
  82. from = from or ""
  83. if doc.modules[modulename] == nil then
  84. -- logger:error(string.format("unresolved reference to module `%s'", modulename))
  85. return
  86. end
  87. local href = "modules/" .. modulename .. ".html"
  88. string.gsub(from, "/", function () href = "../" .. href end)
  89. return href
  90. end
  91. -------------------------------------------------------------------------------
  92. -- Returns the name of the html file to be generated from a lua(doc) file.
  93. -- Files with "lua" or "luadoc" extensions are replaced by "html" extension.
  94. -- @param to Name of the file to be processed, may be a .lua file or
  95. -- a .luadoc file.
  96. -- @param from path of where am I, based on this we append ..'s to the
  97. -- beginning of path
  98. -- @return name of the generated html file
  99. function file_link (to, from)
  100. assert(to)
  101. from = from or ""
  102. local href = to
  103. href = string.gsub(href, "lua$", "html")
  104. href = string.gsub(href, "luadoc$", "html")
  105. href = "files/" .. href
  106. string.gsub(from, "/", function () href = "../" .. href end)
  107. return href
  108. end
  109. -------------------------------------------------------------------------------
  110. -- Returns a link to a function or to a table
  111. -- @param fname name of the function or table to link to.
  112. -- @param doc documentation table
  113. -- @param kind String specying the kinf of element to link ("functions" or "tables").
  114. function link_to (fname, doc, module_doc, file_doc, from, kind)
  115. assert(fname)
  116. assert(doc)
  117. from = from or ""
  118. kind = kind or "functions"
  119. if file_doc then
  120. for _, func_name in pairs(file_doc[kind]) do
  121. if func_name == fname then
  122. return file_link(file_doc.name, from) .. "#" .. fname
  123. end
  124. end
  125. end
  126. local _, _, modulename, fname = string.find(fname, "^(.-)[%.%:]?([^%.%:]*)$")
  127. assert(fname)
  128. -- if fname does not specify a module, use the module_doc
  129. if string.len(modulename) == 0 and module_doc then
  130. modulename = module_doc.name
  131. end
  132. local module_doc = doc.modules[modulename]
  133. if not module_doc then
  134. -- logger:error(string.format("unresolved reference to function `%s': module `%s' not found", fname, modulename))
  135. return
  136. end
  137. for _, func_name in pairs(module_doc[kind]) do
  138. if func_name == fname then
  139. return module_link(modulename, doc, from) .. "#" .. fname
  140. end
  141. end
  142. -- logger:error(string.format("unresolved reference to function `%s' of module `%s'", fname, modulename))
  143. end
  144. -------------------------------------------------------------------------------
  145. -- Make a link to a file, module or function
  146. function symbol_link (symbol, doc, module_doc, file_doc, from)
  147. assert(symbol)
  148. assert(doc)
  149. local href =
  150. -- file_link(symbol, from) or
  151. module_link(symbol, doc, from) or
  152. link_to(symbol, doc, module_doc, file_doc, from, "functions") or
  153. link_to(symbol, doc, module_doc, file_doc, from, "tables")
  154. if not href then
  155. logger:error(string.format("unresolved reference to symbol `%s'", symbol))
  156. end
  157. return href or ""
  158. end
  159. -------------------------------------------------------------------------------
  160. -- Assembly the output filename for an input file.
  161. -- TODO: change the name of this function
  162. function out_file (filename)
  163. local h = filename
  164. h = string.gsub(h, "lua$", "html")
  165. h = string.gsub(h, "luadoc$", "html")
  166. h = "files/" .. h
  167. -- h = options.output_dir .. string.gsub (h, "^.-([%w_]+%.html)$", "%1")
  168. h = options.output_dir .. h
  169. return h
  170. end
  171. -------------------------------------------------------------------------------
  172. -- Assembly the output filename for a module.
  173. -- TODO: change the name of this function
  174. function out_module (modulename)
  175. local h = modulename .. ".html"
  176. h = "modules/" .. h
  177. h = options.output_dir .. h
  178. return h
  179. end
  180. -----------------------------------------------------------------
  181. -- Generate the output.
  182. -- @param doc Table with the structured documentation.
  183. function start (doc)
  184. -- Generate index file
  185. if (#doc.files > 0 or #doc.modules > 0) and (not options.noindexpage) then
  186. local filename = options.output_dir.."index.html"
  187. logger:info(string.format("generating file `%s'", filename))
  188. local f = lfs.open(filename, "w")
  189. assert(f, string.format("could not open `%s' for writing", filename))
  190. io.output(f)
  191. include("index.lp", { doc = doc })
  192. f:close()
  193. end
  194. -- Process modules
  195. if not options.nomodules then
  196. for _, modulename in ipairs(doc.modules) do
  197. local module_doc = doc.modules[modulename]
  198. -- assembly the filename
  199. local filename = out_module(modulename)
  200. logger:info(string.format("generating file `%s'", filename))
  201. local f = lfs.open(filename, "w")
  202. assert(f, string.format("could not open `%s' for writing", filename))
  203. io.output(f)
  204. include("module.lp", { doc = doc, module_doc = module_doc })
  205. f:close()
  206. end
  207. end
  208. -- Process files
  209. if not options.nofiles then
  210. for _, filepath in ipairs(doc.files) do
  211. local file_doc = doc.files[filepath]
  212. -- assembly the filename
  213. local filename = out_file(file_doc.name)
  214. logger:info(string.format("generating file `%s'", filename))
  215. local f = lfs.open(filename, "w")
  216. assert(f, string.format("could not open `%s' for writing", filename))
  217. io.output(f)
  218. include("file.lp", { doc = doc, file_doc = file_doc} )
  219. f:close()
  220. end
  221. end
  222. -- copy extra files
  223. local f = lfs.open(options.output_dir.."luadoc.css", "w")
  224. io.output(f)
  225. include("luadoc.css")
  226. f:close()
  227. end