Skip to content

This site describes solve-engine as it is on main: 2.43.0, which npm does not have yet. npm installs 2.40.0, so a page may show an answer that version does not give yet.

Trigger words

Packages: MATHPHRASES_PACKAGE, MAPREDUCE_PACKAGE, FINANCE_PACKAGE, TAGS_PACKAGE, LINES_PACKAGE, TABLES_PACKAGE, WHATIF_PACKAGE. Registered by createEngine(); for a slimmer engine, register them explicitly (see choosing packages).

The most common worry about a calculator that reads prose is that it will start mangling the prose. This page explains why that mostly does not happen.

The engine needs total, average, tax, sum, line and many other ordinary words. If each were claimed as a keyword, a note containing “the total was disappointing” would start behaving strangely, and defining a variable named total would become impossible.

So they are not keywords. They are recognised only as part of a longer phrase, and only where that phrase forms a complete expression. average of 1, 2, 3 is recognised. A bare average is a name.

The same holds for the bill-split words: split, ways and people are read as the split grammar only inside the full split <amount> between <N> or <amount> split <N> ways shape, so :split = 5 and a variable named split keep working.

That is why this works:

:total = 100
:total + 5 // 105

map, reduce, sum and prod are treated as operations only when immediately followed by an opening parenthesis. Otherwise they are ordinary names.

:sum = 42
:sum + 8 // 50

A leading search: starts a knowledge query

Section titled “A leading search: starts a knowledge query”

Where the knowledge package is registered, search, ask and google begin a lookup only with an immediate colon: search: nearest star is a query, while search 5 reads the variable search and :search = 5 still defines it. The colon, like the parenthesis above, is what separates the special reading from the ordinary word. The package is opt-in, so a default engine treats all three as plain names.

A # followed by a letter, in the middle of a line, is read as a category tag: 40 #grocery tags that line and still calculates to 40. The boundaries keep it out of ordinary prose and out of the other things # already means:

  • A # at the very start of a line is a heading, not a tag, so a note’s #grocery list title is left alone.
  • A # followed by a space is a heading or comment as before: 5 # a note.
  • An all-hex run like #c0ffee is a colour, and a tag name must start with a letter, so #12a is a colour too, not a tag.

The words total, sum, count and average in total of #grocery are, as above, recognised only as part of that whole phrase, so a variable named total and the prose “the total of the day” keep working.

column begins a table lookup only when a quoted column name follows it, as in column "cost" for "food". Anywhere else it is an ordinary name, so a variable called column still works:

:column = 5
column * 2 // 10

through is the same: it starts the banded rates total only in the whole phrase through bands.

section and tag need the rest of their phrase

Section titled “section and tag need the rest of their phrase”

total of section "Travel" reads the lines under a heading (see sections) only when a quoted name follows section, and total by tag needs all three of its words. Neither section nor tag is a keyword on its own, so a variable of either name keeps working:

:section = 5
total of section + 1 // 6

A what-if or a sweep opens with a line reference, and its words keep their ordinary meaning everywhere else. line 3 with starts a what-if only when a name and an = follow it; line 3 with 10 is still line three plus ten, since with is a spelling of +. step is read as a sweep’s step only after line N for <name> from <start> to <end>, so a variable named step keeps working, even inside a sweep’s own range:

step = 2 // 2
x = 5 // 5
x * step // 10
line 3 with 10 // 20
line 3 with x = 1 // 2
line 3 for x from 1 to 3 step 1 // [2, 4, 6]

A line starting with a label keeps the label and evaluates the rest. A label is written before a colon, or without one when an amount of money or a quantity ends the line (see labels).

total: 5 + 3 // 8
Rent $1200 // $1,200.00

A line the engine cannot make sense of is left alone. It does not guess and it does not partially evaluate. That is the intended behaviour for a document that is mostly prose with occasional arithmetic in it.

There is one shape it reads: a line of words that ends in one amount of money or one quantity is a label and that amount, as the same line with a colon is. A number anywhere else in a sentence, a bare number at the end of one, and a sentence whose last word before the amount only leads into it (back in 5 min) are left alone; labels lists what decides it.