diff --git a/README.md b/README.md
index 3118724a..b4f0853d 100644
--- a/README.md
+++ b/README.md
@@ -22,24 +22,24 @@ Features
--------
* Easy-to-use language similar to JS+Rust with dynamic typing.
-* Tight integration with native Rust [functions](https://schungx.github.io/rust/functions.html) and [types]([#custom-types-and-methods](https://schungx.github.io/rust/custom.html)), including [getters/setters](https://schungx.github.io/rust/getters-setters.html), [methods](https://schungx.github.io/rust/custom.html) and [indexers](https://schungx.github.io/rust/indexers.html).
-* Freely pass Rust variables/constants into a script via an external [`Scope`](https://schungx.github.io/rust/scope.html).
-* Easily [call a script-defined function](https://schungx.github.io/engine/call-fn.html) from Rust.
+* Tight integration with native Rust [functions](https://schungx.github.io/rhai/rust/functions.html) and [types]([#custom-types-and-methods](https://schungx.github.io/rhai/rust/custom.html)), including [getters/setters](https://schungx.github.io/rhai/rust/getters-setters.html), [methods](https://schungx.github.io/rhai/rust/custom.html) and [indexers](https://schungx.github.io/rhai/rust/indexers.html).
+* Freely pass Rust variables/constants into a script via an external [`Scope`](https://schungx.github.io/rhai/rust/scope.html).
+* Easily [call a script-defined function](https://schungx.github.io/rhai/engine/call-fn.html) from Rust.
* Fairly low compile-time overhead.
* Fairly efficient evaluation (1 million iterations in 0.25 sec on a single core, 2.3 GHz Linux VM).
* Relatively little `unsafe` code (yes there are some for performance reasons, and most `unsafe` code is limited to
one single source file, all with names starting with `"unsafe_"`).
* Re-entrant scripting engine can be made `Send + Sync` (via the [`sync`] feature).
* Sand-boxed - the scripting engine, if declared immutable, cannot mutate the containing environment unless explicitly permitted (e.g. via a `RefCell`).
-* Rugged - protection against malicious attacks (such as [stack-overflow](https://schungx.github.io/safety/max-call-stack.html), [over-sized data](https://schungx.github.io/safety/max-string-size.html), and [runaway scripts](https://schungx.github.io/safety/max-operations.html) etc.) that may come from untrusted third-party user-land scripts.
-* Track script evaluation [progress](https://schungx.github.io/safety/progress.html) and manually terminate a script run.
-* [Function overloading](https://schungx.github.io/language/overload.html).
-* [Operator overloading](https://schungx.github.io/rust/operators.html).
-* Organize code base with dynamically-loadable [modules](https://schungx.github.io/language/modules.html).
-* Scripts are [optimized](https://schungx.github.io/engine/optimize.html) (useful for template-based machine-generated scripts) for repeated evaluations.
-* Support for [minimal builds](https://schungx.github.io/start/builds/minimal.html) by excluding unneeded language [features](https://schungx.github.io/start/features.html).
+* Rugged - protection against malicious attacks (such as [stack-overflow](https://schungx.github.io/rhai/safety/max-call-stack.html), [over-sized data](https://schungx.github.io/rhai/safety/max-string-size.html), and [runaway scripts](https://schungx.github.io/rhai/safety/max-operations.html) etc.) that may come from untrusted third-party user-land scripts.
+* Track script evaluation [progress](https://schungx.github.io/rhai/safety/progress.html) and manually terminate a script run.
+* [Function overloading](https://schungx.github.io/rhai/language/overload.html).
+* [Operator overloading](https://schungx.github.io/rhai/rust/operators.html).
+* Organize code base with dynamically-loadable [modules](https://schungx.github.io/rhai/language/modules.html).
+* Scripts are [optimized](https://schungx.github.io/rhai/engine/optimize.html) (useful for template-based machine-generated scripts) for repeated evaluations.
+* Support for [minimal builds](https://schungx.github.io/rhai/start/builds/minimal.html) by excluding unneeded language [features](https://schungx.github.io/rhai/start/features.html).
Documentation
-------------
-See [The Rhai Book](https://schungx.github.io/rhai/) for details on the Rhai script engine and language.
+See [The Rhai Book](https://schungx.github.io/rhai) for details on the Rhai script engine and language.
diff --git a/doc/book.toml b/doc/book.toml
index 5d3eae3a..44097145 100644
--- a/doc/book.toml
+++ b/doc/book.toml
@@ -6,7 +6,11 @@ language = "en"
[output.html]
no-section-label = true
+git-repository-url = "https://github.com/jonathandturner/rhai"
[output.html.fold]
enable = true
-level = 4
\ No newline at end of file
+level = 4
+
+[preprocessor.tera]
+command = "mdbook-tera --json ./src/context.json"
diff --git a/doc/src/about/features.md b/doc/src/about/features.md
index 1636ffe8..16910c63 100644
--- a/doc/src/about/features.md
+++ b/doc/src/about/features.md
@@ -8,11 +8,11 @@ Easy
* Easy-to-use language similar to JS+Rust with dynamic typing.
-* Tight integration with native Rust [functions](/rust/functions.md) and [types](/rust/custom.md), including [getters/setters](/rust/getters-setters.md), [methods](/rust/custom.md) and [indexers](/rust/indexers.md).
+* Tight integration with native Rust [functions]({{rootUrl}}/rust/functions.md) and [types]({{rootUrl}}/rust/custom.md), including [getters/setters]({{rootUrl}}/rust/getters-setters.md), [methods]({{rootUrl}}/rust/custom.md) and [indexers]({{rootUrl}}/rust/indexers.md).
* Freely pass Rust variables/constants into a script via an external [`Scope`].
-* Easily [call a script-defined function](/engine/call-fn.md) from Rust.
+* Easily [call a script-defined function]({{rootUrl}}/engine/call-fn.md) from Rust.
* Very few additional dependencies (right now only [`num-traits`](https://crates.io/crates/num-traits/) to do checked arithmetic operations);
for [`no-std`] builds, a number of additional dependencies are pulled in to provide for functionalities that used to be in `std`.
@@ -24,14 +24,14 @@ Fast
* Fairly efficient evaluation (1 million iterations in 0.25 sec on a single core, 2.3 GHz Linux VM).
-* Scripts are [optimized](/engine/optimize.md) (useful for template-based machine-generated scripts) for repeated evaluations.
+* Scripts are [optimized]({{rootUrl}}/engine/optimize.md) (useful for template-based machine-generated scripts) for repeated evaluations.
Dynamic
-------
-* [Function overloading](/language/overload.md).
+* [Function overloading]({{rootUrl}}/language/overload.md).
-* [Operator overloading](/rust/operators.md).
+* [Operator overloading]({{rootUrl}}/rust/operators.md).
* Organize code base with dynamically-loadable [modules].
@@ -46,7 +46,7 @@ Rugged
* Sand-boxed - the scripting [`Engine`], if declared immutable, cannot mutate the containing environment unless explicitly permitted (e.g. via a `RefCell`).
-* Protected against malicious attacks (such as [stack-overflow](/safety/max-call-stack.md), [over-sized data](/safety/max-string-size.md), and [runaway scripts](/safety/max-operations.md) etc.) that may come from untrusted third-party user-land scripts.
+* Protected against malicious attacks (such as [stack-overflow]({{rootUrl}}/safety/max-call-stack.md), [over-sized data]({{rootUrl}}/safety/max-string-size.md), and [runaway scripts]({{rootUrl}}/safety/max-operations.md) etc.) that may come from untrusted third-party user-land scripts.
* Track script evaluation [progress] and manually terminate a script run.
diff --git a/doc/src/about/non-design.md b/doc/src/about/non-design.md
index 66726803..d5496657 100644
--- a/doc/src/about/non-design.md
+++ b/doc/src/about/non-design.md
@@ -1 +1,33 @@
-# What Rhai Doesn't Do
+What Rhai Doesn't Do
+====================
+
+{{#include ../links.md}}
+
+Rhai's purpose is to provide a dynamic layer over Rust code, in the same spirit of _zero cost abstractions_.
+It doesn't attempt to be a new language. For example:
+
+* No classes. Well, Rust doesn't either. On the other hand...
+
+* No traits... so it is also not Rust. Do your Rusty stuff in Rust.
+
+* No structures/records - define your types in Rust instead; Rhai can seamlessly work with _any Rust type_.
+ There is, however, a built-in [object map] type which is adequate for most uses.
+
+* No first-class functions - Code your functions in Rust instead, and register them with Rhai.
+
+* No garbage collection - this should be expected, so...
+
+* No closures - do your closure magic in Rust instead; [turn a Rhai scripted function into a Rust closure]({{rootUrl}}/engine/call-fn.md).
+
+* No byte-codes/JIT - Rhai has an AST-walking interpreter which will not win any speed races. The purpose of Rhai is not
+ to be extremely _fast_, but to make it as easy as possible to integrate with native Rust programs.
+
+Due to this intended usage, Rhai deliberately keeps the language simple and small by omitting advanced language features
+such as classes, inheritance, first-class functions, closures, concurrency, byte-codes, JIT etc.
+
+Avoid the temptation to write full-fledge program logic entirely in Rhai - that use case is best fulfilled by
+more complete languages such as JS or Lua.
+
+Therefore, in actual practice, it is usually best to expose a Rust API into Rhai for scripts to call.
+All your core functionalities should be in Rust.
+This is similar to some dynamic languages where most of the core functionalities reside in a C/C++ standard library.
diff --git a/doc/src/about/non_design.md b/doc/src/about/non_design.md
deleted file mode 100644
index cd1e073c..00000000
--- a/doc/src/about/non_design.md
+++ /dev/null
@@ -1,33 +0,0 @@
-What Rhai Doesn't Do
-====================
-
-{{#include ../links.md}}
-
-Rhai's purpose is to provide a dynamic layer over Rust code, in the same spirit of _zero cost abstractions_.
-It doesn't attempt to be a new language. For example:
-
-* No classes. Well, Rust doesn't either. On the other hand...
-
-* No traits... so it is also not Rust. Do your Rusty stuff in Rust.
-
-* No structures/records - define your types in Rust instead; Rhai can seamlessly work with _any Rust type_.
- There is, however, a built-in [object map] type which is adequate for most uses.
-
-* No first-class functions - Code your functions in Rust instead, and register them with Rhai.
-
-* No garbage collection - this should be expected, so...
-
-* No closures - do your closure magic in Rust instead; [turn a Rhai scripted function into a Rust closure](/engine/call-fn.md).
-
-* No byte-codes/JIT - Rhai has an AST-walking interpreter which will not win any speed races. The purpose of Rhai is not
- to be extremely _fast_, but to make it as easy as possible to integrate with native Rust programs.
-
-Due to this intended usage, Rhai deliberately keeps the language simple and small by omitting advanced language features
-such as classes, inheritance, first-class functions, closures, concurrency, byte-codes, JIT etc.
-
-Avoid the temptation to write full-fledge program logic entirely in Rhai - that use case is best fulfilled by
-more complete languages such as JS or Lua.
-
-Therefore, in actual practice, it is usually best to expose a Rust API into Rhai for scripts to call.
-All your core functionalities should be in Rust.
-This is similar to some dynamic languages where most of the core functionalities reside in a C/C++ standard library.
diff --git a/doc/src/context.json b/doc/src/context.json
new file mode 100644
index 00000000..f898a0c5
--- /dev/null
+++ b/doc/src/context.json
@@ -0,0 +1,4 @@
+{
+ "rootUrl": "",
+ "rootUrlX": "/rhai"
+}
\ No newline at end of file
diff --git a/doc/src/language/arrays.md b/doc/src/language/arrays.md
index 984eea16..5730d862 100644
--- a/doc/src/language/arrays.md
+++ b/doc/src/language/arrays.md
@@ -22,7 +22,7 @@ The maximum allowed size of an array can be controlled via `Engine::set_max_arra
Built-in Functions
-----------------
-The following methods (mostly defined in the [`BasicArrayPackage`](/rust/packages.md) but excluded if using a [raw `Engine`]) operate on arrays:
+The following methods (mostly defined in the [`BasicArrayPackage`]({{rootUrl}}/rust/packages.md) but excluded if using a [raw `Engine`]) operate on arrays:
| Function | Parameter(s) | Description |
| ------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
diff --git a/doc/src/language/eval.md b/doc/src/language/eval.md
index 0d64ce1b..f79810e5 100644
--- a/doc/src/language/eval.md
+++ b/doc/src/language/eval.md
@@ -82,7 +82,7 @@ engine.register_result_fn("eval", alt_eval);
`EvalPackage`
-------------
-There is even a package named [`EvalPackage`](/rust/packages.md) which implements the disabling override:
+There is even a package named [`EvalPackage`]({{rootUrl}}/rust/packages.md) which implements the disabling override:
```rust
use rhai::Engine;
diff --git a/doc/src/language/modules/resolvers.md b/doc/src/language/modules/resolvers.md
index 1125cab8..3377cb56 100644
--- a/doc/src/language/modules/resolvers.md
+++ b/doc/src/language/modules/resolvers.md
@@ -5,7 +5,7 @@ Module Resolvers
When encountering an [`import`] statement, Rhai attempts to _resolve_ the module based on the path string.
-_Module Resolvers_ are service types that implement the [`ModuleResolver`](/rust/traits.md) trait.
+_Module Resolvers_ are service types that implement the [`ModuleResolver`]({{rootUrl}}/rust/traits.md) trait.
There are a number of standard resolvers built into Rhai, the default being the `FileModuleResolver`
which simply loads a script file based on the path (with `.rhai` extension attached) and execute it to form a module.
diff --git a/doc/src/language/num-fn.md b/doc/src/language/num-fn.md
index 8c729f10..c6df7900 100644
--- a/doc/src/language/num-fn.md
+++ b/doc/src/language/num-fn.md
@@ -6,7 +6,7 @@ Numeric Functions
Integer Functions
----------------
-The following standard functions (defined in the [`BasicMathPackage`](/rust/packages.md) but excluded if using a [raw `Engine`])
+The following standard functions (defined in the [`BasicMathPackage`]({{rootUrl}}/rust/packages.md) but excluded if using a [raw `Engine`])
operate on `i8`, `i16`, `i32`, `i64`, `f32` and `f64` only:
| Function | Description |
@@ -17,7 +17,7 @@ operate on `i8`, `i16`, `i32`, `i64`, `f32` and `f64` only:
Floating-Point Functions
-----------------------
-The following standard functions (defined in the [`BasicMathPackage`](/rust/packages.md) but excluded if using a [raw `Engine`])
+The following standard functions (defined in the [`BasicMathPackage`]({{rootUrl}}/rust/packages.md) but excluded if using a [raw `Engine`])
operate on `f64` only:
| Category | Functions |
diff --git a/doc/src/language/object-maps.md b/doc/src/language/object-maps.md
index 4ef3c05a..16d6b6f0 100644
--- a/doc/src/language/object-maps.md
+++ b/doc/src/language/object-maps.md
@@ -39,7 +39,7 @@ The index notation allows setting/getting properties of arbitrary names (even th
Built-in Functions
-----------------
-The following methods (defined in the [`BasicMapPackage`](/rust/packages.md) but excluded if using a [raw `Engine`])
+The following methods (defined in the [`BasicMapPackage`]({{rootUrl}}/rust/packages.md) but excluded if using a [raw `Engine`])
operate on object maps:
| Function | Parameter(s) | Description |
diff --git a/doc/src/language/string-fn.md b/doc/src/language/string-fn.md
index 66f5500e..8504e2e3 100644
--- a/doc/src/language/string-fn.md
+++ b/doc/src/language/string-fn.md
@@ -3,7 +3,7 @@ Built-in String Functions
{{#include ../links.md}}
-The following standard methods (mostly defined in the [`MoreStringPackage`](/rust/packages.md) but excluded if
+The following standard methods (mostly defined in the [`MoreStringPackage`]({{rootUrl}}/rust/packages.md) but excluded if
using a [raw `Engine`]) operate on [strings]:
| Function | Parameter(s) | Description |
diff --git a/doc/src/language/strings-chars.md b/doc/src/language/strings-chars.md
index db56e7f7..f7019048 100644
--- a/doc/src/language/strings-chars.md
+++ b/doc/src/language/strings-chars.md
@@ -6,7 +6,7 @@ Strings and Characters
String in Rhai contain any text sequence of valid Unicode characters.
Internally strings are stored in UTF-8 encoding.
-Strings can be built up from other strings and types via the `+` operator (provided by the [`MoreStringPackage`](/rust/packages.md)
+Strings can be built up from other strings and types via the `+` operator (provided by the [`MoreStringPackage`]({{rootUrl}}/rust/packages.md)
but excluded if using a [raw `Engine`]). This is particularly useful when printing output.
[`type_of()`] a string returns `"string"`.
diff --git a/doc/src/language/timestamps.md b/doc/src/language/timestamps.md
index ad799deb..3d02797e 100644
--- a/doc/src/language/timestamps.md
+++ b/doc/src/language/timestamps.md
@@ -3,7 +3,7 @@
{{#include ../links.md}}
-Timestamps are provided by the [`BasicTimePackage`](/rust/packages.md) (excluded if using a [raw `Engine`])
+Timestamps are provided by the [`BasicTimePackage`]({{rootUrl}}/rust/packages.md) (excluded if using a [raw `Engine`])
via the `timestamp` function.
Timestamps are not available under [`no_std`].
@@ -16,7 +16,7 @@ The Rust type of a timestamp is `std::time::Instant` ([`instant::Instant`](https
Built-in Functions
-----------------
-The following methods (defined in the [`BasicTimePackage`](/rust/packages.md) but excluded if using a [raw `Engine`]) operate on timestamps:
+The following methods (defined in the [`BasicTimePackage`]({{rootUrl}}/rust/packages.md) but excluded if using a [raw `Engine`]) operate on timestamps:
| Function | Parameter(s) | Description |
| ----------------------------- | ---------------------------------- | -------------------------------------------------------- |
diff --git a/doc/src/language/values-and-types.md b/doc/src/language/values-and-types.md
index c4b32533..21bb2474 100644
--- a/doc/src/language/values-and-types.md
+++ b/doc/src/language/values-and-types.md
@@ -5,20 +5,20 @@ Values and Types
The following primitive types are supported natively:
-| Category | Equivalent Rust types | [`type_of()`] | `to_string()` |
-| ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | --------------------- | --------------------- |
-| **Integer number** | `u8`, `i8`, `u16`, `i16`,
`u32`, `i32` (default for [`only_i32`]),
`u64`, `i64` _(default)_ | `"i32"`, `"u64"` etc. | `"42"`, `"123"` etc. |
-| **Floating-point number** (disabled with [`no_float`]) | `f32`, `f64` _(default)_ | `"f32"` or `"f64"` | `"123.4567"` etc. |
-| **Boolean value** | `bool` | `"bool"` | `"true"` or `"false"` |
-| **Unicode character** | `char` | `"char"` | `"A"`, `"x"` etc. |
-| **Immutable Unicode string** | `rhai::ImmutableString` (implemented as `Rc` or `Arc`) | `"string"` | `"hello"` etc. |
-| **Array** (disabled with [`no_index`]) | `rhai::Array` | `"array"` | `"[ ?, ?, ? ]"` |
-| **Object map** (disabled with [`no_object`]) | `rhai::Map` | `"map"` | `#{ "a": 1, "b": 2 }` |
-| **Timestamp** (implemented in the [`BasicTimePackage`](/rust/packages.md)) | `std::time::Instant` | `"timestamp"` | _not supported_ |
-| **Dynamic value** (i.e. can be anything) | `rhai::Dynamic` | _the actual type_ | _actual value_ |
-| **System integer** (current configuration) | `rhai::INT` (`i32` or `i64`) | `"i32"` or `"i64"` | `"42"`, `"123"` etc. |
-| **System floating-point** (current configuration, disabled with [`no_float`]) | `rhai::FLOAT` (`f32` or `f64`) | `"f32"` or `"f64"` | `"123.456"` etc. |
-| **Nothing/void/nil/null** (or whatever it is called) | `()` | `"()"` | `""` _(empty string)_ |
+| Category | Equivalent Rust types | [`type_of()`] | `to_string()` |
+| ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | --------------------- | --------------------- |
+| **Integer number** | `u8`, `i8`, `u16`, `i16`,
`u32`, `i32` (default for [`only_i32`]),
`u64`, `i64` _(default)_ | `"i32"`, `"u64"` etc. | `"42"`, `"123"` etc. |
+| **Floating-point number** (disabled with [`no_float`]) | `f32`, `f64` _(default)_ | `"f32"` or `"f64"` | `"123.4567"` etc. |
+| **Boolean value** | `bool` | `"bool"` | `"true"` or `"false"` |
+| **Unicode character** | `char` | `"char"` | `"A"`, `"x"` etc. |
+| **Immutable Unicode string** | `rhai::ImmutableString` (implemented as `Rc` or `Arc`) | `"string"` | `"hello"` etc. |
+| **Array** (disabled with [`no_index`]) | `rhai::Array` | `"array"` | `"[ ?, ?, ? ]"` |
+| **Object map** (disabled with [`no_object`]) | `rhai::Map` | `"map"` | `#{ "a": 1, "b": 2 }` |
+| **Timestamp** (implemented in the [`BasicTimePackage`]({{rootUrl}}/rust/packages.md)) | `std::time::Instant` | `"timestamp"` | _not supported_ |
+| **Dynamic value** (i.e. can be anything) | `rhai::Dynamic` | _the actual type_ | _actual value_ |
+| **System integer** (current configuration) | `rhai::INT` (`i32` or `i64`) | `"i32"` or `"i64"` | `"42"`, `"123"` etc. |
+| **System floating-point** (current configuration, disabled with [`no_float`]) | `rhai::FLOAT` (`f32` or `f64`) | `"f32"` or `"f64"` | `"123.456"` etc. |
+| **Nothing/void/nil/null** (or whatever it is called) | `()` | `"()"` | `""` _(empty string)_ |
All types are treated strictly separate by Rhai, meaning that `i32` and `i64` and `u32` are completely different -
they even cannot be added together. This is very similar to Rust.
diff --git a/doc/src/links.md b/doc/src/links.md
index 0f0715c7..a6bb5f68 100644
--- a/doc/src/links.md
+++ b/doc/src/links.md
@@ -1,87 +1,86 @@
-[features]: /start/features.md
-[`unchecked`]: /start/features.md
-[`sync`]: /start/features.md
-[`no_optimize`]: /start/features.md
-[`no_float`]: /start/features.md
-[`only_i32`]: /start/features.md
-[`only_i64`]: /start/features.md
-[`no_index`]: /start/features.md
-[`no_object`]: /start/features.md
-[`no_function`]: /start/features.md
-[`no_module`]: /start/features.md
-[`no_std`]: /start/features.md
+[features]: {{rootUrl}}/start/features.md
+[`unchecked`]: {{rootUrl}}/start/features.md
+[`sync`]: {{rootUrl}}/start/features.md
+[`no_optimize`]: {{rootUrl}}/start/features.md
+[`no_float`]: {{rootUrl}}/start/features.md
+[`only_i32`]: {{rootUrl}}/start/features.md
+[`only_i64`]: {{rootUrl}}/start/features.md
+[`no_index`]: {{rootUrl}}/start/features.md
+[`no_object`]: {{rootUrl}}/start/features.md
+[`no_function`]: {{rootUrl}}/start/features.md
+[`no_module`]: {{rootUrl}}/start/features.md
+[`no_std`]: {{rootUrl}}/start/features.md
-[`no-std`]: /start/features.md
+[`no-std`]: {{rootUrl}}/start/features.md
-[minimal builds]: /start/builds/minimal.md
-[WASM]: /start/builds/wasm.md
+[minimal builds]: {{rootUrl}}/start/builds/minimal.md
+[WASM]: {{rootUrl}}/start/builds/wasm.md
-[`Engine`]: /engine/hello-world.md
-[`private`]: /engine/call_fn.md
-[`Func`]: /engine/func.md
-[`eval_expression`]: /engine/expressions.md
-[`eval_expression_with_scope`]: /engine/expressions.md
-[raw `Engine`]: /engine/raw.md
-[built-in operators]: /engine/raw.md#built-in-operators
-[package]: /rust/packages.md
-[packages]: /rust/packages.md
-[`Scope`]: /rust/scope.md
+[`Engine`]: {{rootUrl}}/engine/hello-world.md
+[`private`]: {{rootUrl}}/engine/call_fn.md
+[`Func`]: {{rootUrl}}/engine/func.md
+[`eval_expression`]: {{rootUrl}}/engine/expressions.md
+[`eval_expression_with_scope`]: {{rootUrl}}/engine/expressions.md
+[raw `Engine`]: {{rootUrl}}/engine/raw.md
+[built-in operators]: {{rootUrl}}/engine/raw.md#built-in-operators
+[package]: {{rootUrl}}/rust/packages.md
+[packages]: {{rootUrl}}/rust/packages.md
+[`Scope`]: {{rootUrl}}/rust/scope.md
-[`type_of()`]: /language/type_of.md
-[`to_string()`]: /language/values-and-types.md
-[`()`]: /language/values-and-types.md
-[standard types]: /language/values-and-types.md
-[`Dynamic`]: /language/dynamic.md
-[`to_int`]: /language/convert.md
-[`to_float`]: /language/convert.md
+[`type_of()`]: {{rootUrl}}/language/type_of.md
+[`to_string()`]: {{rootUrl}}/language/values-and-types.md
+[`()`]: {{rootUrl}}/language/values-and-types.md
+[standard types]: {{rootUrl}}/language/values-and-types.md
+[`Dynamic`]: {{rootUrl}}/language/dynamic.md
+[`to_int`]: {{rootUrl}}/language/convert.md
+[`to_float`]: {{rootUrl}}/language/convert.md
-[custom type]: /language/custom.md
-[custom types]: /language/custom.md
+[custom type]: {{rootUrl}}/language/custom.md
+[custom types]: {{rootUrl}}/language/custom.md
-[`print`]: /language/print-debug.md
-[`debug`]: /language/print-debug.md
+[`print`]: {{rootUrl}}/language/print-debug.md
+[`debug`]: {{rootUrl}}/language/print-debug.md
-[variable]: /language/variables.md
-[variables]: /language/variables.md
+[variable]: {{rootUrl}}/language/variables.md
+[variables]: {{rootUrl}}/language/variables.md
-[string]: /language/strings-chars.md
-[strings]: /language/strings-chars.md
-[char]: /language/strings-chars.md
+[string]: {{rootUrl}}/language/strings-chars.md
+[strings]: {{rootUrl}}/language/strings-chars.md
+[char]: {{rootUrl}}/language/strings-chars.md
-[array]: /language/arrays.md
-[arrays]: /language/arrays.md
-[`Array`]: /language/arrays.md
+[array]: {{rootUrl}}/language/arrays.md
+[arrays]: {{rootUrl}}/language/arrays.md
+[`Array`]: {{rootUrl}}/language/arrays.md
-[`Map`]: /language/object-maps.md
-[object map]: /language/object-maps.md
-[object maps]: /language/object-maps.md
+[`Map`]: {{rootUrl}}/language/object-maps.md
+[object map]: {{rootUrl}}/language/object-maps.md
+[object maps]: {{rootUrl}}/language/object-maps.md
-[`timestamp`]: /language/timestamps.md
-[timestamp]: /language/timestamps.md
-[timestamps]: /language/timestamps.md
+[`timestamp`]: {{rootUrl}}/language/timestamps.md
+[timestamp]: {{rootUrl}}/language/timestamps.md
+[timestamps]: {{rootUrl}}/language/timestamps.md
-[function]: /language/functions.md
-[functions]: /language/functions.md
+[function]: {{rootUrl}}/language/functions.md
+[functions]: {{rootUrl}}/language/functions.md
-[`Module`]: /language/modules.md
-[module]: /language/modules.md
-[modules]: /language/modules.md
-[`export`]: /language/modules/export.md
-[`import`]: /language/modules/import.md
+[`Module`]: {{rootUrl}}/language/modules.md
+[module]: {{rootUrl}}/language/modules.md
+[modules]: {{rootUrl}}/language/modules.md
+[`export`]: {{rootUrl}}/language/modules/export.md
+[`import`]: {{rootUrl}}/language/modules/import.md
-[`eval`]: /language/eval.md
+[`eval`]: {{rootUrl}}/language/eval.md
-[maximum statement depth]: /safety/max-stmt-depth.md
-[maximum call stack depth]: /safety/max-call-stack.md
-[maximum number of operations]: /safety/max-operations.md
-[maximum number of modules]: /safety/max-modules.md
-[maximum length of strings]: /safety/max-string-size.md
-[maximum size of arrays]: /safety/max-array-size.md
-[maximum size of object maps]: /safety/max-map-size.md
+[maximum statement depth]: {{rootUrl}}/safety/max-stmt-depth.md
+[maximum call stack depth]: {{rootUrl}}/safety/max-call-stack.md
+[maximum number of operations]: {{rootUrl}}/safety/max-operations.md
+[maximum number of modules]: {{rootUrl}}/safety/max-modules.md
+[maximum length of strings]: {{rootUrl}}/safety/max-string-size.md
+[maximum size of arrays]: {{rootUrl}}/safety/max-array-size.md
+[maximum size of object maps]: {{rootUrl}}/safety/max-map-size.md
[progress]:/safety/progress.md
-[script optimization]: /engine/optimize.md
-[`OptimizationLevel::Full`]: /engine/optimize/optimize-levels.md
-[`OptimizationLevel::Simple`]: /engine/optimize/optimize-levels.md
-[`OptimizationLevel::None`]: /engine/optimize/optimize-levels.md
-
+[script optimization]: {{rootUrl}}/engine/optimize.md
+[`OptimizationLevel::Full`]: {{rootUrl}}/engine/optimize/optimize-levels.md
+[`OptimizationLevel::Simple`]: {{rootUrl}}/engine/optimize/optimize-levels.md
+[`OptimizationLevel::None`]: {{rootUrl}}/engine/optimize/optimize-levels.md
diff --git a/doc/src/rust/functions.md b/doc/src/rust/functions.md
index b543896c..de60646f 100644
--- a/doc/src/rust/functions.md
+++ b/doc/src/rust/functions.md
@@ -7,7 +7,7 @@ Rhai's scripting engine is very lightweight. It gets most of its abilities from
To call these functions, they need to be _registered_ with the [`Engine`] using `Engine::register_fn`
(in the `RegisterFn` trait) and `Engine::register_result_fn` (in the `RegisterResultFn` trait,
-see [fallible functions](/rust/fallible.md)).
+see [fallible functions]({{rootUrl}}/rust/fallible.md)).
```rust
use rhai::{Dynamic, Engine, EvalAltResult, ImmutableString};
diff --git a/doc/src/rust/operators.md b/doc/src/rust/operators.md
index 6a48ed84..b91b1cdc 100644
--- a/doc/src/rust/operators.md
+++ b/doc/src/rust/operators.md
@@ -14,7 +14,7 @@ let x = +(a, b); // <- the above is equivalent to this function call
```
Similarly, comparison operators including `==`, `!=` etc. are all implemented as functions,
-with the stark exception of `&&` and `||`. Because they [_short-circuit_](/language/logic.md#boolean-operators),
+with the stark exception of `&&` and `||`. Because they [_short-circuit_]({{rootUrl}}/language/logic.md#boolean-operators),
`&&` and `||` are handled specially and _not_ via a function; as a result, overriding them has no effect at all.
Operator functions cannot be defined as a script function (because operators syntax are not valid function names).
diff --git a/doc/src/start/builds/wasm.md b/doc/src/start/builds/wasm.md
index c0e7d96b..ca2b0dbb 100644
--- a/doc/src/start/builds/wasm.md
+++ b/doc/src/start/builds/wasm.md
@@ -4,8 +4,11 @@ Building to WebAssembly (WASM)
{{#include ../../links.md}}
It is possible to use Rhai when compiling to WebAssembly (WASM). This yields a scripting engine (and language)
-that can be run in a standard web browser. Why you would want to is another matter... as there is already
-a nice, fast, complete scripting language for the the common WASM environment (i.e. a browser) - and it is called JavaScript.
+that can be run in a standard web browser.
+
+Why you would want to is another matter... as there is already a nice, fast, complete scripting language
+for the the common WASM environment (i.e. a browser) - and it is called JavaScript.
+
But anyhow, do it because you _can_!
When building for WASM, certain features will not be available, such as the script file API's and loading modules