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 | |
| parent | refactoring cyclic requires (diff) | |
| download | alive-b0f6006aa5514a6c3b6b105c791355cf9c366883.tar.gz alive-b0f6006aa5514a6c3b6b105c791355cf9c366883.zip | |
add doc generator
| -rw-r--r-- | Makefile | 17 | ||||
| -rw-r--r-- | docs/.gitignore | 1 | ||||
| -rw-r--r-- | docs/style.css | 78 | ||||
| -rw-r--r-- | extra/docs.moon | 45 | ||||
| -rw-r--r-- | extra/dom.moon | 66 | ||||
| -rw-r--r-- | extra/layout.moon | 78 |
6 files changed, 285 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b1d7263 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +MODULES=$(wildcard lib/*.moon) lib/midi/launchctl.moon +MODREFS=$(MODULES:lib/%.moon=docs/reference/%.html) + +.PHONY: docs clean + +docs: $(MODREFS) docs/reference/index.html + +docs/reference/%.html: lib/%.moon extra/docs.moon extra/layout.moon + @echo "building docs for $<" + @mkdir -p `dirname $@` + moon extra/docs.moon $@ module lib.$(*:/=.) $* + +docs/reference/index.html: $(MODREFS) extra/docs.moon extra/layout.moon + moon extra/docs.moon $@ reference $(MODULES) + +clean: + rm -rf docs/reference/* diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..2d19fc7 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +*.html diff --git a/docs/style.css b/docs/style.css new file mode 100644 index 0000000..809ee05 --- /dev/null +++ b/docs/style.css @@ -0,0 +1,78 @@ +html { + margin: 0; + padding: 0; + background: #222222 center center fixed; + background-image: url("data:image/svg+xml,%3Csvg width='30' height='30' viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23606060' fill-opacity='0.4'%3E%3Cpath d='m7.5,9v12h4v-2h-2v-8h2V9Zm11,0v2h2v8h-2v2h4V9Z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); +} + +body { + margin: auto; + width: 640px; + background: #eeeeee; + + font-family: 'Source Sans Pro', sans-serif; + color: #222222; +} + +article { + padding: 3rem 2em 1em; +} + +code { + font-family: 'Source Code Pro', monospace; +} + +h2 { + margin: 0.5em 0 0.25em; +} + +a { + color: inherit; +} + +ul { + list-style: '- '; + margin: 0; + padding-left: 0.6em; +} + +nav { + position: fixed; + width: inherit; + height: 4rem; + top: 0; + padding: 1em 2em 4px; + background: #eeeeee; + box-sizing: border-box; +} + +nav div { + display: flex; + justify-content: space-around; + + border-bottom: 1px solid #222222; + padding-bottom: 1em; +} + +nav i { + flex: 1; +} + +nav a { + margin-left: 1rem; +} + +.def { + margin-top: 0.5rem; +} + +.nest { + margin: 0.25rem 0.25rem 0 0; + padding-left: 0.75rem; + border-left: 1px solid #222222; +} + +.nest > p { + margin: 0; + white-space: pre-wrap; +} 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 +} |
