version = require 'alv.version' dom = require 'docs.gen.dom' import compile from require 'discount' import opairs from require 'alv.util' 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 a Result to a HTML string render = (name, result, prefix=nil, index=false) -> import div, label, code, ul, li, i, a, pre from dom prefix = if prefix then prefix .. "/" else "" id = prefix .. name typestr = i tostring result.type assert result.meta, "#{id} doesn't have any metadata!" summary = assert result.meta.summary, "#{id} doesn't have a summary!" if result.meta.name != name summary = i "alias of ", a (code result.meta.name), href: "##{prefix}#{result.meta.name}" if index div { label (a (code name), href: "##{id}"), ' (', typestr, '):  – ' summary } else content = switch tostring result.type when 'scope' ul for k, node in opairs result!.values li render k, node.result, id else render_meta result.meta content.class = 'nest' div { :id, class: 'def' label (a (code name), href: "##{id}"), ' (', typestr, '):  – ' 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.git if ref == '*git*' return version.repo if ref == '*repo*' return version.release if ref == '*release*' mod, sym = ref\match '^(.+)/(.*)$' if mod abs "reference/module/#{mod}.html##{sym or ref}" else abs "reference/builtins.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 subnav = do split_name = (file) -> if href = file\match '^docs/(.*/index.html)$' return 'index', href href, label = file\match '^docs/(.*/([%d%w-_]+)%.html)$' label = (label\match '^[%d-]+_([%w-]+)$') or label label = label\gsub '-', ' ' label, href title = (file) -> if file == 'docs/guide/index.html' return "getting started guide" if file == 'docs/reference/index.html' return "alv language reference" elseif mod = file\match '^docs/reference/module/(.*)%.html$' return "#{mod} module reference" elseif href = file\match '^docs/(.*/index.html)$' error "index page without hardcoded name: #{href}" num, label = file\match '/([%d-]+)_([%w%-]+)%.html$' if num num = num\gsub '%f[%d]0', '' num = num\gsub '-', '.' label = label\gsub '-', ' ' "#{num}. #{label}" else (file\match '/([%w%-]+)%.html$') subnav_link = (dir, file) -> import span, a, u from dom if not file return span '' label, href = split_name file label = switch dir when 'l' "◂ back: #{u label}" when 'r' "next: #{u label} ▸" a label, href: abs href (all) -> assert OUT, "OUT needs to be set" import div, nav, h1 from dom local c for i, src in ipairs all if OUT == src c = i break div { class: 'subheader' h1 (title OUT) nav { subnav_link 'l', all[c-1] subnav_link 'r', all[c+1] } } aopts = (href, pat) -> { href: abs href class: if OUT\match 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', '^docs/index.html$' a 'guide', aopts 'guide/index.html', '^docs/guide' a 'reference', aopts 'reference/index.html', '^docs/reference' a 'internals', aopts 'internals/index.html', '^docs/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 :subnav }