1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
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 ''}
<!DOCTYPE html>
<html>
<head>
<meta charset=\"UTF-8\">
<meta name=\"viewport\" content=\"width=640\">
<title>#{title}</title>
<link rel=\"stylesheet\" href=\"#{opts.style or abs 'style.css'}\">
</head>
<body>
#{head}
#{body}
#{foot}
</body>
</html>"
{
:autoref
:render
:layout
}
|