diff --git a/make-docs.fnl b/make-docs.fnl index 5696195..97c07d8 100644 --- a/make-docs.fnl +++ b/make-docs.fnl @@ -1,39 +1,86 @@ -"work in progress script to generate /src/fennel-ls/docs/lua54.fnl automatically" -(local {: view} (require :fennel)) -(local version "5.4") -(local filename (.. "lua" version ".html")) -(var file (io.open filename :r)) -(when (not file) - ;; I think the repos also have the html file (or the ability to generate it, depending on lua version) - ;; but for simplicity I'm just grabbing the html straight from the website - (os.execute (.. "curl https://www.lua.org/manual/" version "/manual.html > lua" version ".html")) - (set file (io.open filename :r))) +"Script to generate /src/fennel-ls/docs/lua54.fnl and friends automatically" -(local html (file:read :a)) +(fn open-file-cached [filename url] + (var file (io.open filename :r)) + (when (not file) + ;; I think the repos also have the html file (or the ability to generate it, depending on lua version) + ;; but for simplicity I'm just grabbing the html straight from the website + (print (.. "Downloading " url)) + (os.execute (.. "curl " url " > " filename)) + (set file (io.open filename :r))) + file) -;; The section of the html about the standard library -(local begin-index (assert (html:find "
tags
+ (: :gsub "?p>" "")
+ ;; tags
- description (description:gsub "?p>" "")
- ;; trim whitespace
- description (description:match "^%s*(.-)%s*$")
;; tags for the rest
+ (: :gsub "\"(.-)\"" "`\"%1\"`")
+ (: :gsub "\'(.-)\'" "`\"%1\"`")
+ (: :gsub "(.-)" "`%1`")
+ (: :gsub "x" "ˣ")
+ (: :gsub "e" "ᵉ")
+ (: :gsub "y" "ʸ")
+ (: :gsub "51" "⁵¹")
+ (: :gsub "32" "³²")
+ ; ᵃᵇᶜᵈᵉᶠᵍʰⁱʲᵏˡᵐⁿᵒᵖ𐞥ʳˢᵗᵘᵛʷˣʸᶻ
+ ;; bold to **
+ (: :gsub "([^<]+)" "*%1*")
+ (: :gsub "([^<]+)" "**%1**")
+ ;; defeat all the links
+ (: :gsub "([^<]+)" "%1")
+ (: :gsub "([^<]+)" "%1")
+ (: :gsub "([^<]+)" "%1")
+ (: :gsub "See [^<]+[^%.]+%." "")
+ (: :gsub "[ \n]%(see [^<]+%)." "")
+ (: :gsub "[ \n]%([^<]+%)." "")
+ ;; code blocks
+ (: :gsub "\n?([^<]+)\n?
" "```lua\n%1\n```")
+ ;; list items to indented * thingies
+ (: :gsub ".-\n" (+ prev 1))
- section (stdlib:sub prev (if header (- header 1)))]
- (let [index (section:find "
")]
- (if index
- (do
- (table.insert module-items (section:sub 1 (- index 1)))
- (table.insert modules (section:sub index)))
- (table.insert module-items section)))
- (when header (loop header))))
-(loop (stdlib:find "
.-\n"))
-
-;; I should probably split more of this file into functions like this
-(fn process-html-thing [html-describing-the-thing]
- (let [(header description) (html-describing-the-thing:match "^(.-)\n+(.-)\n*$")
+(fn parse-h3-section [html]
+ "parse a section that starts with an h3 tag. These are individual functions/variables."
+ (let [(header description) (html:match "^(.-)\n+(.-)\n*$")
optional-args []
signature (header:match "
(.-)")
;; strip commas
@@ -60,38 +107,80 @@
signature (signature:gsub " +" " ")
signature (signature:gsub " +%)" ")")
- ;; delete tags for optional args
description (accumulate [description description _ arg (ipairs optional-args)]
(description:gsub (.. "" arg "")
(.. "`?" arg "`")))
- ;; tags for the rest
- description (description:gsub "\"(.-)\"" "`\"%1\"`")
- description (description:gsub "\'(.-)\'" "`\"%1\"`")
- description (description:gsub "(.-)" "`%1`")
- description (description:gsub " " " ")
- description (description:gsub "–" "–")
- description (description:gsub "—" "—")
+ ;; trim off the string pattern and string.pack/string.unpack format docs
+ description (description:gsub "\n[^\n]*.*" "")
+ description (html-to-markdown description)
name (signature:match "[^() ]+")
key (name:match "[^.:]+$")
?module (and (name:find "[.:]") (name:match "^[^.:]+"))]
- (assert (not (signature:find "[%[%]]")) (.. "bad signature " signature))
- ;; Debug prints for now.
- (when (not ?module)
- (print
- (.. (view ?module)
- (view key)
- " "
- (view {:binding (signature:match "[^() ]+")
- :metadata {:fnl/docstring description}}))))))
+ (values ?module
+ key
+ {:binding (signature:match "[^() ]+")
+ :metadata {:fnl/docstring description}})))
+
+(fn parse-h2-section [html]
+ "parse a section that starts with an h2 tag. These are the main modules."
+ (let [(title description) (html:match "(.-)\n(.*)")
+ module-name (if (title:find "Coroutine")
+ "coroutine"
+ (title:find "Modules")
+ "package"
+ (title:find "String")
+ "string"
+ (title:find "UTF")
+ "utf8"
+ (title:find "Mathematical")
+ "math"
+ (title:find "Input and Output")
+ "io"
+ (title:find "Operating System")
+ "os"
+ (title:find "Debug")
+ "debug"
+ (title:find "Bitwise")
+ "bit32"
+ (title:find "Table")
+ "table")
+ description (html-to-markdown description)]
+ (assert module-name title)
+ (values module-name
+ {:binding module-name
+ :fields {}
+ :metadata {:fnl/docstring description}})))
-(var done false)
-(each [_ section (ipairs module-items) &until done]
- (process-html-thing section))
- ; (if (= (io.read) "done")
- ; (set done true)))
+(fn main []
+ (each [_ version (ipairs [:5.1 :5.2 :5.3 :5.4])]
+ (let [infile (open-file-cached
+ (.. "lua" version ".html")
+ (.. "https://www.lua.org/manual/" version "/manual.html"))
+ (modules module-items) (parse-html (infile:read :a))
+ docs
+ (collect [_ module (ipairs modules)]
+ (parse-h2-section module))]
+
+ (each [_ section (ipairs module-items)]
+ (let [(mod k v) (parse-h3-section section)]
+ (if (not mod)
+ (tset docs k v)
+ (not= mod "file")
+ (do
+ (assert (. docs mod) (.. mod " not found"))
+ (tset (. docs mod :fields) k v)))))
+
+ (print (.. "Emitting docs for lua" version))
+ (let [outfile (io.open (.. "src/fennel-ls/docs/lua" (version:gsub "%." "") ".fnl") :w)]
+ (local {: view : sym : list} (require :fennel))
+ (outfile:write
+ (view (list (sym :local) (sym :docs) docs))
+ "\n"
+ "(set docs._G.fields docs)\n"
+ "docs\n"))
+ (print (.. "Emitted docs for lua" version)))))
+
+(main)