git.s-ol.nu alive / 2c4531c
autoref, styling s-ol 1 year, 10 months ago
5 changed file(s) with 87 addition(s) and 56 deletion(s). Raw diff Collapse all Expand all
1616 docs/reference/%.html: lib/%.moon $(DEPS)
1717 @echo "building docs for $<"
1818 @mkdir -p `dirname $@`
19 moon extra/docs.moon $@ module lib.$(*:/=.) $*
19 moon extra/docs.moon $@ module lib.$(subst /,.,$*) $(subst /,.,$*)
2020
2121 docs/reference/index.html: $(MODREFS) $(DEPS)
2222 moon extra/docs.moon $@ reference $(MODULES)
66 itself does not create neither sound nor video. Rather, `alive` is used
77 together with other tools and synthesizers like [SuperCollider][supercollider],
88 [Pilot][pilot] and many more. `alive` takes the role of a 'conductor', telling
9 the other tools what to play when by sending commands to them using a variety of
10 protocols (such as OSC and MIDI).
9 the other tools what to play when by sending commands to them using a variety
10 of protocols (such as OSC and MIDI).
1111
1212 Before we get to making sound though, we should learn a bit about the `alive`
1313 programming language, and how to install and use it.
2727 If you have trouble installing some of the dependencies, note that `osc`,
2828 `luasocket` and `lua-rtmidi` are optional, however you will not be able to use
2929 the corresponding modules of the `alive` standard library if you do not install
30 them. To follow the later parts of this guide at least `osc` and `luasocket` are
31 required.
30 them. To follow the later parts of this guide at least `osc` and `luasocket`
31 are required.
3232
3333 After installing the dependencies, you can clone the
3434 [`alivecoding` repository][git] using git:
5353 parenthesized lists like `(head a b c...)`, where the first element of the list
5454 (`head`) is the name of an operator of function, which defines what the
5555 expression as a whole will do, while the other elements are parameters whose
56 meaning depends on the `head`. Let's start with a simple operator, `trace`:
57 `trace` is used to inspect values by printing them to the copilot. Enter the
56 meaning depends on the `head`. Let's start with a simple operator, [trace][]:
57 [trace][] is used to inspect values by printing them to the copilot. Enter the
5858 following in your file and save it:
5959
6060 (trace "hello world")
6767 trace "hello world": <Value str: hello world>
6868
6969 In the first line, it notifies us that the file has changed. In the second
70 line, we can see the output from `trace`: it lets us know that our input
70 line, we can see the output from [trace][]: it lets us know that our input
7171 `"hello world"` evaluated to a `Value` with the type `str` (string) and
7272 contents `hello world`.
7373 2. Your editor may notify you that `hello.alv` has changed, or reload the file
7979
8080 ([1]trace "hello world")
8181
82 The `[1]` that the copilot added to our expression is that expression's `tag`.
82 The [1] that the copilot added to our expression is that expression's `tag`.
8383 In `alive`, every expression has a tag that helps the copilot to identify the
8484 individual expressions as you make changes to your code. The copilot will make
8585 sure that all expressions are tagged by adding missing tags when you save the
123123 true
124124 false
125125
126 You can try using `trace` with all of these values to get used to how they are
127 printed.
126 You can try using [trace][] with all of these values to get used to how they
127 are printed.
128128
129129 ### importing modules
130 Apart from `trace`, there are only very little builtin operators in `alive` -
131 you can see all of them in the *builtins* section of the [reference][reference].
130 Apart from [trace][], there are only very little builtin operators in `alive` -
131 you can see all of them in the *builtins* section of the [reference][:/:].
132132 All of the 'real' functionality of `alive` is grouped into *modules*, that have
133133 to be loaded individually. *Modules* help organize all of the operators, so that
134134 it is less overwhelming to look for a concrete feature. It is also possible to
135135 create your own plugins as new modules, which will be covered in another guide
136136 soon.
137137
138 Let's try using the [`+` operator][plus] from the `math` module. To use operators
139 from a module, we need to tell `alive` to load it first: We can load *all* the
140 operators from the `math` module into the current scope using the
141 [`import*`][import*] builtin:
138 Let's try using the [`+` operator][:math/+:] from the [math/][] module. To use
139 operators from a module, we need to tell `alive` to load it first: We can load
140 *all* the operators from the [math/][] module into the current scope using the
141 [import*][] builtin:
142142
143143 (import* math)
144144 (trace (+ 1 2))
149149
150150 Because it can get a bit confusing when all imported operators are mixed in the
151151 global scope, it is also possible to load the module into its own scope and use
152 it with a prefix. This is what the [`import`][import] builtin is for:
152 it with a prefix. This is what the [import][] builtin is for:
153153
154154 (import math)
155155 (trace (math/+ 1 2))
156156
157 ### comments
158 To annotate your code, you can use comments. In `alive`, comments begin with
159 `#(` and end on a matching `)`. This way you can uncomment a complete
160 expression simply by adding a `#` character in front.
161
162 #(this is a comment)
163
164 #(this is a long,
165 multi-line comment,
166 (and it also has nested parentheses).
167 It ends after this sentence.)
168
157169 ### defining symbols
158 Both `import` and `import*` are actually shorthands for other builtins:
159 [`def`][def] and [`use`][use]. `def` is used to *define a symbol* in the
170 Both [import][] and [import*][] are actually shorthands for other builtins:
171 [def][] and [use][]. [def][] is used to *define a symbol* in the
160172 current scope. You can use it to associate a *symbol* (a name, like `hello`,
161 `trace` or `+`) with a value. After a symbol is defined, the name becomes an
162 alias that behaves like the value itself. For example, we can use `def` to
173 `trace`, or `+`) with a value. After a symbol is defined, the name becomes an
174 alias that behaves like the value itself. For example, we can use [def][] to
163175 give the result of our calculation a name, and then refer to it in by that
164 symbol in the `trace` operator:
176 symbol in the [trace][] operator:
165177
166178 (import* math)
167179
185197 for the symbol `world` within the scope found by dynamically resolving
186198 `*hello*`.
187199
188 The `import` builtin is actually a shorthand for the following expression:
200 The [import][] builtin is actually a shorthand for the following expression:
189201
190202 (def math (require "math"))
191203 (trace (math/+ 1 2))
192204
193 [`require`][require] returns a *scope*, which is defined as the symbol `math`.
205 [require][] returns a *scope*, which is defined as the symbol `math`.
194206 Then `math/+` is resolved by looking for `+` in this nested scope. Note that
195207 the symbol that the scope is defined as and the name of the module that is
196208 loaded do not have to be the same, you could call the alias whatever you want:
199211 (trace (fancy-math/+ 1 2))
200212
201213 In practice this is rarely useful, which is why the `require` shortcut exists.
202 The full version of `import*` on the other hand defines every symbol from the
214 The full version of [import*][] on the other hand defines every symbol from the
203215 imported module individually. The expanded version is the following:
204216
205217 (use (require "math"))
206218 (trace (+ 1 2))
207219
208 [`use`][use] copies all symbol definitions from the scope it is passed to the
220 [use][] copies all symbol definitions from the scope it is passed to the
209221 current scope.
210222
211 Note that `import`, `import*`, `def`, and `use` all can take multiple
223 Note that [import][], [import*][], [def][], and [use][] all can take multiple
212224 arguments:
213225
214226 (import* math logic)
220232 (def midi (require "midi")
221233 osc (require "osc"))
222234
223 It is common to have an `import` and `import*` expression at the top of an
235 It is common to have an [import][] and [import*][] expression at the top of an
224236 `alive` program to load all of the modules that will be used later, but the
225237 modules don't necessarily have to be loaded at the very beginning, as long as
226238 all symbols are defined before they are being used.
227239
228 ### scopes
240 ### nested scopes
229241 Once a symbol is defined, it cannot be changed or removed:
230242
231243 (def a 3)
232244 (def a 4) #(error!)
233245
234246 However it is possible to 'shadow' a symbol with another one in a nested scope.
235 So far, all symbols we have defined - using `def`, `import` and `import*` -
247 So far, all symbols we have defined - using `def`, [import][] and [import*][] -
236248 have been defined in the *global scope*, the scope that is active in the whole
237249 `alive` program. However some builtins create a new scope that their parameters
238 are evaluated in. One of them is [`do`][do], which does only that:
250 are evaluated in. One of them is [do][], which does only that:
239251
240252 (import string)
241253
259271 scope keep their values, and changes in the nested scope do not impact the
260272 parent scope.
261273
262 ### functions
263 Another builtin that creates a nested scope is [`fn`][fn], which is used to
274 ### defining functions
275 Another builtin that creates a nested scope is [fn][], which is used to
264276 create a *user-defined function*, which can be used to simplify repetitive
265277 code, amongst other things:
266278
279291 two parameters, `a` and `b`. The last part of the function definition is called
280292 the *function body*.
281293
282 A function created using `fn` can be called like an operator. When a function
294 A function created using [fn][] can be called like an operator. When a function
283295 is called, the parameters to the function are defined with the names given in
284296 the definition, and then the function body is executed. The previous example is
285297 equivalent to the following:
332344 [luarocks]: https://github.com/luarocks/luarocks/#installing
333345 [git]: https://git.s-ol.nu/alivecoding
334346 [reference]: reference/
335 [plus]: reference/math.html#+
336 [import*]: reference/#import*
337 [import]: reference/#import
338 [require]: reference/#require
339 [use]: reference/#use
340 [fn]: reference/#fn
341 [defn]: reference/#defn
2727 font-size: 0.9em;
2828 font-family: 'Source Code Pro', monospace;
2929 background: #cccccc;
30 padding: 0.05em 0.2em;
30 padding: 0.03em 0.2em;
3131 }
3232
3333
4444 h1, h2, h3,
4545 h4, h5, h6 {
4646 margin: 0.5em 0 0.25em;
47 }
48 h1 a, h2 a, h3 a,
49 h4 a, h5 a, h6 a {
50 text-decoration: none;
4751 }
4852 h1 + p, h2 + p, h3 + p,
4953 h4 + p, h5 + p, h6 + p {
120124 text-decoration: none;
121125 }
122126
123 .def:target > label a {
124 font-weight: bold;
127 a:hover code,
128 .def:target > label code {
129 text-decoration: none;
130 background: #202020;
131 color: #cccccc;
125132 }
126133
127134 .nest {
00 import Value, Scope from require 'core'
1 import render, layout from require 'extra.layout'
1 import render, layout, autoref from require 'extra.layout'
22 import section, h2, p, ul, li, a, code, r from require 'extra.dom'
33
44 export OUT, require
2929 module = Scope.from_table require module
3030
3131 layout
32 title: "#{name} module reference"
32 title: "#{name} reference"
3333 body: section {
34 h2 (code name), ' reference'
34 h2 (code name), ' module reference'
3535 ul for key, res in opairs module.values
3636 li render key, res.value
3737 }
4343 section {
4444 id: 'modules'
4545 h2 a "module index", href: '#modules'
46 p "These modules can be imported using #{r 'require'}, #{r 'import'} and " ..
47 "#{r 'import*'}."
46 p autoref "These modules can be imported using [require][], " ..
47 "[import][] and [import*][]."
4848 ul for file in *arg[3,]
49 module = file\match '^lib/(.*)%.moon$'
50 li a (code module), href: "#{module}.html"
49 path = file\match '^lib/(.*)%.moon$'
50 name = path\gsub '/', '.'
51 li a (code name), href: "#{path}.html"
5152 }
5253 section {
5354 id: 'builtins'
6667 contents = slurp file
6768 require 'discount'
6869
69 layout compile contents, 'githubtags', 'fencedcode'
70 layout compile autoref contents, 'githubtags', 'fencedcode'
7071
7172 else
7273 error "unknown command '#{command}'"
2929 up = string.rep '../', depth
3030 "#{up}#{page}"
3131
32 -- generate a link to a reference entry
33 -- entry is one of
34 -- builtin-name; mod.name/name; mod.name
35 link = (ref) ->
36 mod, sym = ref\match '^(.+)/(.*)$'
37 abs "reference/#{mod or 'index'}.html##{sym or ref}"
38
3239 -- link to a reference
33 r = (name, page='') ->
40 r = (text, ref) ->
3441 import a, code from require 'extra.dom'
35 a (code name), href: "#{page}##{name}"
42 href = link ref or text
43 if ref
44 a text, :href
45 else
46 text = text\gsub '/$', ''
47 a (code text), :href
48
49 -- substitute markdown-style reference links
50 autoref = (str) ->
51 str = str\gsub '%[([^%]]-)%]%[%]', r
52 str = str\gsub '%[([^%]]-)%]%[:(.-):%]', r
53 str
3654
3755 -- layout and write a doc page
3856 -- opts:
84102
85103
86104 {
87 :r
105 :autoref
88106 :render
89107 :layout
90108 }