Utilities
This is the junk drawer of the standard library -- a collection of specialized utility objects that don't belong anywhere else but are genuinely useful when you need them. HTML processing, token manipulation, template rendering, and (yes) maze generation.
HTML
The HTML global handles conversion between HTML and JSON representations, plus escaping for safe attribute insertion.
| Function | Description | Returns |
|---|---|---|
HTML.convertHTMLtoJSON(html, rootTag) |
Convert HTML string to JSON tree | maybe<dynamic> |
HTML.convertJSONtoHTML(json) |
Convert JSON tree back to HTML | string |
HTML.escapeHTMLAttributeValue(value) |
Escape a string for use in HTML attrs | string |
// Escape for safe attribute insertion
string safe = HTML.escapeHTMLAttributeValue("value with quotes & <tags>");
HTML-JSON Conversion
convertHTMLtoJSON parses an HTML fragment into a structured JSON tree. Each element becomes an object with tag, optional attributes, and children. Text nodes become objects with a text field.
procedure example() {
maybe<dynamic> tree = HTML.convertHTMLtoJSON("<div class='box'>Hello</div>", "root");
// {"tag":"root","children":[{"tag":"div","attributes":{"class":"box"},"children":[{"text":"Hello"}]}]}
}
convertJSONtoHTML reverses the process:
procedure reverse_example() {
dynamic json = Dynamic.parse("{\"tag\":\"div\",\"children\":[{\"text\":\"hello\"}]}");
if (json as j) {
string html = HTML.convertJSONtoHTML(j); // "<div>hello</div>"
}
}
Token
The Token global provides array manipulation for token-based operations. I built this for implementing search indices and set intersections -- situations where you need to work with sorted, deduplicated arrays efficiently.
| Function | Description | Returns |
|---|---|---|
Token.sortAndUniqueAsIntTokens(list) |
Deduplicate and sort int list | int[] |
Token.normalizeSortAndUniqueAsStringTokens(list) |
Normalize, sort, deduplicate strings | string[] |
Token.intersect(a, b) (int arrays) |
Compute intersection of int arrays | int[] |
Token.intersect(a, b) (string arrays) |
Compute intersection of string arrays | string[] |
procedure example() {
list<int> values;
// ... populate values ...
int[] unique = Token.sortAndUniqueAsIntTokens(values);
int[] set_a = [1, 2, 3, 4];
int[] set_b = [3, 4, 5, 6];
int[] common = Token.intersect(set_a, set_b); // [3, 4]
}
These are useful for building full-text search indices where documents are represented as sorted arrays of term IDs. The intersection operation gives you the documents that match all search terms.
Template
The Template global renders template values with dynamic data inputs. Templates use {{field}} syntax for variable substitution.
| Function | Description | Returns |
|---|---|---|
Template.html(tmpl, data) |
Render template with HTML escaping | maybe<string> |
Template.raw(tmpl, data) |
Render template without escaping | maybe<string> |
template greeting = "Hello, {{name}}! You have {{count}} messages.";
procedure render_greeting() {
if (Dynamic.parse("{\"name\":\"Alice\",\"count\":5}") as data) {
maybe<string> result = Template.html(greeting, data);
// "Hello, Alice! You have 5 messages."
}
}
The html variant escapes special HTML characters in substituted values (so you don't get XSS'd), while raw inserts values as-is. Use html unless you know what you're doing.
Templates
The Templates global provides pre-built email templates for common platform operations. These are opinionated HTML emails that look reasonable without you having to write HTML email markup (which, if you've ever done it, you know is its own special kind of pain).
| Function | Description | Returns |
|---|---|---|
Templates.accountRecoveryDefaultEmail(pwd, reset, instant) |
Account recovery email HTML | string |
Templates.multilineEmailWithButton(...) |
Formatted email with button | string |
accountRecoveryDefaultEmail
Generates a complete HTML email for account recovery.
| Parameter | Type | Description |
|---|---|---|
| tempPassword | string |
Temporary password |
| resetUrl | string |
URL for password reset page |
| instantUrl | string |
URL for instant login |
string email = Templates.accountRecoveryDefaultEmail(
"temp_pass_123",
"https://example.com/reset?token=abc",
"https://example.com/instant?token=xyz"
);
multilineEmailWithButton
Generates a formatted email with a title, body text, and call-to-action button.
| Parameter | Type | Description |
|---|---|---|
| title | string |
Email title/subject |
| first_line | string |
First line of body text |
| second_line | string |
Second line of body text |
| body | string |
Main body content |
| button_url | string |
URL for the CTA button |
| button | string |
Button label text |
| final_line | string |
Closing line of text |
Mazes
The Mazes global generates procedural mazes using cellular automaton rules. I added this because I was building a game and needed it, and figured someone else might too.
| Function | Description | Returns |
|---|---|---|
Mazes.basic_v0(seed, w, h, generations, min, max, margin) |
Generate a maze | grid<int, bool> |
| Parameter | Type | Description |
|---|---|---|
| seed | long |
Random seed for reproducibility |
| w | int |
Width of the maze |
| h | int |
Height of the maze |
| generations | int |
Number of cellular automaton passes |
| min | int |
Min alive neighbors to survive |
| max | int |
Max alive neighbors to survive |
| margin | int |
Border margin size |
grid<int, bool> maze = Mazes.basic_v0(42L, 20, 20, 5, 2, 4, 1);
The generated grid contains true for open cells and false for walls. Different seeds produce different mazes with the same parameters. The min/max neighbor rules control how dense and connected the passages are -- play with these until you get something that looks good.
Method Summary
HTML
| Function | Returns |
|---|---|
HTML.convertHTMLtoJSON(html, tag) |
maybe<dynamic> |
HTML.convertJSONtoHTML(json) |
string |
HTML.escapeHTMLAttributeValue(value) |
string |
Token
| Function | Returns |
|---|---|
Token.sortAndUniqueAsIntTokens(list) |
int[] |
Token.normalizeSortAndUniqueAsStringTokens(list) |
string[] |
Token.intersect(a, b) |
int[] or string[] |
Template
| Function | Returns |
|---|---|
Template.html(tmpl, data) |
maybe<string> |
Template.raw(tmpl, data) |
maybe<string> |
Mazes
| Function | Returns |
|---|---|
Mazes.basic_v0(seed, w, h, ...) |
grid<int, bool> |