* fix syntax highlighting
* disable highlightjs in favor of codehilite / pygments
* add pygments css
* convert scopeslexer into pygments pip-compatible module
* update scopeslexer to python3
M .hgignore +1 -0
@@ 28,6 28,7 @@ syntax: regexp
 ^testing/(_)?test\.wasm$
 ^scopes[.]h$
 ^doc/site
+^doc/site-packages
 ^bin/
 ^src/known_symbols.hpp
 ^Makefile$

          
M doc/Makefile +9 -3
@@ 2,9 2,9 @@ 
 #
 
 # You can set these variables from the command line.
-MKDOCSOPTS    =
 MKDOCS        = mkdocs
 BUILDDIR      = site
+PYBUILDDIR    = site-packages
 
 # User-friendly check for MkDocs
 ifeq ($(shell which $(MKDOCS) >/dev/null 2>&1; echo $$?), 1)

          
@@ 18,11 18,17 @@ help:
 	@echo "Please use \`make <target>' where <target> is one of"
 	@echo "  clean      to discard generated documentation"
 	@echo "  html       to make standalone HTML files"
+	@echo "  serve      to start a web server in preview mode for editing"
 
 clean:
-	rm -rf $(BUILDDIR)/*
+	rm -rf $(BUILDDIR)/* $(PYBUILDDIR)/*
 
 html:
-	$(MKDOCS) $(MKDOCSOPTS) build -d $(BUILDDIR)
+	pip install --upgrade -I ./ScopesLexer -t $(PYBUILDDIR)
+	PYTHONPATH="$(PYBUILDDIR);$(PYTHONPATH)" python -B -m mkdocs build -d "$(BUILDDIR)"
 	@echo
 	@echo "Build finished. The HTML pages are in $(BUILDDIR)/."
+
+serve:
+	pip install --upgrade -I ./ScopesLexer -t $(PYBUILDDIR)
+	PYTHONPATH="$(PYBUILDDIR);$(PYTHONPATH)" python -B -m mkdocs serve

          
A => doc/ScopesLexer/scopeslexer/__init__.py +1 -0
@@ 0,0 1,1 @@ 
+

          
M doc/scopeslexer.py => doc/ScopesLexer/scopeslexer/lexer.py +1 -1
@@ 113,7 113,7 @@ class ScopesLexer(Lexer):
             return state.next_cursor - state.next_line + 1
 
         def location_error(msg):
-            print text
+            print(text)
             raise Exception("%i:%i: error: %s" % (state.lineno,column(),msg))
 
         def is_eof():

          
A => doc/ScopesLexer/setup.py +11 -0
@@ 0,0 1,11 @@ 
+from setuptools import setup, find_packages
+
+setup (
+  name='scopeslexer',
+  packages=find_packages(),
+  entry_points =
+  """
+  [pygments.lexers]
+  scopeslexer = scopeslexer.lexer:ScopesLexer
+  """,
+)

          
M doc/docs/cpp_users.md +350 -307
@@ 103,14 103,16 @@ only parses programs as symbolic lists a
 declarations until the last possible moment, expecting all expressions to follow
 just one basic form:
 
-    # classic braced expression
-    (head argument1 ... argumentN)
-    # naked syntax
-    head argument1 ... argumentN
-    # naked paragraph form
-    head argument1 ...
-        ...
-        argumentN
+```scopes
+# classic braced expression
+(head argument1 ... argumentN)
+# naked syntax
+head argument1 ... argumentN
+# naked paragraph form
+head argument1 ...
+    ...
+    argumentN
+```
 
 The value and type of the head controls whether the expression is dispatched to:
 

          
@@ 199,22 201,24 @@ Scopes does not make such a distinction,
 as an expression with a result type. The top level of a program is equivalent
 to its main function:
 
-    # the right hand side is not limited to constant expressions.
-    let MyInt = int
+```scopes
+# the right hand side is not limited to constant expressions.
+let MyInt = int
 
-    # legal at this level.
-    print "hello!"
+# legal at this level.
+print "hello!"
 
-    fn test (x)
-        let k = (x * x)
+fn test (x)
+    let k = (x * x)
 
-        let m =
-            do
-                # equivalent to statement expressions in GCC.
-                print "hello again!"
-                k * k
-        # even `return` declares an expression of type `noreturn`.
-        return m
+    let m =
+        do
+            # equivalent to statement expressions in GCC.
+            print "hello again!"
+            k * k
+    # even `return` declares an expression of type `noreturn`.
+    return m
+```
 
 Constants and Variables
 -----------------------

          
@@ 253,42 257,46 @@ expression or value to a name. The type 
 depends entirely on the expression that produces it. The `local` and `global`
 forms must be used to explicitly allocate a stack or data segment value:
 
-    # a compile time constant integer
-    let constant = 100
+```scopes
+# a compile time constant integer
+let constant = 100
 
-    # not a global value, but allocated on the main function's stack
-    local variable1 = 0
-    # a global value mapped to data segment
-    global variable2 = 0
+# not a global value, but allocated on the main function's stack
+local variable1 = 0
+# a global value mapped to data segment
+global variable2 = 0
 
-    # variable1 is bound to another name - not a copy operation.
-      variable1_copy remains mutable.
-    let variable1_copy = variable1
+# variable1 is bound to another name - not a copy operation.
+    variable1_copy remains mutable.
+let variable1_copy = variable1
 
-    fn test ()
-        # just a rebind - not a copy operation
-        let variable3 = constant
-        # variable3 is not a reference, so can not be mutated.
-          we should have declared it as local for that.
-        # variable3 = variable2
+fn test ()
+    # just a rebind - not a copy operation
+    let variable3 = constant
+    # variable3 is not a reference, so can not be mutated.
+        we should have declared it as local for that.
+    # variable3 = variable2
 
-        print constant
-        # illegal: variable1 is a stack variable outside of function scope
-        # print variable1
-        # legal: variable2 is a global
-        print variable2
-        # variable3 is a constant
-        print variable3
+    print constant
+    # illegal: variable1 is a stack variable outside of function scope
+    # print variable1
+    # legal: variable2 is a global
+    print variable2
+    # variable3 is a constant
+    print variable3
+```
 
 Unlike in C/C++, declarations of the same name within the same scope are
 permitted, and the previous binding is still accessible during evaluation
 of the right-hand side:
 
-    let x = 1
-    # x is now bound to the value 3
-    let x = (x + 2)
-    # x is now bound to a string
-    let x = "test"
+```scopes
+let x = 1
+# x is now bound to the value 3
+let x = (x + 2)
+# x is now bound to a string
+let x = "test"
+```
 
 Lexical Scope
 -------------

          
@@ 298,18 306,20 @@ Both C/C++ and Scopes employ lexical sco
 Unlike in C/C++, lexical scope is a first order object in Scopes and can be used
 by new declarative forms as well as to export symbols from modules:
 
-    let scope =
-        do
-            let x = 1
-            let y = "test"
+```scopes
+let scope =
+    do
+        let x = 1
+        let y = "test"
 
-            # build a new scope from locally bound names
-            locals;
+        # build a new scope from locally bound names
+        locals;
 
-    # scope is constant if all values in it are constant
-    static-assert (constant? scope)
-    # prints 1 "test"
-    print scope.x scope.y
+# scope is constant if all values in it are constant
+static-assert (constant? scope)
+# prints 1 "test"
+print scope.x scope.y
+```
 
 Macros
 ------

          
@@ 384,39 394,41 @@ In Scopes, all function declarations are
 be used to instantiate concrete functions at compile time. Forward declarations
 are possible but must be completed within the same scope:
 
-    # forward declarations can not be typed
-    #fn typed_forward_decl
-
-    fn typed_decl (x text toggle)
-        return 0
+```scopes
+# forward declarations can not be typed
+#fn typed_forward_decl
 
-    # create typed function
-    let typed_decl = (static-typify typed_decl i32 rawstring bool)
+fn typed_decl (x text toggle)
+    return 0
 
-    # forward declaration of template has no parameter list
-    fn lazy_typed_decl_returns_void
+# create typed function
+let typed_decl = (static-typify typed_decl i32 rawstring bool)
+
+# forward declaration of template has no parameter list
+fn lazy_typed_decl_returns_void
 
-    # test1 is another template
-    fn test1 ()
-        # legal because test1 is not instantiated yet
-        # note: lazy_typed_decl_returns_void must be implemented before
-                test1 is instantiated.
-        lazy_typed_decl_returns_void 1 2 3
+# test1 is another template
+fn test1 ()
+    # legal because test1 is not instantiated yet
+    # note: lazy_typed_decl_returns_void must be implemented before
+            test1 is instantiated.
+    lazy_typed_decl_returns_void 1 2 3
 
-    # forward declaration of template with auto return type
-      note that all our forward declarations have no return type
-    fn lazy_typed_decl_returns_auto
+# forward declaration of template with auto return type
+    note that all our forward declarations have no return type
+fn lazy_typed_decl_returns_auto
 
-    fn test2 ()
-        # legal because test2 is not instantiated yet
-        lazy_typed_decl_returns_auto 1 2 3
+fn test2 ()
+    # legal because test2 is not instantiated yet
+    lazy_typed_decl_returns_auto 1 2 3
 
-    # implementation of template with auto return type
-    fn lazy_typed_decl_returns_auto (a b c)
-        return 0
+# implementation of template with auto return type
+fn lazy_typed_decl_returns_auto (a b c)
+    return 0
 
-    # instantiate test2
-    let test2 = (static-typify test2)
+# instantiate test2
+let test2 = (static-typify test2)
+```
 
 Variadic Arguments
 ------------------

          
@@ 431,29 443,31 @@ Functions in Scopes do not support runti
 variadic C functions is supported), but support compile time variadic arguments.
 See the following example:
 
-    # any trailing parameter ending in '...' is interpreted to be variadic.
-    fn takes-varargs (x y rest...)
-        # count the number of arguments in rest...
-        let numargs = (va-countof rest...)
+```scopes
+# any trailing parameter ending in '...' is interpreted to be variadic.
+fn takes-varargs (x y rest...)
+    # count the number of arguments in rest...
+    let numargs = (va-countof rest...)
 
-        # use let's support for variadic values to split arguments into
-          first argument and remainder.
-        let z rest... = rest...
+    # use let's support for variadic values to split arguments into
+        first argument and remainder.
+    let z rest... = rest...
 
-        # get the 5th argument from rest...
-        let fifth_arg = (va@ 5 rest...)
+    # get the 5th argument from rest...
+    let fifth_arg = (va@ 5 rest...)
 
-        # iterate through all arguments, perform an action on each one
-          and store the result in a new variadic value.
-        let processed... =
-            va-map
-                inline (value)
-                    print value
-                    value + 1
-                rest...
+    # iterate through all arguments, perform an action on each one
+        and store the result in a new variadic value.
+    let processed... =
+        va-map
+            inline (value)
+                print value
+                value + 1
+            rest...
 
-        # return variadic result as multiple return values
-        return processed...
+    # return variadic result as multiple return values
+    return processed...
+```
 
 Overloading
 -----------

          
@@ 475,21 489,23 @@ Scopes offers a similar mechanism as a l
 overloads are grouped at the time of declaration. The first form that
 matches argument types implicitly is selected, in order of declaration:
 
-    fn... overloaded
-    case (a : i32, b : i32)
-        return 0
-    case (a : i32, b : f32)
-        return 1
-    case (a : f32, b : i32)
-        return 2
+```scopes
+fn... overloaded
+case (a : i32, b : i32)
+    return 0
+case (a : i32, b : f32)
+    return 1
+case (a : f32, b : i32)
+    return 2
 
-    # expanding overloaded in a different file, limited to local scope
+# expanding overloaded in a different file, limited to local scope
 
-    # overwrites the previous declaration
-    fn... overloaded
-    case using overloaded # chains the previous declaration
-    case (a : f32, b : f32) # will be tried last
-        return 3
+# overwrites the previous declaration
+fn... overloaded
+case using overloaded # chains the previous declaration
+case (a : f32, b : f32) # will be tried last
+    return 3
+```
 
 Code Generation
 ---------------

          
@@ 538,39 554,43 @@ libraries' or module's functions are act
 Scopes also supports embedding existing third party C libraries in the classical
 way, using `include`, `load-library` and `load-object`:
 
-    # how to create trivial bindings for a C library
+```scopes
+# how to create trivial bindings for a C library
 
-    # include thirdparty.h and make its declarations available as a scope object
-    let thirdparty =
-        include "thirdparty.h"
-            options "-I" (module-dir .. "/../include") # specify options for clang
+# include thirdparty.h and make its declarations available as a scope object
+let thirdparty =
+    include "thirdparty.h"
+        options "-I" (module-dir .. "/../include") # specify options for clang
 
-    # access a define from thirdparty.h
-    if thirdparty.define.USE_SHARED_LIBRARY
-        # load thirdparty as a shared library from system search paths
-        if (operating-system == 'windows)
-            load-library "thirdparty.dll"
-        else
-            load-library "libthirdparty.so"
+# access a define from thirdparty.h
+if thirdparty.define.USE_SHARED_LIBRARY
+    # load thirdparty as a shared library from system search paths
+    if (operating-system == 'windows)
+        load-library "thirdparty.dll"
     else
-        # load thirdparty as a static library from an object file
-        load-object (module-dir .. "/../lib/thirdparty.o")
+        load-library "libthirdparty.so"
+else
+    # load thirdparty as a static library from an object file
+    load-object (module-dir .. "/../lib/thirdparty.o")
 
-    # assemble a ready-to-use scope object for this module
-    do
-        # import only symbols beginning with thirdparty
-        using thirdparty.define filter "^THIRDPARTY_.*$"
-        using thirdparty.typedef filter "^thirdparty_.*$"
-        using thirdparty.const filter "^thirdparty_.*$"
-        using thirdparty.extern filter "^thirdparty_.*$"
+# assemble a ready-to-use scope object for this module
+do
+    # import only symbols beginning with thirdparty
+    using thirdparty.define filter "^THIRDPARTY_.*$"
+    using thirdparty.typedef filter "^thirdparty_.*$"
+    using thirdparty.const filter "^thirdparty_.*$"
+    using thirdparty.extern filter "^thirdparty_.*$"
 
-        locals;
+    locals;
+```
 
 Externals using C signatures can also be defined and used directly:
 
-    let puts = (extern 'puts (function i32 rawstring))
-    # definition becomes immediately available
-    puts "hello\n"
+```scopes
+let puts = (extern 'puts (function i32 rawstring))
+# definition becomes immediately available
+puts "hello\n"
+```
 
 Type Primitives
 ---------------

          
@@ 639,17 659,19 @@ Example example = { .value = 100, .text 
 
 to this equivalent declaration in Scopes:
 
-    using import struct
+```scopes
+using import struct
 
-    struct Example plain
-        value : i32
-        # type can be deduced from initializer
-        choice = false
-        text : rawstring = ""
+struct Example plain
+    value : i32
+    # type can be deduced from initializer
+    choice = false
+    text : rawstring = ""
 
-    global example : Example
-        value = 100
-        text = "test"
+global example : Example
+    value = 100
+    text = "test"
+```
 
 Methods
 -------

          
@@ 683,18 705,20 @@ void use_example (Example example) {
 Scopes supports methods in a more explicit way that makes refactorings from
 function to method and back easier, both in declaration and in usage:
 
-    struct Example plain
-        value : i32
+```scopes
+struct Example plain
+    value : i32
 
-        # note the explicit presence of the object parameter
-        fn get_add_value (self n)
-            self.value + n
+    # note the explicit presence of the object parameter
+    fn get_add_value (self n)
+        self.value + n
 
-        fn print_value_plus_one (self)
-            print ('get_add_value self 1)
+    fn print_value_plus_one (self)
+        print ('get_add_value self 1)
 
-    fn use_example (example)
-        'print_value_plus_one example
+fn use_example (example)
+    'print_value_plus_one example
+```
 
 What happens here is that we call a quoted symbol with arguments. The call
 handler for the `Symbol` type rewrites `'methodname object arg0 ... argN`

          
@@ 715,26 739,28 @@ Access modifiers are not available, but 
 their definition local. Fields can not be hidden, but they can be visibly
 marked as private by convention:
 
-    struct Example plain
-        # an underscore indicates that the attribute is not meant to be
-          accessed directly.
-        _value : i32
+```scopes
+struct Example plain
+    # an underscore indicates that the attribute is not meant to be
+        accessed directly.
+    _value : i32
 
-        fn get_add_value (self n)
-            self._value + n
+    fn get_add_value (self n)
+        self._value + n
 
-        fn print_value_plus_one (self)
-            # use get_add_value directly
-            print (get_add_value self 1)
+    fn print_value_plus_one (self)
+        # use get_add_value directly
+        print (get_add_value self 1)
 
-        # unbind get_add_value from local scope to prevent it
-          from being added as an attribute to Example.
-        unlet get_add_value
+    # unbind get_add_value from local scope to prevent it
+        from being added as an attribute to Example.
+    unlet get_add_value
 
-    fn use_example (example)
-        # this operation is not possible from here:
-        # 'get_add_value example 1
-        'print_value_plus_one example
+fn use_example (example)
+    # this operation is not possible from here:
+    # 'get_add_value example 1
+    'print_value_plus_one example
+```
 
 Template Classes
 ----------------

          
@@ 756,16 782,18 @@ struct Example {
 Scopes leverages constant expression folding and compile time closures to
 trivially provide this feature via `inline` functions:
 
-    # a function decorator memoizes the result so we get the same type for
-      the same arguments
-    @@ memo
-    inline Example (T x)
-        # construct type name from string
-        struct ("Example<" .. (tostring T) .. ">")
-            value : T
+```scopes
+# a function decorator memoizes the result so we get the same type for
+    the same arguments
+@@ memo
+inline Example (T x)
+    # construct type name from string
+    struct ("Example<" .. (tostring T) .. ">")
+        value : T
 
-            fn compare ()
-                value == x
+        fn compare ()
+            value == x
+```
 
 Partial template specialization allows the choice of different implementations
 depending on instantiation arguments. The same mechanism is also used to do

          
@@ 796,29 824,31 @@ In Scopes, it is not necessary to create
 type based dispatch operators. Here are three ways to supply the same
 functionality:
 
-    include "stdlib.h"
+```scopes
+include "stdlib.h"
 
-    # a function that generates a function
-    @@ memo
-    inline to_int1 (T)
-        static-match T
-        case i32 _
-        case rawstring atoi
-        default
-            static-error "unsupported type"
+# a function that generates a function
+@@ memo
+inline to_int1 (T)
+    static-match T
+    case i32 _
+    case rawstring atoi
+    default
+        static-error "unsupported type"
 
-    # a function that performs the operation directly
-    inline to_int2 (x)
-        let T = (typeof x)
-        static-if (T == i32) x
-        elseif (T == rawstring) (atoi x)
-        else
-            static-error "unsupported type"
+# a function that performs the operation directly
+inline to_int2 (x)
+    let T = (typeof x)
+    static-if (T == i32) x
+    elseif (T == rawstring) (atoi x)
+    else
+        static-error "unsupported type"
 
-    # using the overloaded function abstraction
-    fn... to_int3
-    case (x : i32,) x
-    case (x : rawstring,) (atoi x)
+# using the overloaded function abstraction
+fn... to_int3
+case (x : i32,) x
+case (x : rawstring,) (atoi x)
+```
 
 Constructors
 ------------

          
@@ 830,15 860,17 @@ first argument is the name of the type t
 
 Here is an example that changes the default constructor of a struct:
 
-    struct Example plain
-        _value : i32
+```scopes
+struct Example plain
+    _value : i32
 
-        inline __typecall (cls n)
-            # within the context of a struct definition, super-type is bound
-              to the super type of the struct we are defining. In this case
-              the supertype is `CStruct`.
-            super-type.__typecall cls
-                _value = (n * n)
+    inline __typecall (cls n)
+        # within the context of a struct definition, super-type is bound
+            to the super type of the struct we are defining. In this case
+            the supertype is `CStruct`.
+        super-type.__typecall cls
+            _value = (n * n)
+```
 
 Destructors
 -----------

          
@@ 870,19 902,20 @@ referenced only at a single point within
 a unique type is able to supply a destructor through the `__drop` special method
 that is automatically called when the value goes out of scope:
 
-    struct Handle
-        _handle : voidstar
-
-        # constructor
-        inline __typecall (cls handle)
-            super-type.__typecall cls handle
+```scopes
+struct Handle
+    _handle : voidstar
 
-        # destructor
-        inline __drop (self)
-            print "destroying handle"
-            free self._handle
-            return;
+    # constructor
+    inline __typecall (cls handle)
+        super-type.__typecall cls handle
 
+    # destructor
+    inline __drop (self)
+        print "destroying handle"
+        free self._handle
+        return;
+```
 
 Operator Overloading
 --------------------

          
@@ 918,31 951,33 @@ protocols that any type can support by e
 special attributes. See this equivalent example, which applies not only to
 structs, but any type definition:
 
-    struct Accumulable
-        # one compile time function for all left-hand side variants receives
-          left-hand and right-hand types and returns a function which can
-          perform the operation or void.
-        inline __+ (cls T)
-            # test for type + type
-            static-if (T == this-type)
-                # return new closure
-                inline (self other)
-                    this-type (self.value + other.value)
-            # if T can be implicitly cast to i32, support it
-            elseif (imply? T i32)
-                inline (self other)
-                    this-type (self.value + other)
+```scopes
+struct Accumulable
+    # one compile time function for all left-hand side variants receives
+        left-hand and right-hand types and returns a function which can
+        perform the operation or void.
+    inline __+ (cls T)
+        # test for type + type
+        static-if (T == this-type)
+            # return new closure
+            inline (self other)
+                this-type (self.value + other.value)
+        # if T can be implicitly cast to i32, support it
+        elseif (imply? T i32)
+            inline (self other)
+                this-type (self.value + other)
 
-        # another function covers all right-hand side variants
-        inline __r+ (T cls)
-            static-if (imply? T i32)
-                inline (self other)
-                    this-type (self + other.value)
+    # another function covers all right-hand side variants
+    inline __r+ (T cls)
+        static-if (imply? T i32)
+            inline (self other)
+                this-type (self + other.value)
 
-        value : i32
+    value : i32
 
-        inline __repr (self)
-            tostring self.value
+    inline __repr (self)
+        tostring self.value
+```
 
 Standard Library
 ----------------

          
@@ 1032,20 1067,22 @@ Scopes supports compile time closures na
 runtime closures are also supported through so-called captures. The example
 above would be translated as follows:
 
-    fn print_bound_constant ()
-        let y = 42
-        # capture constant `y` along with the function
-        fn f (x)
-            x + y
-        # prints 65
-        print (f 23)
+```scopes
+fn print_bound_constant ()
+    let y = 42
+    # capture constant `y` along with the function
+    fn f (x)
+        x + y
+    # prints 65
+    print (f 23)
 
-    fn print_bound_value (y)
-        # capture variable `y` along with the function
-        capture f (x) {y}
-            x + y
-        # prints 65
-        print (f 23)
+fn print_bound_value (y)
+    # capture variable `y` along with the function
+    capture f (x) {y}
+        x + y
+    # prints 65
+    print (f 23)
+```
 
 Loops
 -----

          
@@ 1083,28 1120,30 @@ Scopes defines a single builtin primitiv
 backpropagation of immutable values, upon which various other library forms are
 implemented:
 
-    # implementing a counter using the range-based form
-    for i in (range 10)
-        print i
+```scopes
+# implementing a counter using the range-based form
+for i in (range 10)
+    print i
 
-    # implementing an iterator using the loop primitive and immutable values
-    loop (it k = (first container) 0)
-        if (is_valid it)
-            process k (at it)
-            repeat (next it) (k + 1)
-        else
-            # break can return values
-            break it k
+# implementing an iterator using the loop primitive and immutable values
+loop (it k = (first container) 0)
+    if (is_valid it)
+        process k (at it)
+        repeat (next it) (k + 1)
+    else
+        # break can return values
+        break it k
 
-    # implementing a counter using a while loop and mutation
-    local i = 0
-    while (i < 10)
-        print i
-        i += 1
+# implementing a counter using a while loop and mutation
+local i = 0
+while (i < 10)
+    print i
+    i += 1
 
-    # range-based form implementing an iterator
-    for key value in map
-        process key value
+# range-based form implementing an iterator
+for key value in map
+    process key value
+```
 
 In addition, with the `fold .. for .. in` form, Scopes combines both immutable
 loop and range-based form.

          
@@ 1126,17 1165,19 @@ implement native GLSL types and function
 
 See the following example implementing and compiling a pixel shader:
 
-    using import glm
-    using import glsl
+```scopes
+using import glm
+using import glsl
 
-    in uv : vec2 (location = 0)
-    out color : vec4 (location = 1)
-    fn main ()
-        color = (vec4 (uv * 0.5 + 0.5) 0 1)
+in uv : vec2 (location = 0)
+out color : vec4 (location = 1)
+fn main ()
+    color = (vec4 (uv * 0.5 + 0.5) 0 1)
 
-    print
-        compile-glsl 330 'fragment
-            static-typify main
+print
+    compile-glsl 330 'fragment
+        static-typify main
+```
 
 The program output is as follows:
 

          
@@ 1175,37 1216,39 @@ can be thrown as an exception using the 
 the `try .. catch` form.
 
 ```c++
-    struct myexception {
-        const char *what;
-    };
+struct myexception {
+    const char *what;
+};
 
-    void main () {
-        try {
-            // throw value of type myexception
-            myexception exc = { "an error occurred" };
-            throw exc;
-        } catch (myexception& e) {
-            // print content to screen
-            std::cout << e.what << std::endl;
-        }
+void main () {
+    try {
+        // throw value of type myexception
+        myexception exc = { "an error occurred" };
+        throw exc;
+    } catch (myexception& e) {
+        // print content to screen
+        std::cout << e.what << std::endl;
     }
+}
 ```
 
 Scopes supports a form of structured exception handling that is monomorphic,
 light-weight and C compatible. A value of any type can be raised using the
 `raise` form, and handled using the `try .. except` form:
 
-    using import struct
+```scopes
+using import struct
 
-    struct myexception
-        what : string
+struct myexception
+    what : string
 
-    try
-        # raise value of type myexception
-        raise (myexception "an error occurred")
-    except (e)
-        # print content to screen
-        print e.what
+try
+    # raise value of type myexception
+    raise (myexception "an error occurred")
+except (e)
+    # print content to screen
+    print e.what
+```
 
 The presence of an exception modifies the return type of a function to a hidden
 tagged union type which returns which path the function returned on, and

          
M doc/docs/dataformat.md +298 -244
@@ 24,98 24,99 @@ At a Glance
 As a summary, here is an example that provides an overview of all
 the notation aspects:
 
-    # below is some random data without any schema
+```scopes
+# below is some random data without any schema
 
-    # a naked list of five 32-bit signed integers
-    1 2 3 4 5
+# a naked list of five 32-bit signed integers
+1 2 3 4 5
 
-    # a list that begins with a symbol 'float-values:' and contains a braced
-    # sublist of floats.
-    float-values: (1.0 2.0 3.1 4.2 5.5:f64 inf nan)
+# a list that begins with a symbol 'float-values:' and contains a braced
+# sublist of floats.
+float-values: (1.0 2.0 3.1 4.2 5.5:f64 inf nan)
 
-    # we can also nest the sublist using indentation
-    # note the extravagant heading, another context-free symbol.
-    ==string-values==
-        "A" "B" "NCC-1701\n" "\xFFD\xFF" "\"E\""
+# we can also nest the sublist using indentation
+# note the extravagant heading, another context-free symbol.
+==string-values==
+    "A" "B" "NCC-1701\n" "\xFFD\xFF" "\"E\""
 
-    # a single top-level element, a single-line string
-    "I am Locutus of Borg."
+# a single top-level element, a single-line string
+"I am Locutus of Borg."
 
-    # a raw block string; four double quotes mark the start
-    """"
-        Ma'am is acceptable in a crunch, but I prefer Captain.
-                                        -- Kathryn Janeway
+# a raw block string; four double quotes mark the start
+""""
+    Ma'am is acceptable in a crunch, but I prefer Captain.
+                                    -- Kathryn Janeway
 
-    # a list of pairs (also lists), arranged horizontally
-    (1 x) (2 y) (3 z)
-    # same list, with last two entries arranged vertically
+# a list of pairs (also lists), arranged horizontally
+(1 x) (2 y) (3 z)
+# same list, with last two entries arranged vertically
+(1 x)
+    (2 y)
+    (3 z)
+# we can line up all entries by using a semicolon to indicate an empty head
+;
     (1 x)
-        (2 y)
-        (3 z)
-    # we can line up all entries by using a semicolon to indicate an empty head
-    ;
-        (1 x)
-        (2 y)
-        (3 z)
-    # parentheses can also be removed for each line entry
-    ;
-        1 x
-        2 y
-        3 z
+    (2 y)
+    (3 z)
+# parentheses can also be removed for each line entry
+;
+    1 x
+    2 y
+    3 z
 
-    # appending values to the parent list in the next line
-    symbol-values one two three four five \
-        six seven-of-nine ten
+# appending values to the parent list in the next line
+symbol-values one two three four five \
+    six seven-of-nine ten
 
-    # line continuation can also begin at the start of the next line
-    ::typed-integers:: 0:u8 1:i8 2:i16 3:u16
-        \ 4:u32 5:i32 6:u64 7:i64
+# line continuation can also begin at the start of the next line
+::typed-integers:: 0:u8 1:i8 2:i16 3:u16
+    \ 4:u32 5:i32 6:u64 7:i64
 
-    # which comes in handy when we want to continue the parent list
-    people like
-        jim kirk
-        commander spock
-        hikari sulu
-        \ and many more
+# which comes in handy when we want to continue the parent list
+people like
+    jim kirk
+    commander spock
+    hikari sulu
+    \ and many more
 
-    # a list with a symbol header and two entries
-    address-list
-        # a list with a header and three more lists of two values each
-        entry
-            name: "Jean-Luc Picard"
-            age: 59
-            address: picard@enterprise.org
-        entry
-            # the semicolon acts as list separator
-            name: "Worf, Son of Mogh"; age: 24; address: worf@house-of-mogh.co.klingon
-        # line comments double as block comments
-        #entry
-            name: "Natasha Yar"
-            age: 27
-            address: natasha.yar@enterprise.org
+# a list with a symbol header and two entries
+address-list
+    # a list with a header and three more lists of two values each
+    entry
+        name: "Jean-Luc Picard"
+        age: 59
+        address: picard@enterprise.org
+    entry
+        # the semicolon acts as list separator
+        name: "Worf, Son of Mogh"; age: 24; address: worf@house-of-mogh.co.klingon
+    # line comments double as block comments
+    #entry
+        name: "Natasha Yar"
+        age: 27
+        address: natasha.yar@enterprise.org
 
-    # the same list with braced notation; within braced lists,
-      indentation is meaningless.
-    (address-list
-        # a list with a header and three more lists of two values each
-        (entry
-            (name: "Jean-Luc Picard")
-            (age: 59)
-            (address: picard@enterprise.org))
-        (entry (name: "Worf, Son of Mogh") (age: 24)
-            (address: worf@house-of-mogh.co.klingon)))
+# the same list with braced notation; within braced lists,
+    indentation is meaningless.
+(address-list
+    # a list with a header and three more lists of two values each
+    (entry
+        (name: "Jean-Luc Picard")
+        (age: 59)
+        (address: picard@enterprise.org))
+    (entry (name: "Worf, Son of Mogh") (age: 24)
+        (address: worf@house-of-mogh.co.klingon)))
 
-    # a list of comma separated values - a comma is always recorded as
-      a separate symbol, so the list has nine entries
-    1, 2, 3,4, 5
+# a list of comma separated values - a comma is always recorded as
+    a separate symbol, so the list has nine entries
+1, 2, 3,4, 5
 
-    # a list of options beginning with a symbol in a list with
-      square brace style
-    [task]
-        cmd = "bash"
-        # the last element is a symbol in a list with curly brace style
-        working-dir = {project-base}
-
+# a list of options beginning with a symbol in a list with
+    square brace style
+[task]
+    cmd = "bash"
+    # the last element is a symbol in a list with curly brace style
+    working-dir = {project-base}
+```
 
 
 Formatting Rules

          
@@ 147,14 148,16 @@ Both line and block comments are initiat
 lasts from its beginning token to the first non-whitespace character with an equal
 or lower indentation level. Some examples of valid comments:
 
-    # a line comment
-    not a comment
-    # a block comment that continues
-      in the next line because the line has
-      a higher indentation level. Note, that
-            comments do not need to respect
-        indentation rules
-    but this line is not a comment
+```scopes
+# a line comment
+not a comment
+# a block comment that continues
+    in the next line because the line has
+    a higher indentation level. Note, that
+        comments do not need to respect
+    indentation rules
+but this line is not a comment
+```
 
 ### Strings ###
 

          
@@ 168,8 171,10 @@ copied over verbatim.
 
 Here are some examples of valid strings:
 
-    "a single-line string in double quotations"
-    "return: \n, tab: \t, backslash: \\, double quote: \", nbsp: \xFF."
+```scopes
+"a single-line string in double quotations"
+"return: \n, tab: \t, backslash: \\, double quote: \", nbsp: \xFF."
+```
 
 ### Raw Block Strings ###
 

          
@@ 180,13 185,15 @@ character that has a lower indentation.
 
 Here are some examples of valid raw block strings:
 
-    """"a single-line string as a block string
-    # commented line inbetween
-    """"// a multi-line string that describes a valid C function
-        #include <stdio.h>
-        void a_function_in_c() {
-            printf("hello world\n");
-        }
+```scopes
+""""a single-line string as a block string
+# commented line inbetween
+""""// a multi-line string that describes a valid C function
+    #include <stdio.h>
+    void a_function_in_c() {
+        printf("hello world\n");
+    }
+```
 
 ### Symbols ###
 

          
@@ 201,16 208,18 @@ As a special case, `,` is always parsed 
 
 Here are some examples of valid symbols:
 
-    # classic underscore notation
-    some_identifier _some_identifier
-    # hyphenated
-    some-identifier
-    # mixed case
-    SomeIdentifier
-    # fantasy operators
-    &+ >~ >>= and= str+str
-    # numbered
-    _42 =303
+```scopes
+# classic underscore notation
+some_identifier _some_identifier
+# hyphenated
+some-identifier
+# mixed case
+SomeIdentifier
+# fantasy operators
+&+ >~ >>= and= str+str
+# numbered
+_42 =303
+```
 
 ### Numbers ###
 

          
@@ 226,18 235,20 @@ to the number as well as a numerical typ
 
 Here are some examples of valid numbers:
 
-    # positive and negative integers in decimal and hexadecimal notation
-    0 +23 42 -303 12 -1 -0x20 0xAFFE
-    # positive and negative reals
-    0.0 1.0 3.14159 -2.0 0.000003 0xa400.a400
-    # reals in scientific notation
-    1.234e+24 -1e-12
-    # special reals
-    +inf -inf nan
-    # zero as unsigned 64-bit integer and as signed 8-bit integer
-    0:u64 0:i8
-    # a floating-point number with double precision
-    1.0:f64
+```scopes
+# positive and negative integers in decimal and hexadecimal notation
+0 +23 42 -303 12 -1 -0x20 0xAFFE
+# positive and negative reals
+0.0 1.0 3.14159 -2.0 0.000003 0xa400.a400
+# reals in scientific notation
+1.234e+24 -1e-12
+# special reals
++inf -inf nan
+# zero as unsigned 64-bit integer and as signed 8-bit integer
+0:u64 0:i8
+# a floating-point number with double precision
+1.0:f64
+```
 
 ### Lists ###
 

          
@@ 249,14 260,16 @@ only separated by whitespace. They typic
 
 Here are some examples of valid lists:
 
-    # a list of numbers in naked format
-    1 2 3 4 5
-    # three empty braced lists within a naked list
-    () () ()
-    # a list containing a symbol, a string, an integer, a real, and an empty list
-    (print (.. "hello world") 303 606 909)
-    # three nesting lists
-    ((()))
+```scopes
+# a list of numbers in naked format
+1 2 3 4 5
+# three empty braced lists within a naked list
+() () ()
+# a list containing a symbol, a string, an integer, a real, and an empty list
+(print (.. "hello world") 303 606 909)
+# three nesting lists
+((()))
+```
 
 Naked & Braced Lists
 --------------------

          
@@ 268,9 281,11 @@ to what [Lisp](http://en.wikipedia.org/w
 [Scheme](http://en.wikipedia.org/wiki/Scheme_(programming_language)) authors
 know as *restricted* [S-expressions](https://en.wikipedia.org/wiki/S-expression>):
 
-    (print
-        (.. "Hello" "World")
-        303 606 909)
+```scopes
+(print
+    (.. "Hello" "World")
+    303 606 909)
+```
 
 As a modern alternative, Scopes offers a *naked notation* where the scope of
 lists is implicitly balanced by indentation, an approach used by

          
@@ 282,42 297,46 @@ other languages.
 
 This source parses as the same list in the previous, braced example:
 
-    # The same list as above, but in naked format.
-        A sub-paragraph continues the list.
-    print
-        # elements on a single line with or without sub-paragraph are wrapped
-          in a list.
-        .. "Hello" "World"
+```scopes
+# The same list as above, but in naked format.
+    A sub-paragraph continues the list.
+print
+    # elements on a single line with or without sub-paragraph are wrapped
+        in a list.
+    .. "Hello" "World"
 
-        # values that should not be wrapped have to be prefixed with an
-          escape token which causes a continuation of the parent list
-        \ 303 606 909
+    # values that should not be wrapped have to be prefixed with an
+        escape token which causes a continuation of the parent list
+    \ 303 606 909
+```
 
 ### Mixing Modes ###
 
 Naked lists can contain braced lists, and braced lists can
 contain naked lists:
 
-    # compute the value of (1 + 2 + (3 * 4)) and print the result
-    (print
-        (+ 1 2
-            (3 * 4)))
+```scopes
+# compute the value of (1 + 2 + (3 * 4)) and print the result
+(print
+    (+ 1 2
+        (3 * 4)))
 
-    # the same list in naked notation.
-      indented lists are appended to the parent list:
-    print
-        + 1 2
-            3 * 4
+# the same list in naked notation.
+    indented lists are appended to the parent list:
+print
+    + 1 2
+        3 * 4
 
-    # any part of a naked list can be braced
-    print
-        + 1 2 (3 * 4)
+# any part of a naked list can be braced
+print
+    + 1 2 (3 * 4)
 
-    # and a braced list can contain naked parts.
-      the escape character \ enters naked mode at its indentation level.
-    print
-        (+ 1 2
-            \ 3 * 4) # parsed as (+ 1 2 (3 * 4))
+# and a braced list can contain naked parts.
+    the escape character \ enters naked mode at its indentation level.
+print
+    (+ 1 2
+        \ 3 * 4) # parsed as (+ 1 2 (3 * 4))
+```
 
 Naked notation is strongly encouraged as it is more convenient for authors
 without specialized editors to write and balancing parentheses can be

          
@@ 334,13 353,15 @@ square `[]` brace styles. They are merel
 writing SLN-based formats, and are expanded to simple lists during parsing.
 Some examples:
 
-    [a b c d]
-    # expands to
-    (\[\] a b c d)
+```scopes
+[a b c d]
+# expands to
+(\[\] a b c d)
 
-    {1 2 3 4}
-    # expands to
-    (\{\} 1 2 3 4)
+{1 2 3 4}
+# expands to
+(\{\} 1 2 3 4)
+```
 
 List Separators
 ---------------

          
@@ 355,24 376,27 @@ mode by starting the head of the block w
 
 Here are some examples:
 
-    # in braced notation
-    (print a; print (a;b;); print c;)
-    # parses as
-    ((print a) (print ((a) (b))) (print c))
+```scopes
+# in braced notation
+(print a; print (a;b;); print c;)
+# parses as
+((print a) (print ((a) (b))) (print c))
 
-    # in naked notation
+# in naked notation
+;
+    print a; print b
     ;
-        print a; print b
-        ;
-            print c; print d
-    # parses as
-    ((print a) (print b) ((print c) (print d)))
+        print c; print d
+# parses as
+((print a) (print b) ((print c) (print d)))
+```
 
 !!! warning
 
     If semicolons are used with braced notation then any trailing elements that
     are not terminated with `;` will not be wrapped:
 
+        :::scopes
         # in braced notation
         (print a; print (a;b;); print c)
         # parses as

          
@@ 392,27 416,37 @@ wants to wrap them in a list.
 
 Here is a braced list describing an expression printing the number 42:
 
-    (print 42)
+```scopes
+(print 42)
+```
 
 The naked equivalent declares two elements in a single line, which are implicitly
 wrapped in a single list:
 
-    print 42
+```scopes
+print 42
+```
 
 A single element on its own line is not wrapped:
 
-    print           # (print
-        42          #        42)
+```scopes
+print           # (print
+    42          #        42)
+```
 
 What if we want to just print a newline, passing no arguments?:
 
-    print           # print
+```scopes
+print           # print
+```
 
 The statement above will be ignored because a symbol is resolved but not called.
 One can make use of the `;` (split-statement) control
 character, which ends the current list:
 
-    print;          # (print)
+```scopes
+print;          # (print)
+```
 
 ### Continuation Lines ###
 

          
@@ 422,118 456,138 @@ column limit (typically 80 or 100).
 
 In braced lists, the problem is easily corrected:
 
-    # import many symbols from an external module into the active namespace
-    (import-from "OpenGL"
-        glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT
-        GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram
-        glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP)
+```scopes
+# import many symbols from an external module into the active namespace
+(import-from "OpenGL"
+    glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT
+    GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram
+    glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP)
+```
 
 The naked approach interprets each new line as a nested list:
 
-    # produces runtime errors
-    import-from "OpenGL"
-        glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT
-        GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram
-        glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP
+```scopes
+# produces runtime errors
+import-from "OpenGL"
+    glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT
+    GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram
+    glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP
 
-    # braced equivalent of the term above; each line is interpreted
-    # as a function call and fails.
-    (import-from "OpenGL"
-        (glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT)
-        (GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram)
-        (glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP))
+# braced equivalent of the term above; each line is interpreted
+# as a function call and fails.
+(import-from "OpenGL"
+    (glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT)
+    (GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram)
+    (glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP))
+```
 
 This can be fixed by using the `splice-line` control character, `\`:
 
-    # correct solution using splice-line, postfix-style
-    import-from "OpenGL" \
-        glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT \
-        GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram \
-        glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP
+```scopes
+# correct solution using splice-line, postfix-style
+import-from "OpenGL" \
+    glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT \
+    GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram \
+    glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP
+```
 
 Unlike in other languages, and as previously demonstrated, `\` splices at the
 token level rather than the character level, and can also be placed at the
 beginning of nested lines, where the parent is still the active list:
 
-    # correct solution using the splice-line control character '\', prefix-style
-    import-from "OpenGL"
-        \ glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT
-        \ GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram
-        \ glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP
+```scopes
+# correct solution using the splice-line control character '\', prefix-style
+import-from "OpenGL"
+    \ glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT
+    \ GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram
+    \ glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP
+```
 
 ### Tail Splicing ###
 
 Naked notation is ideal for writing nested lists that accumulate at the tail:
 
-    # braced
-    (a b c
-        (d e f
-            (g h i))
-        (j k l))
+```scopes
+# braced
+(a b c
+    (d e f
+        (g h i))
+    (j k l))
 
-    # naked
-    a b c
-        d e f
-            g h i
-        j k l
+# naked
+a b c
+    d e f
+        g h i
+    j k l
+```
 
 However, there are complications when additional elements need to be spliced
 back into the parent list:
 
-    (a b c
-        (d e f
-            (g h i))
-        j k l)
+```scopes
+(a b c
+    (d e f
+        (g h i))
+    j k l)
+```
 
 Once again, we can reuse the splice-line control character `\` to get what we
 want:
 
-    a b c
-        d e f
-            g h i
-        \ j k l
+```scopes
+a b c
+    d e f
+        g h i
+    \ j k l
+```
 
 ### Left-Hand Nesting ###
 
 When using infix notation, conditional blocks, or functions producing functions,
 lists occur that nest at the head level rather than the tail:
 
-    ((((a b)
-        c d)
-            e f)
-                g h)
+```scopes
+((((a b)
+    c d)
+        e f)
+            g h)
+```
 
 The equivalent naked mode version makes extensive use of list separator and
 splice-line characters to describe the same tree:
 
-    # equivalent structure
+```scopes
+# equivalent structure
+;
     ;
         ;
-            ;
-                a b
-                \ c d
-            \ e f
-        \ g h
+            a b
+            \ c d
+        \ e f
+    \ g h
+```
 
 A more complex tree which also requires splicing elements back into the parent
 list can be implemented with the same combination of list separator and
 splice-line characters:
 
-    # braced
-    (a
-        ((b
-            (c d)) e)
-        f g
-        (h i))
+```scopes
+# braced
+(a
+    ((b
+        (c d)) e)
+    f g
+    (h i))
 
-    # naked
-    a
-        ;
-            b
-                c d
-            \ e
-        \ f g
-        h i
+# naked
+a
+    ;
+        b
+            c d
+        \ e
+    \ f g
+    h i
+```
 
 While this example demonstrates the versatility of the splice-line and list
 separator characters, use of partially braced notation may be easier to

          
M doc/docs/module-Array.md +57 -57
@@ 1,10 1,10 @@ 
 <style type="text/css" rel="stylesheet">body { counter-reset: chapter 7; }</style>
 
-Array
-=====
-
-Provides mutable array types that store their elements on the heap rather
-than in registers or the stack.
+Array
+=====
+
+Provides mutable array types that store their elements on the heap rather
+than in registers or the stack.
 
 *type*{.property} `Array`{.descname} [](#scopes.type.Array "Permalink to this definition"){.headerlink} {#scopes.type.Array}
 

          
@@ 12,69 12,69 @@ than in registers or the stack.
 
     *fn*{.property} `__@`{.descname} (*&ensp;self index&ensp;*)[](#scopes.Array.fn.__@ "Permalink to this definition"){.headerlink} {#scopes.Array.fn.__@}
 
-    :   Implements support for the `@` operator. Returns a view reference to the
-        element at `index` of array `self`.
+    :   Implements support for the `@` operator. Returns a view reference to the
+        element at `index` of array `self`.
 
     *inline*{.property} `__as`{.descname} (*&ensp;cls T&ensp;*)[](#scopes.Array.inline.__as "Permalink to this definition"){.headerlink} {#scopes.Array.inline.__as}
 
-    :   Implements support for the `as` operator. Arrays can be cast to
-        `Generator`, or directly passed to `for`.
+    :   Implements support for the `as` operator. Arrays can be cast to
+        `Generator`, or directly passed to `for`.
 
     *inline*{.property} `__countof`{.descname} (*&ensp;self&ensp;*)[](#scopes.Array.inline.__countof "Permalink to this definition"){.headerlink} {#scopes.Array.inline.__countof}
 
-    :   Implements support for the `countof` operator. Returns the current
-        number of elements stored in `self` as a value of `usize` type.
+    :   Implements support for the `countof` operator. Returns the current
+        number of elements stored in `self` as a value of `usize` type.
 
     *inline*{.property} `__drop`{.descname} (*&ensp;self&ensp;*)[](#scopes.Array.inline.__drop "Permalink to this definition"){.headerlink} {#scopes.Array.inline.__drop}
 
-    :   Implements support for freeing the array's memory when it goes out
-        of scope.
+    :   Implements support for freeing the array's memory when it goes out
+        of scope.
 
     *inline*{.property} `__imply`{.descname} (*&ensp;cls T&ensp;*)[](#scopes.Array.inline.__imply "Permalink to this definition"){.headerlink} {#scopes.Array.inline.__imply}
 
-    :   Implements support for pointer casts, to pass the array to C functions
-        for example.
+    :   Implements support for pointer casts, to pass the array to C functions
+        for example.
 
     *inline*{.property} `__typecall`{.descname} (*&ensp;cls element-type capacity&ensp;*)[](#scopes.Array.inline.__typecall "Permalink to this definition"){.headerlink} {#scopes.Array.inline.__typecall}
 
-    :   Construct a mutable array type of `element-type` with a variable or
-        fixed maximum capacity.
-        
-        If `capacity` is defined, then it specifies the maximum number
-        of array elements permitted. If it is undefined, then an initial
-        capacity of 16 elements is assumed, which is doubled whenever
-        it is exceeded, allowing for an indefinite number of elements.
+    :   Construct a mutable array type of `element-type` with a variable or
+        fixed maximum capacity.
+        
+        If `capacity` is defined, then it specifies the maximum number
+        of array elements permitted. If it is undefined, then an initial
+        capacity of 16 elements is assumed, which is doubled whenever
+        it is exceeded, allowing for an indefinite number of elements.
 
     *fn*{.property} `append`{.descname} (*&ensp;self value&ensp;*)[](#scopes.Array.fn.append "Permalink to this definition"){.headerlink} {#scopes.Array.fn.append}
 
-    :   Append `value` as an element to the array `self` and return a reference
-        to the new element. When the `array` is of `GrowingArray` type, this
-        operation will transparently resize the array's storage.
+    :   Append `value` as an element to the array `self` and return a reference
+        to the new element. When the `array` is of `GrowingArray` type, this
+        operation will transparently resize the array's storage.
 
     *fn*{.property} `clear`{.descname} (*&ensp;self&ensp;*)[](#scopes.Array.fn.clear "Permalink to this definition"){.headerlink} {#scopes.Array.fn.clear}
 
-    :   Clear the array and reset its element count to zero. This will drop
-        all elements that have been previously contained by the array.
+    :   Clear the array and reset its element count to zero. This will drop
+        all elements that have been previously contained by the array.
 
     *inline*{.property} `emplace-append`{.descname} (*&ensp;self args...&ensp;*)[](#scopes.Array.inline.emplace-append "Permalink to this definition"){.headerlink} {#scopes.Array.inline.emplace-append}
 
-    :   Construct a new element with arguments `args...` directly in a newly
-        assigned slot of array `self`. When the `array` is of `GrowingArray`
-        type, this operation will transparently resize the array's storage.
+    :   Construct a new element with arguments `args...` directly in a newly
+        assigned slot of array `self`. When the `array` is of `GrowingArray`
+        type, this operation will transparently resize the array's storage.
 
     *inline*{.property} `emplace-append-many`{.descname} (*&ensp;self size args...&ensp;*)[](#scopes.Array.inline.emplace-append-many "Permalink to this definition"){.headerlink} {#scopes.Array.inline.emplace-append-many}
 
-    :   Construct a new element with arguments `args...` directly in a newly
-        assigned slot of array `self`. When the `array` is of `GrowingArray`
-        type, this operation will transparently resize the array's storage.
+    :   Construct a new element with arguments `args...` directly in a newly
+        assigned slot of array `self`. When the `array` is of `GrowingArray`
+        type, this operation will transparently resize the array's storage.
 
     *type*{.property} `insert`{.descname} [](#scopes.Array.type.insert "Permalink to this definition"){.headerlink} {#scopes.Array.type.insert}
 
-    :   Insert `value` at `index` into the array `self` and return a reference
-        to the new element. When the `array` is of `GrowingArray` type, this
-        operation will transparently resize the array's storage.
-        This operation offsets the index of each following element by 1.
-        If index is omitted, `insert` operates like `append`.
+    :   Insert `value` at `index` into the array `self` and return a reference
+        to the new element. When the `array` is of `GrowingArray` type, this
+        operation will transparently resize the array's storage.
+        This operation offsets the index of each following element by 1.
+        If index is omitted, `insert` operates like `append`.
 
     *fn*{.property} `last`{.descname} (*&ensp;self&ensp;*)[](#scopes.Array.fn.last "Permalink to this definition"){.headerlink} {#scopes.Array.fn.last}
 

          
@@ 82,17 82,17 @@ than in registers or the stack.
 
     *fn*{.property} `pop`{.descname} (*&ensp;self&ensp;*)[](#scopes.Array.fn.pop "Permalink to this definition"){.headerlink} {#scopes.Array.fn.pop}
 
-    :   Remove element with highest index from array `self` and return it.
+    :   Remove element with highest index from array `self` and return it.
 
     *fn*{.property} `remove`{.descname} (*&ensp;self index&ensp;*)[](#scopes.Array.fn.remove "Permalink to this definition"){.headerlink} {#scopes.Array.fn.remove}
 
-    :   Remove element at index from array `self` and return it.
-        This operation offsets the index of each following element by -1.
+    :   Remove element at index from array `self` and return it.
+        This operation offsets the index of each following element by -1.
 
     *fn*{.property} `resize`{.descname} (*&ensp;self count args...&ensp;*)[](#scopes.Array.fn.resize "Permalink to this definition"){.headerlink} {#scopes.Array.fn.resize}
 
-    :   Resize the array to the specified count. Items are apppend or removed
-        to meet the desired count.
+    :   Resize the array to the specified count. Items are apppend or removed
+        to meet the desired count.
 
     *inline*{.property} `reverse`{.descname} (*&ensp;self&ensp;*)[](#scopes.Array.inline.reverse "Permalink to this definition"){.headerlink} {#scopes.Array.inline.reverse}
 

          
@@ 100,14 100,14 @@ than in registers or the stack.
 
     *inline*{.property} `sort`{.descname} (*&ensp;self key ...&ensp;*)[](#scopes.Array.inline.sort "Permalink to this definition"){.headerlink} {#scopes.Array.inline.sort}
 
-    :   Sort elements of array `self` from smallest to largest, either using
-        the `<` operator supplied by the element type, or by using the key
-        supplied by the callable `key`, which is expected to return a comparable
-        value for each element value supplied.
+    :   Sort elements of array `self` from smallest to largest, either using
+        the `<` operator supplied by the element type, or by using the key
+        supplied by the callable `key`, which is expected to return a comparable
+        value for each element value supplied.
 
     *fn*{.property} `swap`{.descname} (*&ensp;self a b&ensp;*)[](#scopes.Array.fn.swap "Permalink to this definition"){.headerlink} {#scopes.Array.fn.swap}
 
-    :   Safely swap the contents of two indices.
+    :   Safely swap the contents of two indices.
 
 *type*{.property} `FixedArray`{.descname} [](#scopes.type.FixedArray "Permalink to this definition"){.headerlink} {#scopes.type.FixedArray}
 

          
@@ 115,7 115,7 @@ than in registers or the stack.
 
     *fn*{.property} `__repr`{.descname} (*&ensp;self&ensp;*)[](#scopes.FixedArray.fn.__repr "Permalink to this definition"){.headerlink} {#scopes.FixedArray.fn.__repr}
 
-    :   Implements support for the `repr` operation.
+    :   Implements support for the `repr` operation.
 
     *inline*{.property} `__typecall`{.descname} (*&ensp;cls opts...&ensp;*)[](#scopes.FixedArray.inline.__typecall "Permalink to this definition"){.headerlink} {#scopes.FixedArray.inline.__typecall}
 

          
@@ 123,13 123,13 @@ than in registers or the stack.
 
     *inline*{.property} `capacity`{.descname} (*&ensp;self&ensp;*)[](#scopes.FixedArray.inline.capacity "Permalink to this definition"){.headerlink} {#scopes.FixedArray.inline.capacity}
 
-    :   Returns the maximum capacity of array `self`, which is fixed.
+    :   Returns the maximum capacity of array `self`, which is fixed.
 
     *fn*{.property} `reserve`{.descname} (*&ensp;self count&ensp;*)[](#scopes.FixedArray.fn.reserve "Permalink to this definition"){.headerlink} {#scopes.FixedArray.fn.reserve}
 
-    :   Internally used by the type. Ensures that array `self` can hold at least
-        `count` elements. A fixed array will raise an assertion when its
-        capacity has been exceeded.
+    :   Internally used by the type. Ensures that array `self` can hold at least
+        `count` elements. A fixed array will raise an assertion when its
+        capacity has been exceeded.
 
 *type*{.property} `GrowingArray`{.descname} [](#scopes.type.GrowingArray "Permalink to this definition"){.headerlink} {#scopes.type.GrowingArray}
 

          
@@ 137,7 137,7 @@ than in registers or the stack.
 
     *fn*{.property} `__repr`{.descname} (*&ensp;self&ensp;*)[](#scopes.GrowingArray.fn.__repr "Permalink to this definition"){.headerlink} {#scopes.GrowingArray.fn.__repr}
 
-    :   Implements support for the `repr` operation.
+    :   Implements support for the `repr` operation.
 
     *inline*{.property} `__typecall`{.descname} (*&ensp;cls opts...&ensp;*)[](#scopes.GrowingArray.inline.__typecall "Permalink to this definition"){.headerlink} {#scopes.GrowingArray.inline.__typecall}
 

          
@@ 145,10 145,10 @@ than in registers or the stack.
 
     *inline*{.property} `capacity`{.descname} (*&ensp;self&ensp;*)[](#scopes.GrowingArray.inline.capacity "Permalink to this definition"){.headerlink} {#scopes.GrowingArray.inline.capacity}
 
-    :   Returns the current maximum capacity of array `self`.
+    :   Returns the current maximum capacity of array `self`.
 
     *fn*{.property} `reserve`{.descname} (*&ensp;self count&ensp;*)[](#scopes.GrowingArray.fn.reserve "Permalink to this definition"){.headerlink} {#scopes.GrowingArray.fn.reserve}
 
-    :   Internally used by the type. Ensures that array `self` can hold at least
-        `count` elements. A growing array will always attempt to comply.
+    :   Internally used by the type. Ensures that array `self` can hold at least
+        `count` elements. A growing array will always attempt to comply.
 

          
M doc/docs/module-FunctionChain.md +2 -0
@@ 8,6 8,7 @@ a module to call back into dependent mod
 
 See following example:
 
+    :::scopes
     using import FunctionChain
 
     # declare new function chain

          
@@ 34,6 35,7 @@ See following example:
 
 Running this program will output:
 
+    :::text
     first handler activated with argument 1
     handler activated with argument 1
     last handler activated with argument 1

          
M doc/docs/module-core.md +7 -0
@@ 888,6 888,7 @@ parses the command-line and optionally e
     
     Here is a typical pattern for constructing a generator:
     
+        :::scopes
         inline make-generator (container)
             Generator
                 inline "start" ()

          
@@ 905,6 906,7 @@ parses the command-line and optionally e
     
     The generator can then be subsequently used like this:
     
+        :::scopes
         # this example prints up to two elements returned by a generator
         # generate a new instance bound to container
         let gen = (make-generator container)

          
@@ 2762,12 2764,14 @@ parses the command-line and optionally e
 
 :   usage example:
     
+        :::scopes
         error@ ('anchor value) "while checking parameter" "error in value"
 
 *fn*{.property} `error@+`{.descname} (*&ensp;error anchor traceback-msg&ensp;*)[](#scopes.fn.error@+ "Permalink to this definition"){.headerlink} {#scopes.fn.error@+}
 
 :   usage example:
     
+        :::scopes
         except (err)
             error@+ err ('anchor value) "while processing stream"
 

          
@@ 3279,6 3283,7 @@ parses the command-line and optionally e
 :   uncomma list l, wrapping all comma separated symbols as new lists
     example:
     
+        :::scopes
         (uncomma '(a , b c d , e f , g h)) -> '(a (b c d) (e f) (g h))
 
 *fn*{.property} `unpack-infix-op`{.descname} (*&ensp;op&ensp;*)[](#scopes.fn.unpack-infix-op "Permalink to this definition"){.headerlink} {#scopes.fn.unpack-infix-op}

          
@@ 3425,6 3430,7 @@ parses the command-line and optionally e
 
     Usage example:
 
+        :::scopes
         # add numbers from 0 to 9, skipping number 5, and print the result
         print
             fold (sum = 0) for i in (range 100)

          
@@ 4641,6 4647,7 @@ parses the command-line and optionally e
 
 :   This function can be used in conjunction with `from`:
     
+        :::scopes
         from (methodsof <object>) let method1 method2
     
     now the imported methods are implicitly bound to `<object>` and can be

          
M doc/docs/module-testing.md +2 -0
@@ 77,6 77,7 @@ fashion.
     
     usage:
     
+        :::scopes
         features    B1  B2  B3 ...
             ---
             A1      Y   N   Y

          
@@ 85,6 86,7 @@ fashion.
     
     will expand to:
     
+        :::scopes
         do
             Y A1 B1; N A1 B2; Y A1 B3
             N A2 B1; Y A2 B2; N A2 B3

          
A => doc/docs/pygments.css +69 -0
@@ 0,0 1,69 @@ 
+.codehilite .hll { background-color: #ffffcc }
+.codehilite  { background: #f8f8f8; }
+.codehilite .c { color: #408080; font-style: italic } /* Comment */
+.codehilite .err { border: 1px solid #FF0000 } /* Error */
+.codehilite .k { color: #008000; font-weight: bold } /* Keyword */
+.codehilite .o { color: #666666 } /* Operator */
+.codehilite .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
+.codehilite .cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.codehilite .cp { color: #BC7A00 } /* Comment.Preproc */
+.codehilite .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
+.codehilite .c1 { color: #408080; font-style: italic } /* Comment.Single */
+.codehilite .cs { color: #408080; font-style: italic } /* Comment.Special */
+.codehilite .gd { color: #A00000 } /* Generic.Deleted */
+.codehilite .ge { font-style: italic } /* Generic.Emph */
+.codehilite .gr { color: #FF0000 } /* Generic.Error */
+.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.codehilite .gi { color: #00A000 } /* Generic.Inserted */
+.codehilite .go { color: #888888 } /* Generic.Output */
+.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.codehilite .gs { font-weight: bold } /* Generic.Strong */
+.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.codehilite .gt { color: #0044DD } /* Generic.Traceback */
+.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.codehilite .kp { color: #008000 } /* Keyword.Pseudo */
+.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.codehilite .kt { color: #B00040 } /* Keyword.Type */
+.codehilite .m { color: #666666 } /* Literal.Number */
+.codehilite .s { color: #BA2121 } /* Literal.String */
+.codehilite .na { color: #7D9029 } /* Name.Attribute */
+.codehilite .nb { color: #008000 } /* Name.Builtin */
+.codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.codehilite .no { color: #880000 } /* Name.Constant */
+.codehilite .nd { color: #AA22FF } /* Name.Decorator */
+.codehilite .ni { color: #999999; font-weight: bold } /* Name.Entity */
+.codehilite .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.codehilite .nf { color: #0000FF } /* Name.Function */
+.codehilite .nl { color: #A0A000 } /* Name.Label */
+.codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */
+.codehilite .nv { color: #19177C } /* Name.Variable */
+.codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.codehilite .w { color: #bbbbbb } /* Text.Whitespace */
+.codehilite .mb { color: #666666 } /* Literal.Number.Bin */
+.codehilite .mf { color: #666666 } /* Literal.Number.Float */
+.codehilite .mh { color: #666666 } /* Literal.Number.Hex */
+.codehilite .mi { color: #666666 } /* Literal.Number.Integer */
+.codehilite .mo { color: #666666 } /* Literal.Number.Oct */
+.codehilite .sa { color: #BA2121 } /* Literal.String.Affix */
+.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */
+.codehilite .sc { color: #BA2121 } /* Literal.String.Char */
+.codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */
+.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */
+.codehilite .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */
+.codehilite .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.codehilite .sx { color: #008000 } /* Literal.String.Other */
+.codehilite .sr { color: #BB6688 } /* Literal.String.Regex */
+.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */
+.codehilite .ss { color: #19177C } /* Literal.String.Symbol */
+.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */
+.codehilite .fm { color: #0000FF } /* Name.Function.Magic */
+.codehilite .vc { color: #19177C } /* Name.Variable.Class */
+.codehilite .vg { color: #19177C } /* Name.Variable.Global */
+.codehilite .vi { color: #19177C } /* Name.Variable.Instance */
+.codehilite .vm { color: #19177C } /* Name.Variable.Magic */
+.codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */

          
M doc/docs/tutorial.md +214 -162
@@ 18,24 18,30 @@ to start it is to simply launch the exec
 is usually located in the root directory, and on Unix-compatible systems
 it can simply be started from the terminal with:
 
-    $ ./scopes
+```bash
+$ ./scopes
+```
 
 On Windows, and on systems where Scopes has been installed system-wide, it can
 be started from the command line without the preceding dot:
 
-    > scopes
+```text
+> scopes
+```
 
 ### Interactive Console ###
 
 When `scopes` is launched without arguments, it enters an interactive
 read-eval-print loop (REPL), also called a console. Here is an example:
 
-    $ ./scopes
-      \\\
-       \\\
-     ///\\\
-    ///  \\\  Scopes 0.14 (Apr 17 2019, 19:43:48)
-    $0 ▶
+```bash
+$ ./scopes
+  \\\
+   \\\    Scopes 0.14 (Apr 17 2019, 19:43:48)
+ ///\\\   http://scopes.rocks
+///  \\\  
+$0 ▶
+```
 
 !!! attention
 

          
@@ 49,30 55,36 @@ read-eval-print loop (REPL), also called
 Simple expressions can be written on a single line, followed by hitting the
 return key:
 
-    $0 ▶ print "hello world"
-    hello world
-    $0 ▶
+```scopes
+$0 ▶ print "hello world"
+hello world
+$0 ▶
+```
 
 Multiline expressions can be entered by trailing the first line with a space
 character, and exited by entering nothing on the last line:
 
-    $0 ▶ print#put a space here
-    ....     "yes"
-    ....     "this"
-    ....     "is"
-    ....     "dog"
-    ....
-    yes this is dog
-    $0 ▶
+```scopes
+$0 ▶ print#put a space here
+....     "yes"
+....     "this"
+....     "is"
+....     "dog"
+....
+yes this is dog
+$0 ▶
+```
 
 Entering a value binds it to the name indicated by the prompt, and can then
 be reused:
 
-    $0 ▶ 3
-    $0 = 3
-    $1 ▶ print $0
-    3
-    $1 ▶
+```scopes
+$0 ▶ 3
+$0 = 3
+$1 ▶ print $0
+3
+$1 ▶
+```
 
 A special keyboard shortcut (`Control+D`) at the prompt exits the program.
 You can also exit the program by typing `exit;` followed by hitting the

          
@@ 84,7 96,9 @@ Most of the time you would like to use S
 written Scopes programs. This is simply done by appending the name of the
 Scopes file you would like to launch to the executable:
 
-    $ scopes path/to/my/program.sc
+```bash
+$ scopes path/to/my/program.sc
+```
 
 A Fistful of Scopes
 -------------------

          
@@ 95,24 109,28 @@ to the first line starting with a charac
 
 Some examples:
 
-    # this is the first comment
-    print "hey!" # and this is a second comment
-                   and a third, continuing on the same indentation
-    let str = "# hash characters inside string quotes do not count as comments"
+```scopes
+# this is the first comment
+print "hey!" # and this is a second comment
+               and a third, continuing on the same indentation
+let str = "# hash characters inside string quotes do not count as comments"
+```
 
 ### Using Scopes as a Calculator ###
 
 Scopes is not only a fully-fledged compiler infrastructure, but also works
 nicely as a comfy calculator:
 
-    $0 ▶ 1 + 2 + 3
-    $0 = 6
-    $1 ▶ 23 + 2 * 21
-    $1 = 65
-    $2 ▶ (23 + 2 * 21) / 5
-    $2 = 13.0
-    $3 ▶ 8 / 5 # all divisions return a floating point number
-    $3 = 1.6
+```scopes
+$0 ▶ 1 + 2 + 3
+$0 = 6
+$1 ▶ 23 + 2 * 21
+$1 = 65
+$2 ▶ (23 + 2 * 21) / 5
+$2 = 13.0
+$3 ▶ 8 / 5 # all divisions return a floating point number
+$3 = 1.6
+```
 
 Integer numbers like `6` or `65` have type `i32`, real numbers with a
 fractional part like `13.0` or `1.6` have type `f32`.

          
@@ 123,6 141,7 @@ fractional part like `13.0` or `1.6` hav
     operators and numbers are omitted that the Interactive Console will
     display an error when evaluating the expression. For example:
 
+        :::scopes
         $0 ▶ 1+2+3
         <string>:1:1: while expanding
             1+2+3

          
@@ 138,14 157,16 @@ Division always returns a real number. O
 integer result without the fractional part, use the floor division operator
 `//`:
 
-    $0 ▶ 23 / 3 # regular division returns a real
-    $0 = 7.666667
-    $1 ▶ 23 // 3 # floor division returns an integer
-    $1 = 7
-    $2 ▶ 23 % 3 # modulo returns the remainder
-    $2 = 2
-    $3 ▶ $1 * 3 + $2 # result * divisor + remainder
-    $3 = 23
+```scopes
+$0 ▶ 23 / 3 # regular division returns a real
+$0 = 7.666667
+$1 ▶ 23 // 3 # floor division returns an integer
+$1 = 7
+$2 ▶ 23 % 3 # modulo returns the remainder
+$2 = 2
+$3 ▶ $1 * 3 + $2 # result * divisor + remainder
+$3 = 23
+```
 
 ### Binding Names ###
 

          
@@ 153,38 174,44 @@ Notice how the last example leveraged th
 console to bind any result to a name for reuse. But we can also make use of
 `let` to bind values to specific names:
 
-    $0 ▶ let width = 23
-    23
-    $0 ▶ let height = 42
-    42
-    $0 ▶ width * height
-    $0 = 966
+```scopes
+$0 ▶ let width = 23
+23
+$0 ▶ let height = 42
+42
+$0 ▶ width * height
+$0 = 966
+```
 
 If a name is not bound to anything, using it will give you an error, which is
 useful when you've just mistyped it:
 
-    $0 ▶ let color = "red"
-    $0 ▶ colour
-    <string>:1:1: while expanding
-        colour
-    error: syntax: identifier 'colour' is not declared in scope. Did you mean 'color'?
+```scopes
+$0 ▶ let color = "red"
+$0 ▶ colour
+<string>:1:1: while expanding
+    colour
+error: syntax: identifier 'colour' is not declared in scope. Did you mean 'color'?
+```
 
 ### Strings ###
 
 Life can be tedious and boring at times. Why not perform some string operations
 to pass the time? We start with some light declarations of string literals:
 
-    $0 ▶ "make it so" # every string is wrapped in double quotes
-    $0 = "make it so"
-    $1 ▶ "\"make it so!\", he said" # nested quotes need to be escaped
-    $1 = "\"make it so!\", he said"
-    $2 ▶ "'make it so!', he said" # single quotes are no problem though
-    $2 = "'make it so!', he said"
-    $3 ▶ """"1. make it so
-             2. ???
-             3. profit!
-    ....
-    $3 = "1. make it so\n2. ???\n3. profit!\n"
+```scopes
+$0 ▶ "make it so" # every string is wrapped in double quotes
+$0 = "make it so"
+$1 ▶ "\"make it so!\", he said" # nested quotes need to be escaped
+$1 = "\"make it so!\", he said"
+$2 ▶ "'make it so!', he said" # single quotes are no problem though
+$2 = "'make it so!', he said"
+$3 ▶ """"1. make it so
+            2. ???
+            3. profit!
+....
+$3 = "1. make it so\n2. ???\n3. profit!\n"
+```
 
 In the interactive console output, the output string is enclosed in quotes and
 special characters are escaped with backslashes, to match the way the string

          
@@ 192,72 219,84 @@ has been declared. Sometimes this might 
 but the strings are equivalent. The `print` function produces a more readable
 output that produces the intended look:
 
-    $0 ▶ print "make it so"
-    make it so
-    $0 ▶ print "\"make it so!\", he said"
-    "make it so!", he said
-    $0 ▶ print """"1. "make it so!", he said
-                   2. ???
-                   3. profit!"
-    ....
-    1. "make it so!", he said
-    2. ???
-    3. profit!
+```scopes
+$0 ▶ print "make it so"
+make it so
+$0 ▶ print "\"make it so!\", he said"
+"make it so!", he said
+$0 ▶ print """"1. "make it so!", he said
+                2. ???
+                3. profit!"
+....
+1. "make it so!", he said
+2. ???
+3. profit!
+```
 
 Sometimes it is necessary to join several strings into one. Strings can be
 joined with the `..` operator:
 
-    $0 ▶ "Sco" .. "pes" .. "!" # joining three strings together
-    $0 = "Scopes!"
-    $1 ▶ .. "Sco" "pes" "!" # using prefix notation
-    $1 = "Scopes!"
+```scopes
+$0 ▶ "Sco" .. "pes" .. "!" # joining three strings together
+$0 = "Scopes!"
+$1 ▶ .. "Sco" "pes" "!" # using prefix notation
+$1 = "Scopes!"
+```
 
 The inverse operation, slicing strings, can be performed with the `lslice`,
 `rslice` and `slice` operations:
 
-    $0 ▶ "scopes" # bind the string we are working on to $0
-    $0 = "scopes"
-    $1 ▶ rslice $0 1 # slice right side starting at the second character
-    $1 = "copes"
-    $2 ▶ slice $0 1 5 # slice four letters from the center
-    $2 = "cope"
-    $3 ▶ lslice $0 ((countof $0) - 1) # a negative index selects from the back
-    $3 = "scope"
-    $4 ▶ rslice $0 ((countof $0) - 2) # get the last two characters
-    $4 = "es"
-    $5 ▶ slice $0 2 3 # get the center character
-    $5 = "o"
+```scopes
+$0 ▶ "scopes" # bind the string we are working on to $0
+$0 = "scopes"
+$1 ▶ rslice $0 1 # slice right side starting at the second character
+$1 = "copes"
+$2 ▶ slice $0 1 5 # slice four letters from the center
+$2 = "cope"
+$3 ▶ lslice $0 ((countof $0) - 1) # a negative index selects from the back
+$3 = "scope"
+$4 ▶ rslice $0 ((countof $0) - 2) # get the last two characters
+$4 = "es"
+$5 ▶ slice $0 2 3 # get the center character
+$5 = "o"
+```
 
 One way to remember how slices work is to think of the indices as pointing
 *between* characters, with the left edge of the first character numbered 0. Then
 the right edge of the last character of a string of *n* characters has index *n*,
 for example:
 
-     +---+---+---+---+---+---+
-     | S | c | o | p | e | s |
-     +---+---+---+---+---+---+
-     0   1   2   3   4   5   6
+```text
++---+---+---+---+---+---+
+| S | c | o | p | e | s |
++---+---+---+---+---+---+
+0   1   2   3   4   5   6
+```
 
 If we are interested in the byte value of a single character from a string, we
 can use the `@` operator, also called the at-operator, to extract it:
 
-    $0 ▶ "abc" @ 0
-    $0 = 97:i8
-    $1 ▶ "abc" @ 1
-    $1 = 98:i8
-    $2 ▶ "abc" @ 2
-    $2 = 99:i8
-    $3 ▶ "abc" @ ((countof "abc") - 1) # get the last character
-    $3 = 99:i8
+```scopes
+$0 ▶ "abc" @ 0
+$0 = 97:i8
+$1 ▶ "abc" @ 1
+$1 = 98:i8
+$2 ▶ "abc" @ 2
+$2 = 99:i8
+$3 ▶ "abc" @ ((countof "abc") - 1) # get the last character
+$3 = 99:i8
+```
 
 The `countof` operation returns the byte length of a string:
 
-    $2 ▶ countof "six"
-    $2 = 3:usize
-    $3 ▶ countof "three"
-    $3 = 5:usize
-    $4 ▶ countof "five"
-    $4 = 4:usize
+```scopes
+$2 ▶ countof "six"
+$2 = 3:usize
+$3 ▶ countof "three"
+$3 = 5:usize
+$4 ▶ countof "five"
+$4 = 4:usize
+```
 
 ### A Mild Breeze of Programming ###
 

          
@@ 265,20 304,22 @@ Many calculations require repeating an o
 Scopes can also do that. For instance, here is one of the typical examples
 for such a task, computing the first few numbers of the fibonacci sequence:
 
-    $0 ▶ loop (a b = 0 1)
-    ....     if (b < 10)
-    ....         print b
-    ....         repeat b (a + b)
-    ....     else
-    ....         break b
-    ....
-    1
-    1
-    2
-    3
-    5
-    8
-    $0 = 13
+```scopes
+$0 ▶ loop (a b = 0 1)
+....     if (b < 10)
+....         print b
+....         repeat b (a + b)
+....     else
+....         break b
+....
+1
+1
+2
+3
+5
+8
+$0 = 13
+```
 
 In Scopes, indentation is how the grouping of statements is determined which
 is why the conditional block is indented. A tab or four spaces must start each

          
@@ 297,6 338,7 @@ This example introduces several new feat
   the same time. `a` is initially bound to `0`, while `b` is initialized
   to `1`:
 
+        :::scopes
         $0 ▶ loop (a b = 0 1)
 
 * On the second line, we perform a *conditional operation*. That is, the

          
@@ 304,6 346,7 @@ This example introduces several new feat
   expression `(b < 10)` evaluates to `true`. In other words: we are going
   to be performing the loop as long as `b` is smaller than `10`:
 
+        :::scopes
         ....     if (b < 10)
 
     !!! tip

          
@@ 316,15 359,18 @@ This example introduces several new feat
 * On line 4, the loop will be repeated with `a` bound to the value of `b`,
   while `b` will be bound to the result of calculating `(a + b)`:
 
+        :::scopes
         ....         repeat b (a + b)
 
 * On line 5, we introduce the alternative block to be executed when `b`
   is greater or equal to `10`:
 
+        :::scopes
         ....     else
 
 * On line 6, we break from the loop, returning the final value of `b`:
 
+        :::scopes
         ....         break b
 
 Controlling Flow

          
@@ 338,51 384,57 @@ You have seen a small bit of `if` in tha
 go-to solution for any task that requires the program to make decisions.
 Another example:
 
-    $0 ▶ sc_prompt "please enter a word: " ""
-    please enter a word: bang
-    $0 $1 = true "bang"
-    $2 ▶ if ($1 < "n")
-    ....     print "early in the dictionary, good choice!"
-    .... elseif ($1 == "scopes")
-    ....     print "oh, a very good word!"
-    .... elseif ($1 == "")
-    ....     print "that is no word at all!"
-    .... else
-    ....     print "late in the dictionary, nice!"
-    ....
-    early in the dictionary, good choice!
+```scopes
+$0 ▶ sc_prompt "please enter a word: " ""
+please enter a word: bang
+$0 $1 = true "bang"
+$2 ▶ if ($1 < "n")
+....     print "early in the dictionary, good choice!"
+.... elseif ($1 == "scopes")
+....     print "oh, a very good word!"
+.... elseif ($1 == "")
+....     print "that is no word at all!"
+.... else
+....     print "late in the dictionary, nice!"
+....
+early in the dictionary, good choice!
+```
 
 You can also use `if` to decide on an expression:
 
-    $0 ▶ let chosen = true
-    true
-    $0 ▶ print "you chose"
-    ....     if x
-    ....         "poorly"
-    ....     elseif
-    ....         "wisely"
-    ....
-    you chose poorly
+```scopes
+$0 ▶ let chosen = true
+true
+$0 ▶ print "you chose"
+....     if x
+....         "poorly"
+....     elseif
+....         "wisely"
+....
+you chose poorly
+```
 
 ### Defining Functions ###
 
 Let us generalize the fibonacci example from earlier to a function that can
 write numbers from the fibonacci sequence up to an arbitrary boundary:
 
-    $0 ▶ fn fib (n) # write Fibonacci series up to n
-    ....     loop (a b = 0 1)
-    ....         if (a < n)
-    ....             io-write! (repr a)
-    ....             io-write! " "
-    ....             repeat b (a + b)
-    ....         else
-    ....             io-write! "\n"
-    ....             break b
-    ....
-    fib:Closure
-    $0 ▶ fib 2000 # call the function we just defined
-    0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
-    $0 = 4181
+```scopes
+$0 ▶ fn fib (n) # write Fibonacci series up to n
+....     loop (a b = 0 1)
+....         if (a < n)
+....             io-write! (repr a)
+....             io-write! " "
+....             repeat b (a + b)
+....         else
+....             io-write! "\n"
+....             break b
+....
+fib:Closure
+$0 ▶ fib 2000 # call the function we just defined
+0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
+$0 = 4181
+```
 
 The keyword `fn` introduces a function definition. It must be followed by an
 optional name and a list of formal parameters. All expressions that follow

          
M doc/make.bat +17 -2
@@ 6,7 6,7 @@ if "%MKDOCS%" == "" (
 	set MKDOCS=mkdocs
 )
 set BUILDDIR=site
-set MKDOCSOPTS=
+set PYBUILDDIR=site-packages
 
 if "%1" == "" goto help
 

          
@@ 15,12 15,15 @@ if "%1" == "help" (
 	echo.Please use `make ^<target^>` where ^<target^> is one of
 	echo.  clean      to discard generated documentation
 	echo.  html       to make standalone HTML files
+	echo.  serve      to start a web server in preview mode for editing
 	goto end
 )
 
 if "%1" == "clean" (
 	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
 	del /q /s %BUILDDIR%\*
+	for /d %%i in (%PYBUILDDIR%\*) do rmdir /q /s %%i
+	del /q /s %PYBUILDDIR%\*
 	goto end
 )
 

          
@@ 38,11 41,23 @@ if errorlevel 9009 (
 )
 
 if "%1" == "html" (
-	%MKDOCS% %MKDOCSOPTS% build -d %BUILDDIR%
+	set PYTHONDONTWRITEBYTECODE=1
+	set PYTHONPATH=site-packages;
+	pip install --upgrade -I ./ScopesLexer -t "%PYBUILDDIR%"
+	python -B -m mkdocs build -d "%BUILDDIR%"
 	if errorlevel 1 exit /b 1
 	echo.
 	echo.Build finished. The HTML pages are in %BUILDDIR%/.
 	goto end
 )
 
+if "%1" == "serve" (
+	set PYTHONDONTWRITEBYTECODE=1
+	set PYTHONPATH=site-packages;
+	pip install --upgrade -I ./ScopesLexer -t "%PYBUILDDIR%"
+	python -B -m mkdocs serve 
+	if errorlevel 1 exit /b 1
+	goto end
+)
+
 :end

          
M doc/mkdocs.yml +4 -2
@@ 22,8 22,10 @@ nav:
         - "struct": module-struct.md
         - "testing": module-testing.md
         - "UTF-8": module-UTF-8.md
-theme: readthedocs
-extra_css: [extra.css]
+theme:
+    name: readthedocs
+    highlightjs: false
+extra_css: [extra.css, pygments.css]
 markdown_extensions:
     - admonition:
     - attr_list:

          
M lib/scopes/Array.sc +2 -0
@@ 341,10 341,12 @@ let DEFAULT_CAPACITY = (1:usize << 2:usi
 
     To construct a new growing array type:
 
+        :::scopes
         GrowingArray element-type
 
     Instantiate a new array with mutable memory:
 
+        :::scopes
         local new-array : (GrowingArray element-type) [(capacity = ...)]
 typedef+ GrowingArray
     let parent-type = this-type

          
M lib/scopes/FunctionChain.sc +2 -1
@@ 11,6 11,7 @@ 
 
     See following example:
 
+        :::scopes
         using import FunctionChain
 
         # declare new function chain

          
@@ 37,6 38,7 @@ 
 
     Running this program will output:
 
+        :::text
         first handler activated with argument 1
         handler activated with argument 1
         last handler activated with argument 1

          
@@ 44,7 46,6 @@ 
         handler activated with argument 2
         last handler activated with argument 2
         handler activated with argument 3
-
 typedef FunctionChain : (storageof type)
     inline __repr (self)
         repr (bitcast self type)

          
M lib/scopes/String.sc +4 -0
@@ 339,10 339,12 @@ typedef+ StringBase
 
     To construct a new fixed string type:
 
+        :::scopes
         FixedString element-type capacity
 
     Instantiate a new string with mutable memory:
 
+        :::scopes
         local new-string : (FixedString element-type capacity)
 typedef+ FixedString
     let parent-type = this-type

          
@@ 418,10 420,12 @@ let DEFAULT_CAPACITY = (1:usize << 2:usi
 
     To construct a new growing string type:
 
+        :::scopes
         GrowingString element-type
 
     Instantiate a new string with mutable memory:
 
+        :::scopes
         local new-string : (GrowingString element-type) [(capacity = ...)]
 typedef+ GrowingString
     let parent-type = this-type

          
M lib/scopes/core.sc +7 -1
@@ 81,6 81,7 @@ fn error (msg)
 fn error@ (anchor traceback-msg error-msg)
     """"usage example:
 
+            :::scopes
             error@ ('anchor value) "while checking parameter" "error in value"
     hide-traceback;
     let err = (sc_error_new error-msg)

          
@@ 90,6 91,7 @@ fn error@ (anchor traceback-msg error-ms
 fn error@+ (error anchor traceback-msg)
     """"usage example:
 
+            :::scopes
             except (err)
                 error@+ err ('anchor value) "while processing stream"
     hide-traceback;

          
@@ 1236,6 1238,7 @@ sc_typename_type_set_opaque Struct
 
     Here is a typical pattern for constructing a generator:
 
+        :::scopes
         inline make-generator (container)
             Generator
                 inline "start" ()

          
@@ 1253,6 1256,7 @@ sc_typename_type_set_opaque Struct
 
     The generator can then be subsequently used like this:
 
+        :::scopes
         # this example prints up to two elements returned by a generator
         # generate a new instance bound to container
         let gen = (make-generator container)

          
@@ 1270,7 1274,6 @@ sc_typename_type_set_opaque Struct
                 # container has one more item; print it
                 print (at state...)
         # we are done; no cleanup necessary
-
 let Generator = (sc_typename_type "Generator" typename)
 'set-plain-storage Generator ('storageof Closure)
 

          
@@ 5524,6 5527,7 @@ fn uncomma (l)
     """"uncomma list l, wrapping all comma separated symbols as new lists
         example:
 
+            :::scopes
             (uncomma '(a , b c d , e f , g h)) -> '(a (b c d) (e f) (g h))
     fn comma-separated? (l)
         loop (next = l)

          
@@ 6807,6 6811,7 @@ sugar unlet ((name as Symbol) names...)
 
         Usage example:
 
+            :::scopes
             # add numbers from 0 to 9, skipping number 5, and print the result
             print
                 fold (sum = 0) for i in (range 100)

          
@@ 7883,6 7888,7 @@ typedef MethodsAccessor
 
 """"This function can be used in conjunction with `from`:
 
+        :::scopes
         from (methodsof <object>) let method1 method2
 
     now the imported methods are implicitly bound to `<object>` and can be

          
M lib/scopes/testing.sc +2 -0
@@ 169,6 169,7 @@ sugar test-compiler-error (args...)
 
     usage:
 
+        :::scopes
         features    B1  B2  B3 ...
             ---
             A1      Y   N   Y

          
@@ 177,6 178,7 @@ sugar test-compiler-error (args...)
 
     will expand to:
 
+        :::scopes
         do
             Y A1 B1; N A1 B2; Y A1 B3
             N A2 B1; Y A2 B2; N A2 B3