diff --git a/doc/site/classes.markdown b/doc/site/classes.markdown
index a38c9b68..26ece8e5 100644
--- a/doc/site/classes.markdown
+++ b/doc/site/classes.markdown
@@ -1,9 +1,10 @@
^title Classes
-^category guide
Every value in Wren is an object, and every object is an instance of a class.
Even `true` and `false` are full-featured objects—instances of the
-[`Bool`](core/bool.html) class.
+[Bool][] class.
+
+[bool]: modules/core/bool.html
Classes define an objects *behavior* and *state*. Behavior is defined by
[*methods*][method calls] which live in the class. Every object of the same
diff --git a/doc/site/concurrency.markdown b/doc/site/concurrency.markdown
index e4b4d475..7a396a3d 100644
--- a/doc/site/concurrency.markdown
+++ b/doc/site/concurrency.markdown
@@ -1,5 +1,4 @@
^title Concurrency
-^category guide
Lightweight concurrency is a key feature of Wren and it is expressed using
*fibers*. They control how all code is executed, and take the place of
diff --git a/doc/site/control-flow.markdown b/doc/site/control-flow.markdown
index 33bcf68e..09fbd875 100644
--- a/doc/site/control-flow.markdown
+++ b/doc/site/control-flow.markdown
@@ -1,5 +1,4 @@
^title Control Flow
-^category guide
Control flow is used to determine which chunks of code are executed and how many
times. *Branching* statements and expressions decide whether or not to execute
diff --git a/doc/site/embedding-api.markdown b/doc/site/embedding-api.markdown
index f3784e03..061b5ac3 100644
--- a/doc/site/embedding-api.markdown
+++ b/doc/site/embedding-api.markdown
@@ -1,5 +1,4 @@
^title Embedding API
-^category reference
Wren is designed to be a scripting language, so the embedding API is as
important as any of its language features. There are two (well, three) ways to
diff --git a/doc/site/error-handling.markdown b/doc/site/error-handling.markdown
index a916bd2f..87b1fdbe 100644
--- a/doc/site/error-handling.markdown
+++ b/doc/site/error-handling.markdown
@@ -1,5 +1,4 @@
^title Error Handling
-^category guide
Errors come in a few fun flavors.
@@ -165,5 +164,5 @@ For example, a method for parsing a number could return a number on success and
`null` to indicate parsing failed. Since Wren is dynamically typed, it's easy
and natural for a method to return different types of values.
-Modules →
+Modularity →← Concurrency
diff --git a/doc/site/functions.markdown b/doc/site/functions.markdown
index 13981506..65a3d093 100644
--- a/doc/site/functions.markdown
+++ b/doc/site/functions.markdown
@@ -1,5 +1,4 @@
^title Functions
-^category guide
No self-respecting language today can get by without functions—first
class little bundles of code. Since Wren is object-oriented, most of your code
diff --git a/doc/site/lists.markdown b/doc/site/lists.markdown
index ab0c915a..f9521085 100644
--- a/doc/site/lists.markdown
+++ b/doc/site/lists.markdown
@@ -1,5 +1,4 @@
^title Lists
-^category guide
A list is a compound object that holds a collection of elements identified by
integer index. You can create a list by placing a sequence of comma-separated
diff --git a/doc/site/maps.markdown b/doc/site/maps.markdown
index 30c483f3..06062c3b 100644
--- a/doc/site/maps.markdown
+++ b/doc/site/maps.markdown
@@ -1,5 +1,4 @@
^title Maps
-^category guide
A map is an *associative* collection. It holds a set of entries, each of which
maps a *key* to a *value*. The same data structure has a variety of names in
@@ -117,7 +116,7 @@ For that, map exposes two methods: `keys` and `values`.
The first returns a [Sequence][] that [iterates][] over all of the keys in the
map, and the second returns one that iterates over the values.
-[sequence]: core/sequence.html
+[sequence]: modules/core/sequence.html
[iterates]: control-flow.html#the-iterator-protocol
If you want to see all of the key-value pairs in a map, the easiest way is to
diff --git a/doc/site/method-calls.markdown b/doc/site/method-calls.markdown
index 0a87dd48..f13305b2 100644
--- a/doc/site/method-calls.markdown
+++ b/doc/site/method-calls.markdown
@@ -1,5 +1,4 @@
^title Method Calls
-^category guide
Wren is deeply object oriented, so most code consists of invoking methods on
objects, usually something like this:
@@ -34,11 +33,11 @@ methods with the same *name*, as long as they have different *signatures*. The
signature includes the method's name along with the number of arguments it
takes. In technical terms, this means you can *overload by arity*.
-
+For example, the [Random][] class has two methods for getting a random integer.
+One takes a minimum and maximum value and returns a value in that range. The
+other only takes a maximum value and uses 0 as the minimum:
-For example, the Random class has two methods for getting a random integer. One
-takes a minimum and maximum value and returns a value in that range. The other
-only takes a maximum value and uses 0 as the minimum:
+[random]: modules/random/random.html
:::wren
var random = Random.new()
@@ -143,7 +142,7 @@ it to tell if an object is an instance of a given class. You'll rarely need to,
but you can override `is` in your own classes. That can be useful for things
like mocks or proxies where you want an object to masquerade as a certain class.
-[object]: core/object.html
+[object]: modules/core/object.html
## Subscripts
diff --git a/doc/site/modules.markdown b/doc/site/modularity.markdown
similarity index 97%
rename from doc/site/modules.markdown
rename to doc/site/modularity.markdown
index 7ce0bdce..cfda5f93 100644
--- a/doc/site/modules.markdown
+++ b/doc/site/modularity.markdown
@@ -1,5 +1,4 @@
-^title Modules
-^category guide
+^title Modularity
Once you start writing programs that are more than little toys, you quickly run
into two problems:
@@ -52,7 +51,8 @@ performs:
1. Locate the source code for the module.
2. Execute the imported module's code.
-3. Bind new variables in the importing module to values defined in the imported module.
+3. Bind new variables in the importing module to values defined in the imported
+ module.
We'll go through each step:
@@ -110,9 +110,11 @@ valid separator on Windows, but backslashes are not valid on other OSes.)
## Executing the module
Once we have the source code for a module, we need to run it. First, the VM
-takes the fiber that is executing the `import` statement in the importing
+takes the [fiber][] that is executing the `import` statement in the importing
module and pauses it.
+[fiber]: concurrency.html
+
Then it creates a new module object—a new fresh top-level scope,
basically—and a new fiber. It executes the new module's code in that
fiber and scope. The module can run whatever imperative code it wants and
@@ -157,7 +159,7 @@ rarely makes a difference.
## Shared imports
-Earlier, I described a programs set of modules as a tree. Of course, it's only
+Earlier, I described a program's set of modules as a tree. Of course, it's only
a *tree* of modules if there are no *shared imports*. But consider a program
like:
diff --git a/doc/site/core/bool.markdown b/doc/site/modules/core/bool.markdown
similarity index 73%
rename from doc/site/core/bool.markdown
rename to doc/site/modules/core/bool.markdown
index e61fca7f..03ac5e51 100644
--- a/doc/site/core/bool.markdown
+++ b/doc/site/modules/core/bool.markdown
@@ -1,7 +1,8 @@
^title Bool Class
-^category core
-Boolean values. There are two instances, `true` and `false`.
+Boolean [values][]. There are two instances, `true` and `false`.
+
+[values]: ../../values.html
## Methods
diff --git a/doc/site/core/class.markdown b/doc/site/modules/core/class.markdown
similarity index 97%
rename from doc/site/core/class.markdown
rename to doc/site/modules/core/class.markdown
index d3e9d5f1..9abe86f8 100644
--- a/doc/site/core/class.markdown
+++ b/doc/site/modules/core/class.markdown
@@ -1,5 +1,6 @@
^title Class Class
-^category core
+
+**TODO**
## Methods
diff --git a/doc/site/core/fiber.markdown b/doc/site/modules/core/fiber.markdown
similarity index 98%
rename from doc/site/core/fiber.markdown
rename to doc/site/modules/core/fiber.markdown
index a3aca2aa..99583d48 100644
--- a/doc/site/core/fiber.markdown
+++ b/doc/site/modules/core/fiber.markdown
@@ -1,9 +1,8 @@
^title Fiber Class
-^category core
A lightweight coroutine. [Here][fibers] is a gentle introduction.
-[fibers]: ../concurrency.html
+[fibers]: ../../concurrency.html
### Fiber.**new**(function)
diff --git a/doc/site/core/fn.markdown b/doc/site/modules/core/fn.markdown
similarity index 93%
rename from doc/site/core/fn.markdown
rename to doc/site/modules/core/fn.markdown
index 5c4a6ed7..78785bc5 100644
--- a/doc/site/core/fn.markdown
+++ b/doc/site/modules/core/fn.markdown
@@ -1,8 +1,9 @@
^title Fn Class
-^category core
A first class function—an object that wraps an executable chunk of code.
-[Here](../functions.html) is a friendly introduction.
+[Here][functions] is a friendly introduction.
+
+[functions]: ../../functions.html
### Fn.**new**(function)
diff --git a/doc/site/core/index.markdown b/doc/site/modules/core/index.markdown
similarity index 78%
rename from doc/site/core/index.markdown
rename to doc/site/modules/core/index.markdown
index f592d394..2b1e17ae 100644
--- a/doc/site/core/index.markdown
+++ b/doc/site/modules/core/index.markdown
@@ -1,8 +1,7 @@
-^title Core Library
-^category core
+^title Core Module
Because Wren is designed for [embedding in applications][embedding], its core
-library is minimal and is focused on working with objects within Wren. For
+module is minimal and is focused on working with objects within Wren. For
stuff like file IO, graphics, etc., it is up to the host application to provide
interfaces for this.
@@ -22,4 +21,4 @@ All Wren source files automatically have access to the following classes:
* [String](string.html)
* [System](system.html)
-[embedding]: ../embedding-api.html
+[embedding]: ../../embedding-api.html
diff --git a/doc/site/core/list.markdown b/doc/site/modules/core/list.markdown
similarity index 92%
rename from doc/site/core/list.markdown
rename to doc/site/modules/core/list.markdown
index 443eddbc..56c5f27f 100644
--- a/doc/site/core/list.markdown
+++ b/doc/site/modules/core/list.markdown
@@ -1,9 +1,10 @@
^title List Class
-^category core
Extends [Sequence](sequence.html).
-An indexable contiguous collection of elements. More details [here](../lists.html).
+An indexable contiguous collection of elements. More details [here][lists].
+
+[lists]: ../../lists.html
## Methods
@@ -52,8 +53,10 @@ It is a runtime error if the index is not an integer or is out of bounds.
### **iterate**(iterator), **iteratorValue**(iterator)
-Implements the [iterator protocol](../control-flow.html#the-iterator-protocol)
-for iterating over the elements in the list.
+Implements the [iterator protocol][] for iterating over the elements in the
+list.
+
+[iterator protocol]: ../../control-flow.html#the-iterator-protocol
### **removeAt**(index)
diff --git a/doc/site/core/map.markdown b/doc/site/modules/core/map.markdown
similarity index 99%
rename from doc/site/core/map.markdown
rename to doc/site/modules/core/map.markdown
index 72a2bc7c..96c05fb1 100644
--- a/doc/site/core/map.markdown
+++ b/doc/site/modules/core/map.markdown
@@ -1,5 +1,4 @@
^title Map Class
-^category core
An associative collection that maps keys to values. More details [here](../maps.html).
diff --git a/doc/site/core/null.markdown b/doc/site/modules/core/null.markdown
similarity index 92%
rename from doc/site/core/null.markdown
rename to doc/site/modules/core/null.markdown
index f0e8ce47..192d0d12 100644
--- a/doc/site/core/null.markdown
+++ b/doc/site/modules/core/null.markdown
@@ -1,5 +1,4 @@
^title Null Class
-^category core
## Methods
diff --git a/doc/site/core/num.markdown b/doc/site/modules/core/num.markdown
similarity index 99%
rename from doc/site/core/num.markdown
rename to doc/site/modules/core/num.markdown
index 0b18ae9c..f00b785c 100644
--- a/doc/site/core/num.markdown
+++ b/doc/site/modules/core/num.markdown
@@ -1,5 +1,4 @@
^title Num Class
-^category core
## Static Methods
diff --git a/doc/site/core/object.markdown b/doc/site/modules/core/object.markdown
similarity index 99%
rename from doc/site/core/object.markdown
rename to doc/site/modules/core/object.markdown
index c71e3a8a..5611b1fb 100644
--- a/doc/site/core/object.markdown
+++ b/doc/site/modules/core/object.markdown
@@ -1,5 +1,4 @@
^title Object Class
-^category core
## Static Methods
diff --git a/doc/site/core/range.markdown b/doc/site/modules/core/range.markdown
similarity index 98%
rename from doc/site/core/range.markdown
rename to doc/site/modules/core/range.markdown
index b957195d..9d31c8b4 100644
--- a/doc/site/core/range.markdown
+++ b/doc/site/modules/core/range.markdown
@@ -1,5 +1,4 @@
^title Range Class
-^category core
A range defines a bounded range of values from a starting point to a possibly
exclusive endpoint. [Here](../range.html) is a friendly introduction.
diff --git a/doc/site/core/sequence.markdown b/doc/site/modules/core/sequence.markdown
similarity index 95%
rename from doc/site/core/sequence.markdown
rename to doc/site/modules/core/sequence.markdown
index 6f9cc649..968b88bf 100644
--- a/doc/site/core/sequence.markdown
+++ b/doc/site/modules/core/sequence.markdown
@@ -1,10 +1,9 @@
^title Sequence Class
-^category core
An abstract base class for any iterable object. Any class that implements the
core [iterator protocol][] can extend this to get a number of helpful methods.
-[iterator protocol]: ../control-flow.html#the-iterator-protocol
+[iterator protocol]: ../../control-flow.html#the-iterator-protocol
## Methods
@@ -25,9 +24,11 @@ and returns the value. Otherwise, returns `true`.
Tests whether any element in the sequence passes the `predicate`.
Iterates over the sequence, passing each element to the function `predicate`.
-If it returns something [true](../control-flow.html#truth), stops iterating and
+If it returns something [true][], stops iterating and
returns that value. Otherwise, returns `false`.
+[true]: ../../control-flow.html#truth
+
:::wren
System.print([1, 2, 3].any {|n| n < 1}) //> false
System.print([1, 2, 3].any {|n| n > 2}) //> true
@@ -126,7 +127,9 @@ the sequence is empty, returns `seed`.
### **toList**
-Creates a [list](list.html) containing all the elements in the sequence.
+Creates a [list][] containing all the elements in the sequence.
+
+[list]: list.html
:::wren
System.print((1..3).toList) //> [1, 2, 3]
diff --git a/doc/site/core/string.markdown b/doc/site/modules/core/string.markdown
similarity index 99%
rename from doc/site/core/string.markdown
rename to doc/site/modules/core/string.markdown
index fbecf658..fad74c27 100644
--- a/doc/site/core/string.markdown
+++ b/doc/site/modules/core/string.markdown
@@ -1,5 +1,4 @@
^title String Class
-^category core
A string is an immutable array of bytes. Strings usually store text, in which
case the bytes are the UTF-8 encoding of the text's code points. But you can put
diff --git a/doc/site/core/system.markdown b/doc/site/modules/core/system.markdown
similarity index 98%
rename from doc/site/core/system.markdown
rename to doc/site/modules/core/system.markdown
index cfaf8cc3..1104c34d 100644
--- a/doc/site/core/system.markdown
+++ b/doc/site/modules/core/system.markdown
@@ -1,5 +1,4 @@
^title System Class
-^category core
The System class is a grab-bag of functionality exposed by the VM, mostly for
use during development or debugging.
diff --git a/doc/site/modules/core/template.html b/doc/site/modules/core/template.html
new file mode 100644
index 00000000..6674caf1
--- /dev/null
+++ b/doc/site/modules/core/template.html
@@ -0,0 +1,98 @@
+
+
+