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 bycreateEngine(); 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.
Words are not keywords
Section titled “Words are not keywords”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 // 105Function-like names need the parenthesis
Section titled “Function-like names need the parenthesis”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 // 50A 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 mid-line #word is a category tag
Section titled “A mid-line #word is a category tag”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 listtitle is left alone. - A
#followed by a space is a heading or comment as before:5 # a note. - An all-hex run like
#c0ffeeis a colour, and a tag name must start with a letter, so#12ais 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 needs a quoted name
Section titled “column needs a quoted name”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 = 5column * 2 // 10through 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 = 5total of section + 1 // 6with, for and step after a line reference
Section titled “with, for and step after a line reference”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 // 2x = 5 // 5x * step // 10line 3 with 10 // 20line 3 with x = 1 // 2line 3 for x from 1 to 3 step 1 // [2, 4, 6]Labels are preserved
Section titled “Labels are preserved”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 // 8Rent $1200 // $1,200.00When a line is not an expression
Section titled “When a line is not an expression”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.