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.

Line references

Package: LINES_PACKAGE. Registered by createEngine(); for a slimmer engine, register it explicitly (see choosing packages).

A note is often a column of working where each line builds on the ones above it. Rather than retype a figure, refer to the line it came from, and the reference updates when that line changes.

ExpressionMeaning
prevthe result of the previous line
ansthe same, under the name other calculators use
line 3the result of line three
sum(line 1 : line 4)the total of a span of lines
average(line 1 : line 4)the mean of a span
total abovethe total of every line above (also sum above)
sum, totalon a line of their own, the same as total above
average abovethe same, averaged (also avg above and mean above)
count abovehow many figures are above
min above, max abovethe least and the greatest figure above
median abovethe figure in the middle
line deleteda reference whose line was deleted; answers with an error

prev reads the line immediately above, and line N reads any earlier line by its number:

120
80
prev // 80
line 1 // 120

ans is the previous answer in Numi, Numbr and SpeedCrunch, and reads the line above the way prev does. It is an ordinary name otherwise: a note that defines a variable called ans gets that variable instead.

10
ans * 2 // 20

total above and average above gather every line above them:

10
20
30
total above // 60

sum above is the same total under the spreadsheet’s word for it:

10
20
30
sum above // 60

The same block can be asked other questions: how many figures it holds, the least and the greatest of them, and the one in the middle. Each of these lines is a summary itself, so the next one reads past it to the figures:

10
20
30
count above // 3
max above // 30
median above // 20

A column that carries units answers in the unit written at its top, as a total does, and a column mixing measures is refused rather than compared. A number written in another base (255 in hex) is a figure like any other, added as the number it is, and the total is a plain decimal number (see number bases).

A line that is only sum or total is the same total, the way other calculators read the word under a column. It totals the block above it as total above does, and it can follow a label:

Rent $1200 // $1,200.00
Food $300 // $300.00
Subtotal: sum // $1,500.00
Car $250 // $250.00
total // $1,750.00

The second total passes over the subtotal, since a subtotal is a summary of figures already counted. A note that defines a variable called total or sum gets that variable instead, as it always did:

total = 100 // 100
total // 100

The boundary: only the whole line is the total. Inside an expression the word is a name like any other, so sum * 2 in a note that never defines sum is an error that says to write total above, rather than a total nobody asked for. On its own, outside a note, a lone sum has no block to read and says so.

A blank line or a heading acts as a boundary, so total above sums the current block rather than the whole document:

10
20
100
total above // 100

A horizontal rule (---), a code or math fence and a markdown table end the block the same way. A line with no figure on it, a // comment, a > quote or a [[wiki link]], does not: the total passes over it and keeps reading the figures above, so a note can sit in the middle of a column.

rent: $500
// remember to check the gas bill // (no result)
food: $200
total above // $700.00

A subtotal inside the block is a summary of figures already counted, not another figure, so a later total above leaves it out rather than counting those figures twice:

10
total above // 10
5
total above // 15

A line that is itself a total, total above, sum(line 1 : line 3), a tag or section total, is recognised from its text, with any label before a colon set aside, which is the same test the section totals use.

To total a block from somewhere else in the note, a summary at the bottom say, name its heading instead: total of section "Travel" (see sections).

A sum(...) or average(...) over an explicit span reads exactly the lines it names, so it can reach across a boundary a bare above would stop at:

10
20
30
sum(line 1 : line 3) // 60
average(line 1 : line 3) // 20

A blank line or a heading inside the span has no figure to add and is passed over, the way a spreadsheet’s SUM passes over an empty cell, so pressing Enter inside a summed block does not break the sum. A line of prose inside it is still an error, since it is a line that failed rather than one left empty:

10
30
sum(line 1 : line 3) // 40

These forms only work inside a document, since they refer to other lines. They return an error through the single-expression entry point, which has no document to refer to.

line 3 is an absolute number: it means the third line, whatever is on it. Type a new line at the top of the note and everything moves down one, so the line that line 3 meant is now line 4. An editor built on the engine can keep references on their lines as the note changes, the way a spreadsheet keeps a cell reference on its row when a row is inserted above it, by asking the engine’s language service which numbers to update (see reference-aware editing).

A reference to a line that has been deleted has no right number to become, so it is rewritten as line deleted. That answers with an error which says so, rather than quietly reading whichever line moved up into the gap:

10
line deleted + 5 // ERROR: This reference pointed at a line that has been deleted

prev, total above and average above are relative, so they are never rewritten: they read whatever is above them now.

A reference needs a line with an answer of its own. If line 1 reads line 2 and line 2 reads line 1, neither has one: each is computed from the other, and there is no value to start from. The engine reports that on each line rather than settling on a number, and it reports the same thing however the text was reached, typed out at once or edited into a note that used to say something else:

line 2 + 5 // ERROR: Line 2 has not been evaluated yet (forward reference, or out of range)
prev + 5 // ERROR: Line 1 has an error

Line 1 reports that line 2 has not been evaluated yet, which is what a line below it is from where line 1 stands, and line 2 reports that line 1 has an error. The same holds for a cycle that runs through a name (:a = line 2 + 1 above a + 1) or a running total (spent += line 2 above spent += 9): every line on it reports it, and none takes a number from the others.

A reference to a line further down is refused too, cycle or not. A note is read from the top, so from where line 1 stands, line 2 has not been evaluated yet. That holds however the note is evaluated and however often: a live editor runs a note again on every keystroke, and on the second run the line below has an answer from the first, but it is still below, and it is still refused. Put the line that is read above the line that reads it:

line 2 + 1 // ERROR: Line 2 has not been evaluated yet (forward reference, or out of range)
7

Eight other forms read the whole note the same way, each with its own page:

  • Category tags: label a line with #tag and total, average or count every line carrying it, or break the note down by tag.
  • Sections: total, average or count the figures under a heading, by the heading’s name.
  • Goal seek: solve backwards for the input that makes a line reach a target.
  • Table columns: name a markdown table column and summarise the numbers in it.
  • Table lookups: read one cell of a table by the label on its row.
  • Banded rates: apply a table of bands, such as a tax or commission schedule, to an amount.
  • What-if and sweeps: ask what a line would say if an input were different, or list its answers across a range of inputs.
  • Tracing inputs: ask which lines fed a result, inputs of line 4, and which lines fed those.