diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-03-03 15:56:23 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2020-03-05 10:36:33 +0000 |
| commit | b0f6006aa5514a6c3b6b105c791355cf9c366883 (patch) | |
| tree | 09d19b698d1c6bc41c69e6dea5ffd90e6d88c1c2 /extra | |
| parent | refactoring cyclic requires (diff) | |
| download | alive-b0f6006aa5514a6c3b6b105c791355cf9c366883.tar.gz alive-b0f6006aa5514a6c3b6b105c791355cf9c366883.zip | |
add doc generator
Diffstat (limited to 'extra')
| -rw-r--r-- | extra/docs.moon | 45 | ||||
| -rw-r--r-- | extra/dom.moon | 66 | ||||
| -rw-r--r-- | extra/layout.moon | 78 |
3 files changed, 189 insertions, 0 deletions
diff --git a/extra/docs.moon b/extra/docs.moon new file mode 100644 index 0000000..a8438cf --- /dev/null +++ b/extra/docs.moon @@ -0,0 +1,45 @@ +import Value, Scope from require 'core' +import render, write from require 'extra.layout' +import section, h2, p, ul, li, a, code, r from require 'extra.dom' + +export OUT +{ OUT, command } = arg + +write switch command + when 'module' + { _, _, module, name } = arg + + name or= module + module = Scope.from_table require module + + title: "#{name} module reference" + body: section { + h2 (code name), ' reference' + ul for key, res in pairs module.values + li render key, res.value + } + + when 'reference' + title: 'reference index' + body: { + section { + id: 'modules' + h2 a "module index", href: '#modules' + p "These modules can be imported using #{r 'require'}, #{r 'import'} and " .. + "#{r 'import*'}." + ul for file in *arg[3,] + module = file\match '^lib/(.*)%.moon$' + li a (code module), href: "#{module}.html" + } + section { + id: 'builtins' + h2 a "builtins", href: '#builtins' + p "These definitions are automatically loaded into the global Scope of + every alive session." + ul for key, val in pairs require 'core.builtin' + li render key, Value.wrap val + } + } + + else + error "unknown command '#{command}'" diff --git a/extra/dom.moon b/extra/dom.moon new file mode 100644 index 0000000..73dc743 --- /dev/null +++ b/extra/dom.moon @@ -0,0 +1,66 @@ +-- mmm.dom +-- see https://mmm.s-ol.nu/meta/mmm.dom/ + +-- ordered table iterator, for stable(r) renderers +sort = (t, order_fn, only_strings) -> + with index = [k for k,v in pairs t when (not only_strings) or 'string' == type k] + table.sort index, order_fn + +-- ordered next(t) +onext = (state, key) -> + state.i += state.step + { :t, :index, :i } = state + + if key = index[i] + key, t[key] + +-- ordered pairs(t). +-- order_fn is optional; see table.sort +opairs = (t, order_fn, only_strings=false) -> + state = { :t, i: 0, step: 1, index: sort t, order_fn, only_strings } + onext, state, nil + +void_tags = { 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr' } +void_tags = { t,t for t in *void_tags } + +element = (element) -> (...) -> + children = { ... } + + -- attributes are last arguments but mustn't be a ReactiveVar + attributes = children[#children] + if 'table' == (type attributes) and not attributes.node + table.remove children + else + attributes = {} + + b = "<#{element}" + for k,v in opairs attributes, nil, true + if k == 'style' and 'table' == type v + tmp = '' + for kk, vv in opairs v + tmp ..= "#{kk}: #{vv}; " + v = tmp + b ..= " #{k}=\"#{v}\"" + + -- if there is only one argument, + -- children can be in attributes table too + if #children == 0 + children = attributes + + for i,v in ipairs children + if 'string' != type v + print v + error "wrong type: #{type v}" + children[i] = '' unless v + + if void_tags[element] + assert #children == 0, "void tag #{element} cannot have children!" + b .. ">" + else + b ..= ">" .. table.concat children, '' + b ..= "</#{element}>" + b + +setmetatable {}, __index: (name) => + with val = element name + @[name] = val diff --git a/extra/layout.moon b/extra/layout.moon new file mode 100644 index 0000000..1a4ee7b --- /dev/null +++ b/extra/layout.moon @@ -0,0 +1,78 @@ +-- render an ALV Value to a HTML string +render = (name, value, prefix=nil) -> + import div, label, code, ul, li, i, a, p from require 'extra.dom' + + id = if prefix then "#{prefix}/#{name}" else name + type = i value.type + + content = switch value.type + when 'scope' + ul for k, result in pairs value!.values + li render k, result.value, id + when 'opdef', 'builtin' + p value!.doc + when 'num', 'str', 'bool' + code tostring value! + + div { + :id, class: 'def' + label (a (code name), :id, href: "##{id}"), ' (', type, '):' + div content, class: 'nest' + } + +-- generate a relative link +abs = (page) -> + assert OUT, "OUT needs to be set" + relative = assert (OUT\match '^docs/(.*)'), "unexpected output path" + _, depth = relative\gsub '/', '/' + up = string.rep '../', depth + "#{up}#{page}" + +-- link to a reference +r = (name, page='') -> + import a, code from require 'extra.dom' + a (code name), href: "#{page}##{name}" + +spit = (file, str) -> + file = io.open file, 'w' + file\write str + file\close! + +-- layout and write a doc page +-- opts: +-- - title +-- - body +write = (opts) -> + import nav, div, span, b, code, i, a, article from require 'extra.dom' + + navigation = nav div { + span (b 'alive'), ' ', (code 'v0.0'), ' documentation' + i! + a 'home', href: abs 'index.html' + a 'getting started', href: abs 'guide.html' + a 'reference', href: abs 'reference/index.html' + } + body = article opts.body + + assert OUT, "OUT needs to be set" + spit OUT, "<!DOCTYPE html> +<html> + <head> + <title>#{opts.title} - alive docs</title> + <link rel=\"stylesheet\" href=\"#{abs 'style.css'}\"> + <style> + + </style> + </head> + <body> + #{navigation} + #{body} + </body> +</html>" + + +{ + :r + :render + :write +} |
