From aedd7f485397b322fc88c60241fa1e5e684fd2b4 Mon Sep 17 00:00:00 2001 From: s-ol Date: Fri, 17 Apr 2020 16:08:45 +0200 Subject: move extra/ to docs/gen/ and split up --- Makefile | 23 +++-- docs/gen/dom.moon | 68 +++++++++++++ docs/gen/git-version | 25 +++++ docs/gen/index | 48 +++++++++ docs/gen/layout.moon | 149 ++++++++++++++++++++++++++++ docs/gen/ldoc | 196 +++++++++++++++++++++++++++++++++++++ docs/gen/md | 23 +++++ docs/gen/module | 40 ++++++++ extra/docs.moon | 270 --------------------------------------------------- extra/dom.moon | 68 ------------- extra/git-version.sh | 25 ----- extra/layout.moon | 150 ---------------------------- 12 files changed, 563 insertions(+), 522 deletions(-) create mode 100644 docs/gen/dom.moon create mode 100755 docs/gen/git-version create mode 100755 docs/gen/index create mode 100644 docs/gen/layout.moon create mode 100755 docs/gen/ldoc create mode 100755 docs/gen/md create mode 100755 docs/gen/module delete mode 100644 extra/docs.moon delete mode 100644 extra/dom.moon delete mode 100755 extra/git-version.sh delete mode 100644 extra/layout.moon diff --git a/Makefile b/Makefile index 3f3dfff..b6ac592 100644 --- a/Makefile +++ b/Makefile @@ -1,35 +1,40 @@ MODULES=$(wildcard alv-lib/*.moon) alv-lib/midi/launchctl.moon MODREFS=$(MODULES:alv-lib/%.moon=docs/reference/%.html) CORE=$(wildcard alv/*.moon alv/**/*.moon) $(wildcard alv/*.md) -DEPS=alv/version.moon extra/docs.moon extra/layout.moon extra/dom.moon +DEPS=alv/version.moon $(wildcard docs/gen/*.moon) -.PHONY: docs reference internals release clean +.PHONY: docs test release clean reference internals docs: docs/index.html docs/guide.html reference internals -reference: $(MODREFS) docs/reference/index.html -internals: docs/internals/index.html + +test: + busted release: rm -f alv/version.moon - extra/git-version.sh >alv/version.moon + docs/gen/git-version >alv/version.moon + +# docs parts +reference: $(MODREFS) docs/reference/index.html +internals: docs/internals/index.html docs/%.html: docs/%.md $(DEPS) @echo "building page $<" - moon extra/docs.moon $@ markdown $< + docs/gen/md $@ $< docs/reference/%.html: alv-lib/%.moon $(DEPS) @echo "building docs for $<" @mkdir -p `dirname $@` - moon extra/docs.moon $@ module alv-lib.$(subst /,.,$*) $(subst /,.,$*) + docs/gen/module $@ alv-lib.$(subst /,.,$*) $(subst /,.,$*) docs/reference/index.html: $(MODREFS) $(DEPS) - moon extra/docs.moon $@ reference $(MODULES) + docs/gen/index $@ $(MODULES) docs/ldoc.css: docs/style.css cp $< $@ docs/ldoc.ltp: $(DEPS) - moon extra/docs.moon $@ ldoc + docs/gen/ldoc $@ docs/internals/index.html: alv/config.ld docs/ldoc.ltp docs/ldoc.css $(CORE) ldoc alv diff --git a/docs/gen/dom.moon b/docs/gen/dom.moon new file mode 100644 index 0000000..7541fbd --- /dev/null +++ b/docs/gen/dom.moon @@ -0,0 +1,68 @@ +-- mmm.dom +-- see https://mmm.s-ol.nu/meta/mmm.dom/ + +export opairs + +-- 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 ..= "" + b + +setmetatable {}, __index: (name) => + with val = element name + @[name] = val diff --git a/docs/gen/git-version b/docs/gen/git-version new file mode 100755 index 0000000..495b679 --- /dev/null +++ b/docs/gen/git-version @@ -0,0 +1,25 @@ +#!/bin/sh + +TAG=$(git describe --abbrev=0 HEAD) +# REV_SHORT=$(git rev-parse --short HEAD) +# REV_LONG=$(git rev-parse HEAD) + +cat < + file = io.open file, 'r' + with file\read '*all' + file\close! + +spit = (file, str) -> + file = io.open file, 'w' + file\write str + file\close! + +{ OUT } = arg + +spit OUT, layout + title: 'reference' + body: { + h1 (code 'alive'), " language reference" + p "This section documents all builtins and modules that are currently + available in the alive programming language." + p autoref "If you are new to alive, the [getting started guide][:../guide/:] is + the recommended place to start. If you are looking for + information on adding your own module or contributing to alive, check + out the [developer documentation][:../internals/index/:]." + section { + id: 'modules' + h2 a "module index", href: '#modules' + p autoref "These modules can be imported using [require][], " .. + "[import][] and [import*][]." + ul for file in *arg[2,] + path = file\match '^alv%-lib/(.*)%.moon$' + name = path\gsub '/', '.' + li a (code name), href: "#{path}.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 opairs require 'alv.builtin' + li render key, ValueStream.wrap val + } + } diff --git a/docs/gen/layout.moon b/docs/gen/layout.moon new file mode 100644 index 0000000..084807e --- /dev/null +++ b/docs/gen/layout.moon @@ -0,0 +1,149 @@ +version = require 'alv.version' +dom = require 'docs.gen.dom' +import compile from require 'discount' + +render_meta = (meta) -> + import p, code from dom + contents = {} + if meta.examples + -- table.insert contents, h4 'signature' + examples = p table.concat [code e for e in *meta.examples], ' ' + table.insert contents, examples + if meta.description + description = compile meta.description\match '^\n*(.+)\n*$' + table.insert contents, description.body + + contents + +-- render an ALV Value to a HTML string +render = (name, value, prefix=nil, index=false) -> + import div, label, code, ul, li, i, a, pre from dom + + id = if prefix then "#{prefix}/#{name}" else name + type = i value.type + assert value.meta, "#{id} doesn't have any metadata!" + summary = assert value.meta.summary, "#{id} doesn't have a summary!" + + if index + div { + label (a (code name), href: "##{id}"), ' (', type, '):  – ' + summary + } + else + content = switch value.type + when 'scope' + ul for k, result in opairs value!.values + li render k, result.value, id + else + render_meta value.meta + + content.class = 'nest' + div { + :id, class: 'def' + label (a (code name), href: "##{id}"), ' (', type, '):  – ' + summary + div content + } + +-- generate a relative link +abs = (page) -> + if BASE + "#{BASE}#{page}" + else + assert OUT, "OUT needs to be set" + relative = assert (OUT\match '^docs/(.*)'), "unexpected output path" + _, depth = relative\gsub '/', '/' + up = string.rep '../', depth + "#{up}#{page}" + +-- generate a link to a reference entry +-- entry is one of +-- builtin-name; mod.name/name; mod.name +link = (ref) -> + return version.web if ref == '*web*' + return version.repo if ref == '*repo*' + return version.release if ref == '*release*' + + mod, sym = ref\match '^(.+)/(.*)$' + abs "reference/#{mod or 'index'}.html##{sym or ref}" + +-- link to a reference +r = (text, ref) -> + import a, code from dom + href = link ref or text + if ref + a text, :href + else + text = text\gsub '/$', '' + escape = ESCAPE or (i) -> i + a (code escape text), :href + +-- substitute markdown-style reference links +autoref = (str) -> + str = str\gsub '%[([^%]]-)%]%[%]', r + str = str\gsub '%[([^%]]-)%]%[:(.-):%]', r + str + +aopts = (href, pat) -> + { + href: abs href + class: if OUT\match "^docs/#{pat}" then 'active' + } + +-- layout and write a doc page +-- opts: +-- - preamble +-- - title +-- - style +-- - body (str or table) +layout = (opts) -> + import header, footer, nav, div, span, b, code, a, article from dom + + head = header nav { + span { + b 'alive' + ' ' + a (code version.tag), href: version.release + ' documentation' + } + div class: 'grow' + a 'home', aopts 'index.html', 'index.html$' + a 'getting started', aopts 'guide.html', 'guide.html$' + a 'reference', aopts 'reference/index.html', 'reference' + a 'internals', aopts 'internals/index.html', 'ldoc' + } + body = article opts.body + title = if opts.title + "#{opts.title} - alive" + else + "alive documentation" + foot = footer div { + 'alive ' + a (code version.tag), href: version.release + ', generated ' + os.date '!%Y-%m-%d %T' + } + + "#{opts.preamble or ''} + + + + + + + #{title} + + + + #{head} + #{body} + #{foot} + +" + + +{ + :autoref + :render + :layout +} diff --git a/docs/gen/ldoc b/docs/gen/ldoc new file mode 100755 index 0000000..b75740d --- /dev/null +++ b/docs/gen/ldoc @@ -0,0 +1,196 @@ +#!/usr/bin/env moon +import layout from require 'docs.gen.layout' + +export OUT, BASE + +spit = (file, str) -> + file = io.open file, 'w' + file\write str + file\close! + +{ OUT } = arg +BASE = '$(base)' + +spit OUT, layout + style: '$(ldoc.css)' + title: '$(ldoc.title)' + class: 'ldoc' + preamble: ' +# local iter = ldoc.modules.iter +# local M = ldoc.markup +# local function display_name(item) +# if item.type == "function" then +# return item.name:gsub(":new$", "")..item.args +# else return item.name end +# end +# local function use_li(ls) +# if #ls > 1 then return "
  • ","
  • " else return "","" end +# end +# local base = module and "../../" or "../"' + body: { + class: 'ldoc' + ' +# if ldoc.body then + $(ldoc.body) +# elseif not module then +# if ldoc.description then +

    $(M(ldoc.description))

    +# end +# if ldoc.full_description then +

    $(M(ldoc.full_description))

    +#end + +# for kind, mods in ldoc.kinds() do +# kind = kind:lower() +

    $(kind)

    + +# end +# else +

    $(ldoc.module_typename(module):lower()) $(module.name)

    +

    $(M(module.summary, module))

    +

    $(M(module.description, module))

    + +# if module.see then +# local li,il = use_li(module.see) +

    see also:

    + +# end + +# if module.kinds()() then +

    index

    +# for kind, items in module.kinds() do +# kind = kind:lower() +

    $(kind)

    + +# end + +

    details

    +# for kind, items in module.kinds() do +# kind = kind:lower() +

    $(kind)

    + +# end +# end +# end +' + } diff --git a/docs/gen/md b/docs/gen/md new file mode 100755 index 0000000..32d4fdd --- /dev/null +++ b/docs/gen/md @@ -0,0 +1,23 @@ +#!/usr/bin/env moon +import layout, autoref from require 'docs.gen.layout' +import compile from require 'discount' + +export OUT, ESCAPE + +slurp = (file) -> + file = io.open file, 'r' + with file\read '*all' + file\close! + +spit = (file, str) -> + file = io.open file, 'w' + file\write str + file\close! + +ESCAPE = (str) -> + (str\gsub '([*`])', '\\%1') + +{ OUT, file } = arg + +contents = slurp file +spit OUT, layout compile (autoref contents), 'githubtags', 'fencedcode' diff --git a/docs/gen/module b/docs/gen/module new file mode 100755 index 0000000..143e3fe --- /dev/null +++ b/docs/gen/module @@ -0,0 +1,40 @@ +#!/usr/bin/env moon +import Scope from require 'alv' +import render, layout from require 'docs.gen.layout' +import section, h2, h3, ul, li, code from require 'docs.gen.dom' + +export OUT, require + +require = do + old_require = require + blacklist = {k, true for k in *{'osc', 'socket', 'system', 'luartmidi'}} + (mod, ...) -> + return {} if blacklist[mod] + old_require mod, ... + +slurp = (file) -> + file = io.open file, 'r' + with file\read '*all' + file\close! + +spit = (file, str) -> + file = io.open file, 'w' + file\write str + file\close! + +{ OUT, module, name } = arg + +name or= module +module = Scope.from_table require module + +spit OUT, layout + title: "#{name} reference" + body: section { + h2 (code name), ' module reference' + h3 'index' + ul for key, res in opairs module.values + li render key, res.value, nil, true + h3 'details' + ul for key, res in opairs module.values + li render key, res.value + } diff --git a/extra/docs.moon b/extra/docs.moon deleted file mode 100644 index 6ed5ea0..0000000 --- a/extra/docs.moon +++ /dev/null @@ -1,270 +0,0 @@ -import ValueStream, Scope from require 'alv' -import render, layout, autoref from require 'extra.layout' -import section, h1, h2, h3, p, ul, li, a, code, r from require 'extra.dom' - -export OUT, BASE, require -{ OUT, command } = arg - -slurp = (file) -> - file = io.open file, 'r' - with file\read '*all' - file\close! - -spit = (file, str) -> - file = io.open file, 'w' - file\write str - file\close! - -spit OUT, switch command - when 'module' - { _, _, module, name } = arg - - require = do - old_require = require - blacklist = {k, true for k in *{'osc', 'socket', 'system', 'luartmidi'}} - (mod, ...) -> - return {} if blacklist[mod] - old_require mod, ... - - name or= module - module = Scope.from_table require module - - layout - title: "#{name} reference" - body: section { - h2 (code name), ' module reference' - h3 'index' - ul for key, res in opairs module.values - li render key, res.value, nil, true - h3 'details' - ul for key, res in opairs module.values - li render key, res.value - } - - when 'reference' - layout - title: 'reference' - body: { - h1 (code 'alive'), " language reference" - p "This section documents all builtins and modules that are currently - available in the alive programming language." - p autoref "If you are new to alive, the [getting started guide][:../guide/:] is - the recommended place to start. If you are looking for - information on adding your own module or contributing to alive, check - out the [developer documentation][:../internals/index/:]." - section { - id: 'modules' - h2 a "module index", href: '#modules' - p autoref "These modules can be imported using [require][], " .. - "[import][] and [import*][]." - ul for file in *arg[3,] - path = file\match '^alv%-lib/(.*)%.moon$' - name = path\gsub '/', '.' - li a (code name), href: "#{path}.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 opairs require 'alv.builtin' - li render key, ValueStream.wrap val - } - } - - when 'markdown' - import compile from require 'discount' - - { _, _, file } = arg - contents = slurp file - require 'discount' - - layout compile (autoref contents), 'githubtags', 'fencedcode' - - when 'ldoc' - BASE = '$(base)' - layout - style: '$(ldoc.css)' - title: '$(ldoc.title)' - class: 'ldoc' - preamble: ' -# local iter = ldoc.modules.iter -# local M = ldoc.markup -# local function display_name(item) -# if item.type == "function" then -# return item.name:gsub(":new$", "")..item.args -# else return item.name end -# end -# local function use_li(ls) -# if #ls > 1 then return "
  • ","
  • " else return "","" end -# end -# local base = module and "../../" or "../"' - body: { - class: 'ldoc' - ' -# if ldoc.body then - $(ldoc.body) -# elseif not module then -# if ldoc.description then -

    $(M(ldoc.description))

    -# end -# if ldoc.full_description then -

    $(M(ldoc.full_description))

    -#end - -# for kind, mods in ldoc.kinds() do -# kind = kind:lower() -

    $(kind)

    - -# end -# else -

    $(ldoc.module_typename(module):lower()) $(module.name)

    -

    $(M(module.summary, module))

    -

    $(M(module.description, module))

    - -# if module.see then -# local li,il = use_li(module.see) -

    see also:

    - -# end - -# if module.kinds()() then -

    index

    -# for kind, items in module.kinds() do -# kind = kind:lower() -

    $(kind)

    - -# end - -

    details

    -# for kind, items in module.kinds() do -# kind = kind:lower() -

    $(kind)

    - -# end -# end -# end -' - } - else - error "unknown command '#{command}'" diff --git a/extra/dom.moon b/extra/dom.moon deleted file mode 100644 index 7541fbd..0000000 --- a/extra/dom.moon +++ /dev/null @@ -1,68 +0,0 @@ --- mmm.dom --- see https://mmm.s-ol.nu/meta/mmm.dom/ - -export opairs - --- 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 ..= "" - b - -setmetatable {}, __index: (name) => - with val = element name - @[name] = val diff --git a/extra/git-version.sh b/extra/git-version.sh deleted file mode 100755 index 495b679..0000000 --- a/extra/git-version.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -TAG=$(git describe --abbrev=0 HEAD) -# REV_SHORT=$(git rev-parse --short HEAD) -# REV_LONG=$(git rev-parse HEAD) - -cat < - import p, code from require 'extra.dom' - contents = {} - if meta.examples - -- table.insert contents, h4 'signature' - examples = p table.concat [code e for e in *meta.examples], ' ' - table.insert contents, examples - if meta.description - description = compile meta.description\match '^\n*(.+)\n*$' - table.insert contents, description.body - - contents - --- render an ALV Value to a HTML string -render = (name, value, prefix=nil, index=false) -> - import div, label, code, ul, li, i, a, pre from require 'extra.dom' - - id = if prefix then "#{prefix}/#{name}" else name - type = i value.type - assert value.meta, "#{id} doesn't have any metadata!" - summary = assert value.meta.summary, "#{id} doesn't have a summary!" - - if index - div { - label (a (code name), href: "##{id}"), ' (', type, '):  – ' - summary - } - else - content = switch value.type - when 'scope' - ul for k, result in opairs value!.values - li render k, result.value, id - else - render_meta value.meta - - content.class = 'nest' - div { - :id, class: 'def' - label (a (code name), href: "##{id}"), ' (', type, '):  – ' - summary - div content - } - --- generate a relative link -abs = (page) -> - if BASE - "#{BASE}#{page}" - else - assert OUT, "OUT needs to be set" - relative = assert (OUT\match '^docs/(.*)'), "unexpected output path" - _, depth = relative\gsub '/', '/' - up = string.rep '../', depth - "#{up}#{page}" - --- generate a link to a reference entry --- entry is one of --- builtin-name; mod.name/name; mod.name -link = (ref) -> - return version.web if ref == '*web*' - return version.repo if ref == '*repo*' - return version.release if ref == '*release*' - - mod, sym = ref\match '^(.+)/(.*)$' - abs "reference/#{mod or 'index'}.html##{sym or ref}" - -escape = (str) -> - (str\gsub '([*`])', '\\%1') - --- link to a reference -r = (text, ref) -> - import a, code from require 'extra.dom' - href = link ref or text - if ref - a text, :href - else - text = text\gsub '/$', '' - a (code escape text), :href - --- substitute markdown-style reference links -autoref = (str) -> - str = str\gsub '%[([^%]]-)%]%[%]', r - str = str\gsub '%[([^%]]-)%]%[:(.-):%]', r - str - -aopts = (href, pat) -> - { - href: abs href - class: if OUT\match "^docs/#{pat}" then 'active' - } - --- layout and write a doc page --- opts: --- - preamble --- - title --- - style --- - body (str or table) -layout = (opts) -> - import header, footer, nav, div, span, b, code, a, article from require 'extra.dom' - - head = header nav { - span { - b 'alive' - ' ' - a (code version.tag), href: version.release - ' documentation' - } - div class: 'grow' - a 'home', aopts 'index.html', 'index.html$' - a 'getting started', aopts 'guide.html', 'guide.html$' - a 'reference', aopts 'reference/index.html', 'reference' - a 'internals', aopts 'internals/index.html', 'ldoc' - } - body = article opts.body - title = if opts.title - "#{opts.title} - alive" - else - "alive documentation" - foot = footer div { - 'alive ' - a (code version.tag), href: version.release - ', generated ' - os.date '!%Y-%m-%d %T' - } - - "#{opts.preamble or ''} - - - - - - - #{title} - - - - #{head} - #{body} - #{foot} - -" - - -{ - :autoref - :render - :layout -} -- cgit v1.2.3