Custom Javascript

Between forks, nested forks, and references, BML offers deep chance operation capabilities out of the box. For more advanced use-cases, BML allows you to run custom Javascript throughout your document.

ℹ️ Note

If you aren’t a comfortable Javascript programmer and you don’t immediately need these features, consider skipping this page.

Eval branches

Javascript code is defined in a fork branch, marked with square brackets. If you want to unconditionally run the code, simply define a single-branch fork:

{[
    insert('foo');
]}

Eval blocks are evaluated as Javascript through the Function constructor. They pass data back to BML with two provided functions - insert and bind.

Insertion

insert simply takes a string and inserts it in the branch’s output.

{[
    insert('foo');
]}
output:

Note that insert writes to the branch, not the document. This distinction is relevant when dealing with multiple branches and silent forks.

{[insert('foo')], (bar)}
output:
{#silent: [insert('foo')], (bar)}
Insert writes to the branch, not immediately to the document.
{@silent}
output:

Binding

You can mark variables to be saved between eval blocks with the bind function. It takes an object where all its keys are valid javascript identifiers, and injects its members into every following eval block.

{[
    bind({
        someValue: 'bar',
        myFunc: (value) => {
            insert(value);
        }
    });
]}
{[myFunc('foo')]}
{[myFunc(someValue)]}
output:

Once bound, you cannot bind the same name again, but you can change their values by simply assigning to them.

{[
    bind({
        someValue: 'bar',
        myFunc: (value) => {
            insert(value);
        }
    });
]}
{[
    myFunc(someValue);
    // This change will be saved in the execution context
    someValue = 'biz';
]}
{[myFunc(someValue)]}
output:

The Eval API

Some additional functions are provided to the executation context through the reserved bml object. These are currently limited to methods which generate random numbers using BML’s random number generator, which is necessary to ensure reproducibility when BML is run with a fixed seed.

bml.randomFloat(min, max)

Return a random float within the given bounds

{[
    insert(bml.randomFloat(1, 2));
]}
output:

bml.randomInt(min, max)

Return a random integer greater than or equal to min and less than max.

{[
    insert(bml.randomInt(1, 10));
]}
output: