Formula Reference
The Blaze Formula Language makes it possible to use formulas and calculations as part of your snippets. This enables dynamic and conditional snippet content. The Blaze Formula Language is used in the {formula}, {if} and {repeat} commands.
50% More Would Be: {=count * 1.5} {if: count > 10}That's a lot!{else}Not so many.{endif}
Supported Operators
The Blaze Formula Language supports many operators for manipulating numbers, comparing values, and working with strings and boolean (yes/no) values.
Operator | Description | Example |
---|---|---|
Mathematical Operators | ||
+ | Add two numbers together | 5 + 6 ⇒ 11 |
- | Subtract two numbers | 7 - 2 ⇒ 5 |
* | Multiply two numbers | 5 * 2 ⇒ 10 |
/ | Divide two numbers | 9 / 2 ⇒ 4.5 |
^ | Take a number to a power | 2 ^ 3 ⇒ 8 |
Comparison Operators | ||
== | Whether two values are equal (can convert types) | 2 == 2 ⇒ yes |
=== | Whether two values are strictly equal (will not convert types) | 2 === "2" ⇒ no |
<> | Whether two values are not equal (can convert types) | 2 <> 2 ⇒ no |
>= | Greater than or equals to | 5 >= 2 ⇒ yes |
> | Greater than | 5 > 2 ⇒ yes |
<= | Less than or equals to | 5 <= 2 ⇒ no |
< | Less than | 5 < 2 ⇒ no |
String Operators | ||
& | String concatenation | "abc" & "xyz" & 1 ⇒ "abcxyz1" |
Logical Operators | ||
not | The opposite of a boolean | not no ⇒ yes |
and | Whether two booleans are both true | yes and no ⇒ no |
or | Whether either of two booleans is true | yes or no ⇒ yes |
ternary | Conditional value. Of the form: value1 if condition else value2 | "big" if 100 > 10 else "small" ⇒ "big" |
Supported Functions
Text Blaze supports a variety of functions in formulas.
Function | Description | Example |
---|---|---|
Mathematical Functions | ||
round(x) | Rounds a number to the nearest integer | round(1.7) ⇒ 2 |
floor(x) | Rounds a number down to the nearest integer | floor(1.7) ⇒ 1 |
ceil(x) | Rounds a number up to the nearest integer | ceil(1.2) ⇒ 2 |
sqrt(x) | Gets the square root of a number | sqrt(16) ⇒ 4 |
abs(x) | Gets the absolute value of a number | abs(-3) ⇒ 3 |
log(x) | Gets the base-10 log of a number | log(100) ⇒ 2 |
ln(x) | Gets the natural log of a number | ln(100) ⇒ 4.605 |
remainder(x, y) | Gets the remainder from a division | remainder(12, 5) ⇒ 2 |
max(x, y, ...) | Gets the maximum of two or more values | max(3, 7) ⇒ 7 |
min(x, y, ...) | Gets the minimum of two or more values | min(3, 7) ⇒ 3 |
isodd(x) | Whether a number is odd | isodd(7) ⇒ yes |
iseven(x) | Whether a number is even | iseven(7) ⇒ no |
random() | Gets a random number between 0 and 1 | random() ⇒ 0.370826324 |
base(x, base, padding) | Express numbers in different numeric bases (e.g. hexadecimal) | base(123, 16) ⇒ "7b" |
Trigonometric Functions | ||
sin(x) | Returns the sine of a number of degrees | sin(90) ⇒ 1 |
cos(x) | Returns the cosine of a number of degrees | cos(90) ⇒ 0 |
tan(x) | Returns the tangent of a number of degrees | tan(45) ⇒ 1 |
asin(x) | Returns the arcsine in degrees of a number | asin(1) ⇒ 90 |
acos(x) | Returns the arccosine in degrees of a number | acos(0) ⇒ 90 |
atan(x) | Returns the arctangent in degrees of a number | atan(1) ⇒ 45 |
Error Functions | ||
error(msg) | Raises a Text Blaze error | error("Invalid widget size") |
catch(x, msg) | Evaluates and returns x. If there is an error in x, returns msg. msg may also be an anonymous function taking the error as its first argument | catch(log(-1), "Negative") ⇒ "Negative" |
String Functions | ||
concat(x, y, ...) | Concatenates two or more values as a string | concat("abc", 123) ⇒ "abc123" |
lower(x) | Lowercase a string | lower("Hi") ⇒ "hi" |
upper(x) | Uppercase a string | upper("Hi") ⇒ "HI" |
proper(x) | Capitalizes each word | proper("HI all") ⇒ "Hi All" |
trim(x) | Removes leading and trailing whitespace | trim(" abc ") ⇒ "abc" |
reverse(x) | Reverses a string | reverse("abc") ⇒ "cba" |
replace(x, find, replacement) | Replaces all occurrences of find with replacement | replace("good job", "good", "great") ⇒ "great job" |
len(x) | The length of a string in characters | len("abc") ⇒ 3 |
substring(x, start, length) | Extracts the portion of the string of length from the start character. If start is negative, it is relative to the end of the string. If length is omitted, the rest of the string is returned. | substring("abcdef", 2, 3) ⇒ "bcd" |
comparestrings(a, b) | Returns a negative number if a is lexicographically before b, a positive number if b is before a and 0 if they are equivalent. | comparestrings("at", "dog") ⇒ -1 |
contains(string, value) | Whether one string contains another | contains("Good morning", "morning") ⇒ yes |
startswith(string, value) | Whether one string starts with another | startswith("Good morning", "morning") ⇒ no |
endswith(string, value) | Whether one string ends with another | endswith("Good morning", "morning") ⇒ yes |
search(string, value) | The position of one string in another | search("Good morning", "morning") ⇒ 6 |
Regular Expression Functions | ||
testregex(x, regex, flags) | Tests whether a Regular Expression matches a string. flags is optional and if set to "i" , the search will be case-insensitive. | testregex("dog", "d..") ⇒ yes |
extractregex(x, regex, flags) | Extracts the portion of a string matching a Regular Expression. If a capture group is set, extracts the capture group. Flags is optional and if set to "i" , the search will be case-insensitive. | extractregex("dog", "d(..)") ⇒ "og" |
splitregex(x, regex, flags) | Splits a string by a regular expression | extractregex("ab5cd3ef", "\d") ⇒ ["ab", "cd", "ef"] |
replaceregex(x, regex, replacement, flags) | Replaces matches of a regular expression in a string. Flags is optional and if set to "g" will replace all matches. | replaceregex("ID: 1234", "\d", "X", "g") ⇒ "ID: XXXX" |
List Functions | ||
count(list) | The number of elements in a list | count([1, 4, 9]) ⇒ 3 |
includes(list, value) | yes if a list contains a specific value | includes([1, 4, 9], 4) ⇒ yes |
location(list, value) | Returns the index or key of the first location of the value | location([1, 4, 9], 4) ⇒ 2 |
merge(list, list2, ...) | Merges two or more lists together | merge([1], [2, 3], [4]) ⇒ [1, 2, 3, 4] |
filter(list, fn(value, index/key)) | Returns a new list comprised of the elements where fn evaluates to yes | filter([1, 4, 9], v -> v > 3) ⇒ [4, 9] |
map(list, fn(value, index/key)) | Returns a new list where each element is replaced with the value of fn | map([1, 4, 9], v -> v > 3) ⇒ [no, yes yes] |
reduce(list, accumulator, fn(accumulator, value, index/key)) | Aggregates the elements of the list | reduce([1, 4, 9], 0, (a, v) -> a + v) ⇒ 14 |
Ordered List Functions | ||
seq(start, end, step) | Creates an ordered list from start to end by step. If step is omitted, it defaults to 1 or -1. | seq(1, 3) ⇒ [1, 2, 3] |
split(str, del) | Creates an ordered list by splitting a string by a deliminator | split("a/b/c", "/") ⇒ ["a", "b", "c"] |
join(list, del) | Creates a string by joining the elements of a list | join([1, 3, 9], "-") ⇒ 1-3-9 |
sort(list, fn(a, b)) | Sorts the elements of the ordered list. fn(a, b) will be called for each pair of elements; if is negative, a will be placed before b; if positive, b will be placed before a; if 0, the elements are equivalent | sort([3, 9, 1], (a, b) -> a - b) ⇒ [1, 3, 9] |
slice(list, start, last) | Extract part of the list from start to last. If last is omitted, returns from start to the end of the list | slice([1, 4, 9, 16], 2, 3) ⇒ [4, 9] |
sum(list) | Sum the elements of a list | sum([1, 4, 10]) ⇒ 15 |
average(list) | The average (mean) of the elements in a list | average([1, 4, 10]) ⇒ 5 |
median(list) | The median of the elements in a list | median([1, 4, 10]) ⇒ 4 |
find(list, fn) | Returns the first element of a list that matches a condition | find([1, 4, 9], x -> x > 3) ⇒ 4 |
Keyed List Functions | ||
keys(list) | The keys in a keyed list as an ordered list | keys(["a"=123, "b"=345]) ⇒ ["a", "b"] |
Miscellaneous Functions | ||
isnumber(x) | Whether a value is a number | isnumber("1.2") ⇒ yes |
isboolean(x) | Whether a value is a boolean | isboolean("no") ⇒ yes |
islist(x) | Whether a value is a list | islist([1,2,3]) ⇒ yes |
iserror(x) | Whether a value is an error | iserror(1 + "a") ⇒ yes |
fromjson(str) | Converts a JSON string into a list | fromjson("{\"a\": [1,2,3]}") ⇒ `["a"=[1, 2, 3]] |
urlencode(x) | Encodes special characters to allow including a string in a url | urlencode("a&b") ⇒ "a%26b" |
urldecode(x) | Decodes a urlencode d string | urlencode("a%26b") ⇒ "a&b" |
base64encode(x) | Base 64 encode a string | base64encode("hello") ⇒ "aGVsbG8=" |
base64decode(x) | Base 64 decode a string | base64decode("aGVsbG8=") ⇒ "hello" |
Escaping Special Characters
Certain characters have special meaning in Text Blaze commands and strings. For instance, the ;
character is used to separate settings in commands. In formula strings, the "
character is used to signal the start and end of the string.
To use these special characters in their normal form you can "escape" them by placing a single backslash (\
) before them.
For example:
{="this is a \" character"}
will print:
this is a " character
The rules for escaping special characters are slightly different within commands and strings. The following table summarizes these rules:
In Commands | In Strings | |
---|---|---|
Common escapes: \n , \r , \t , \\ | Replaced with newline, carriage return, tab, and \ respectively | Replaced with newline, carriage return, tab, and \ respectively | |
Special characters that need to be escaped | { , } , = , ; , and spaces at the start or end of a setting (and within the values of list settings: , ) | " |
Any other occurrences of \X | Backslashes are stripped. E.g. \a\b\c becomes abc | Backslashes remain. E.g. \a\b\c stays as \a\b\c |
Additional common escapes may be added to Text Blaze in the future, so you should be explicit with your backslashes and not accidentally rely on the behaviors in the third row of this table.
Lists
Lists are special data structures in the sense that they contain other pieces of data. There are two types of lists in Text Blaze: ordered lists and keyed lists.
Ordered Lists
Ordered lists (also called arrays), are a sequential set of zero or more values. Their syntax is as follows:
[Value1, Value2, Value3, ...]
Since there is a distinct order to the elements, you can access a specific element by its index
using the syntax list[index]
. The first element in the list has index 1, the second index 2 and so on. For example:
Ordered lists are especially useful when processing multiple items of some type.
Keyed Lists
Keyed lists are a set of key/value mappings. Their syntax is as follows:
["key a" = ValueA, "key b" = ValueB, ...]
There is no ordering to the keys or values in keyed lists, but you can still access individual elements using the syntax list["key"]
or list.key
. For example:
{=["color"="red", "age"=33, "sign"="libra"].color} {=["color"="red", "age"=33, "sign"="libra"].age}
Note that the "." syntax doesn't work when the key has spaces or other special characters in it. In this case you always need to use the
["key"]
approach to reference the value:{=["color"="red", "age"=33, "sign"="libra", "favorite food"="pizza"]["favorite food"]}
Keyed lists are particularly useful when processing data. Keys are case-sensitive.
If the key is not quoted when defining a list, it is a treated as a form variable and the value of the variable is used as the key value. The following example illustrates this:
{=list["abc"]}
List Comprehensions
Text Blaze has powerful methods for manipulating lists: including filter()
, map()
, and reduce()
.
Sometimes though, it can be easier to use a powerful Text Blaze feature called list comprehensions if you need to transform a list. List comprehensions carry our an operation across each element of a list.
Imagine you wanted to square each element of an ordered list. The following example shows how to do that with both the map()
function and a list comprehension:
Map() version: {=map(n, x -> x^2)}
List comprehension version: {=[x^2 for x in n]}
Both work and are almost exactly the same length, but many people find the list comprehension version easier to read.
You can also include an optional if
block in your list comprehensions, items will only included when it evaluates to yes
. Imagine we only wanted to include items who were larger than 20:
Filter() & Map() version: {=map(filter(n, x -> x > 20), x -> x^2)}
List comprehension version: {=[x^2 for x in n if x > 20]}
List comprehensions can also iterate across keyed lists and can create keyed lists. The following shows the examples of the different possible combinations:
Keyed List: {formtext: name=k; default=["a"=10, "b"=12, "c"=100]}
Ordered in and Ordered out: {=[x^2 for x in o]}
Ordered in and Keyed out: {=[index=x^2 for (x, index) in o]}
Keyed in and Ordered out: {=[value^2 for (key, value) in k]}
Keyed in and Keyed out: {=[key=value^2 for (key, value) in k]}
Anonymous Functions
An anonymous function is like a regular function except it does not have a name. The syntax for anonymous functions is:
(arg1, arg2, ...) -> doSomething(arg1, arg2, ...)
The parenthesis around the arguments can be omitted if you have exactly one argument:
arg -> doSomething(arg)
Some built-in functions and commands use anonymous functions. For instance, the sort()
function for lists takes an anonymous function to define the sorting order to use. The following example shows the use of anonymous functions with the sort()
function to sort the same array four different ways:
Numeric Descending Sort: {=sort([9, 4, 10, 1, 12], (a, b) -> b - a)}
Alphabetic Ascending Sort: {=sort([9, 4, 10, 1, 12], (a, b) -> comparestrings(a, b))}
Alphabetic Descending Sort: {=sort([9, 4, 10, 1, 12], (a, b) -> -comparestrings(a, b))}
Using anonymous functions, you can define whatever sorting method you want.
You can also call anonymous functions directly in your formulas. For example:
A common use case for anonymous functions is manipulating lists. The filter()
, map()
and reduce()
built-in functions are three functions for operating across a list that leverage anonymous functions.
Divide everything in the list by 100: {=map(n, v -> v/100)}
Find the mean of a list: {=reduce(n, 0, (acc, v) -> acc + v)/count(n)}
Regular Expressions
A regular expression pattern is composed of simple characters, such as "abc"
, or a combination of simple and special characters, such as "ab*c"
or "Chapter (\d+)\.\d*"
. The last example includes parentheses which can be used to extract specific parts of the regex using the extractregex()
function.
This section is adapted from this MDN Page by Mozilla Contributors and licensed under CC-BY-SA license.
Text Blaze provides the extractregex()
and testregex()
functions to leverage regular expressions.
{if: testregex(number, "^\s*\(\d\d\d\)\s*\d\d\d-\d\d\d\d\s*$")}
Area Code: {=extractregex(number, "\((\d\d\d)\)")}
{else}That is not a valid phone number.{endif}Using simple patterns
Simple patterns are constructed of characters for which you want to find a direct match. For example, the pattern "abc"
matches character combinations in strings only when exactly the characters 'abc' occur together and in that order. Such a match would succeed in the strings "Hi, do you know your abc's?" and "The latest airplane designs evolved from slabcraft." In both cases the match is with the substring 'abc'. There is no match in the string 'Grab crab' because while it contains the substring 'ab c', it does not contain the exact substring 'abc'.
Using special characters
When the search for a match requires something more than a direct match, such as finding one or more b's, or finding white space, the pattern includes special characters. For example, the pattern "ab*c"
matches any character combination in which a single 'a' is followed by zero or more 'b's (*
means 0 or more occurrences of the preceding item) and then immediately followed by 'c'. In the string "cbbabbbbcdebc," the pattern matches the substring 'abbbbc'.
The table at the end of this section provides a complete list and description of the special characters that can be used in regular expressions.
Special characters in regular expressions
Table of special characters that can be used in regular expressions:
Character | Meaning |
---|---|
\ | Matches according to the following rules: A backslash that precedes a non-special character indicates that the next character is special and is not to be interpreted literally. For example, a 'b' without a preceding '' generally matches lowercase 'b's wherever they occur. But a ' \b ' by itself doesn't match any character; it forms the special word boundary character.A backslash that precedes a special character indicates that the next character is not special and should be interpreted literally. For example, the pattern "a*" relies on the special character '\* ' to match 0 or more a's. By contrast, the pattern "a\*" removes the specialness of the '*' to enable matches with strings like 'a*'.To match a \ you need to escape it as \\ . If you are entering your regex as a string directly in your snippet, you will need to double escape it (\\\\ ) as a \\ is replaced by a single \ in Text Blaze quoted strings. |
^ | Matches the beginning of input. For example, "^A" does not match the 'A' in "an A", but does match the 'A' in "An E".The '^' has a different meaning when it appears as the first character in a character set pattern. See complemented character sets for details and an example. |
$ | Matches end of input. For example, "t$" does not match the 't' in "eater", but does match it in "eat". |
* | Matches the preceding expression 0 or more times. Equivalent to {0,} .For example, "bo*" matches 'boooo' in "A ghost booooed" and 'b' in "A bird warbled" but nothing in "A goat grunted". |
+ | Matches the preceding expression 1 or more times. Equivalent to {1,} .For example, "a+" matches the 'a' in "candy" and all the a's in "caaaaaaandy", but nothing in "cndy". |
? | Matches the preceding expression 0 or 1 time. Equivalent to {0,1} .For example, "e?le?" matches the 'el' in "angel" and the 'le' in "angle" and also the 'l' in "oslo".If used immediately after any of the quantifiers * , + , ? , or {} , makes the quantifier non-greedy (matching the fewest possible characters), as opposed to the default, which is greedy (matching as many characters as possible). For example, applying "\d+" to "123abc" matches "123". But applying "\d+?" to that same string matches only the "1". |
. | (The decimal point) matches any single character except the newline character. For example, ".n" matches 'an' and 'on' in "nay, an apple is on the tree", but not 'nay'. |
x|y | Matches 'x', or 'y' (if there is no match for 'x'). For example, "green|red" matches 'green' in "green apple" and 'red' in "red apple." The order of 'x' and 'y' matters. For example "a*|b" matches the empty string in "b", but "b|a*" matches "b" in the same string. |
{n} | Matches exactly n occurrences of the preceding expression. N must be a positive integer. For example, "a{2}" doesn't match the 'a' in "candy," but it does match all of the a's in "caandy," and the first two a's in "caaandy." |
{n,} | Matches at least n occurrences of the preceding expression. N must be a positive integer. For example, "a{2,}" will match "aa", "aaaa" and "aaaaa" but not "a" |
{n,m} | Where n and m are positive integers and n <= m. Matches at least n and at most m occurrences of the preceding expression. When m is omitted, it's treated as ∞. For example, "a{1,3}" matches nothing in "cndy", the 'a' in "candy," the first two a's in "caandy," and the first three a's in "caaaaaaandy". Notice that when matching "caaaaaaandy", the match is "aaa", even though the original string had more a's in it. |
[xyz] | Character set. This pattern type matches any one of the characters in the brackets, including escape sequences. Special characters like the dot(. ) and asterisk (* ) are not special inside a character set, so they don't need to be escaped. You can specify a range of characters by using a hyphen, as the following examples illustrate.The pattern [a-d] , which performs the same match as [abcd], matches the 'b' in "brisket" and the 'c' in "city". The patterns "[a-z.]+" and "[\w.]+" match the entire string "test.i.ng". |
[^xyz] | A negated or complemented character set. That is, it matches anything that is not enclosed in the brackets. You can specify a range of characters by using a hyphen. Everything that works in the normal character set also works here. For example, [^abc] is the same as [^a-c] . They initially match 'r' in "brisket" and 'h' in "chop." |
[\b] | Matches a backspace (U+0008). You need to use square brackets if you want to match a literal backspace character. (Not to be confused with \b .) |
\b | Matches a word boundary. A word boundary matches the position where a word character is not followed or preceded by another word-character. Note that a matched word boundary is not included in the match. In other words, the length of a matched word boundary is zero. (Not to be confused with [\b] .)Examples: "\bm" matches the 'm' in "moon" ;"oo\b" does not match the 'oo' in "moon", because 'oo' is followed by 'n' which is a word character;"oon\b" matches the 'oon' in "moon", because 'oon' is the end of the string, thus not followed by a word character;"\w\b\w" will never match anything, because a word character can never be followed by both a non-word and a word character.Note: The regular expression engine defines a specific set of characters to be "word" characters. Any character not in that set is considered a word break. This set of characters is fairly limited: it consists solely of the Roman alphabet in both upper- and lower-case, decimal digits, and the underscore character. Accented characters, such as "é" or "ü" are, unfortunately, treated as word breaks. |
\B | Matches a non-word boundary. This matches a position where the previous and next character are of the same type: Either both must be words, or both must be non-words. The beginning and end of a string are considered non-words. For example, "\B.." matches 'oo' in "noonday", and "y\B." matches 'ye' in "possibly yesterday." |
\d | Matches a digit character. Equivalent to [0-9] .For example, "\d" or "[0-9]" matches '2' in "B2 is the suite number." |
\D | Matches a non-digit character. Equivalent to [^0-9] .For example, "\D" or "[^0-9]" matches 'B' in "B2 is the suite number." |
\s | Matches a single white space character, including space, tab, form feed, line feed. For example, "\s\w*" matches ' bar' in "foo bar." |
\S | Matches a single character other than white space. For example, "\S*" matches 'foo' in "foo bar." |
\w | Matches any alphanumeric character including the underscore. For example, "\w" matches 'a' in "apple," '5' in "$5.28," and '3' in "3D." |
\W | Matches any non-word character. For example, "\W" matches '%' in "50%." |