Skip to content

Math and formulas

Mudlark can evaluate a line, show a calculation inside prose, and use table columns as formula inputs. The editor keeps the expression you wrote. The right pane shows its current value.

on this page

Math lines

Start a line with = and a space. Mudlark evaluates the expression and shows the result in the right pane. A missing space, as in =42, leaves the line as plain text.

= 42 * 1.21 ← 50.82

= sum(10, 20, 30) ← 60

= round(3.14159, 2) ← 3.14

Operators and numbers

Use +, -, *, /, and ^, plus parentheses. ^ is power and groups from right to left. The constants pi ande are built in. Function names are case-insensitive.

Number punctuation follows the vault’s math input convention. The default uses . for decimals and accepts either, or ; between function arguments. A comma-decimal vault uses , for decimals and requires; between arguments. Grouping separators are rejected.; works under either convention when the numbers do not contain a decimal separator.

Units and conversions

Physical units follow a number. Compatible quantities can be added and subtracted, and the result uses the left value’s unit. A bare number can join a quantity and adopts its unit. Multiplying two unit-bearing values or raising one to a power is an error. A same-kind quantity divided by another returns a bare number.

= 5 km + 3 mi ← 9.83 km

= 100 km to mi ← 62.14 mi

= 3 days to h ← 72 h

Use to at the top level to convert between compatible units. Chained conversions run from right to left. A bare number has no source unit, so = 5 to km is an error.

Currency uses the prefixes $, ,£, and ¥. Each symbol is its own unit. The symbol may touch the number or be followed by a space.$5 + $3 returns $8. Mixing currencies, as in $5 + €3, is an incompatible-units error. Mudlark does not apply exchange rates or convert one currency to another.

Day and week durations accept d, day,days, w, week, andweeks. They convert like other duration units and display as days or weeks.

Math blocks

A doubled == opens a math block. Put one expression on each line and close with another bare ==. Add a name after the opener to label the rendered block.

== Budget

income = 5000

rent = 1500

income - rent

==

Variables

Assign a variable with name = expression inside a math block. Later lines in that block can reuse it. Evaluation runs from top to bottom, and variable names ignore case.

Variables belong to one block. Other math blocks, standalone math lines, inline math, and table formulas cannot read them. Function names and the constants pi and e are reserved and cannot be assigned.

Aggregate hints

Glue a function name to the opener to add a result footer. The block’s plain, successful expression lines become the function arguments. Assignment lines and lines with errors are left out.

==sum totals

100

200

300

==

sum = 600 (3 values)

Functions that summarize lists include sum,avg, mean, average,stdev, percentile, min,max, count, median,product, and range. Their argument counts still apply. For example, stdev needs at least two values and percentile takes exactly two arguments.

Conditional aggregates and row functions need table context, so they cannot reduce a math block. An unknown hint leaves the body visible, adds an unknown-function label, and omits the footer.

Inline math

Wrap a single-line math expression in braces to place its result anywhere in a supported line. The examples use a space after the prefix for readability.

The trip is {= 1240 km to mi}.

The square is {= 12^2}.

Inline math works in plain text, tasks, highlights, quotes, bullets, numbered items, custom callouts, and table cells. Balanced braces let an expression contain braces of its own. Table formulas often use the compact spelling {=expr}, such as{=Qty*Price}.

Table formulas

A table formula is inline math that reads cells from its own table. A column name can supply the current row or the full column, depending on where it appears in the expression.

& Item | Qty | Price | Total

& Widget | 2 | $5 | {=Qty * Price}

& Gadget | 3 | $4 | {=Qty * Price}

& Total | | {=sum(Price)} | {=sum(Total)}

Column aggregates

Pass a column name to an aggregate to use every parsed value in that column. The full column roster is sum,avg, mean, average,stdev, percentile, min,max, count, median,product, and range.

{=stdev(Price)} ← sample standard deviation

{=percentile(Price, 90)} ← 90th percentile

stdev requires at least two values and uses the sample formula. percentile(column, p) takes a percentile from 0 through 100 and uses inclusive linear interpolation. Ordinary aggregates skip blank and prose cells. A formula excludes its own cell when it aggregates the column that contains it.

Row formulas

A bare column name outside an aggregate reads the same row. This is how {=Qty * Price} computes a line total. Row formulas can also mix a current-row value with an aggregate, as in {=Price - avg(Price)}.

A same-row reference must resolve to a number, quantity, or date. A blank or prose cell produces a visible not-a-number error.

Column names and errors

Column references match the resolved header text exactly after ignoring case and surrounding whitespace. Put a multi-word name in quotes, as in {="Unit Price" * Qty} or{=sum("Unit Price")}. Quotes identify a name. They do not create text values or text arithmetic.

An unknown name renders an error in that cell. Mudlark may suggest a close header or tell you to quote a multi-word name, but it never uses that suggestion as the value. Formula matching has no fuzzy fallback. A function name used as a header cannot be referenced. A header containing a quote should be renamed.

Row addressing

Table formulas can read one named row, refer to the cell above, or derive a value from the current row’s position.

Keyed lookups

Price[Widget] reads the Price cell from the row whose first column says Widget. To look through another column, put its name before a colon. Price[SKU: W7] finds the row whose SKU cell says W7.

{=Price[Widget]} ← first-column key

{=Price[SKU: W7]} ← named key column

{="Unit Price"["Order ID": "A-7"]} ← quoted names and key

Value columns, key columns, and keys match their resolved display text exactly after ignoring case and surrounding whitespace. A missing key shows an unknown-row error. A duplicate key shows an ambiguous-row error when referenced. A missing named key column shows an unknown-column error. The header row cannot be a keyed target. A self-reference or a keyed dependency cycle shows a circular error.

Running values and row numbers

running(column) sums from the first data row through the formula’s current row, including that row. Use the same formula in every row. Blank and prose cells are skipped, and the first compatible unit is retained.

& Item | Price | Balance | Row

& First | 2 | {=running(Price)} | {=sequential()}

& Second | 3 | {=running(Price)} | {=sequential()}

& Third | 4 | {=running(Price)} | {=sequential()}

Balance renders as 2, 5, 9. Row renders as 1, 2, 3.

sequential() returns the current data row’s 1-based position. Reordering rows renumbers it. above() reads the computed cell directly above in the same column. The first data row has no data cell above, so it errors. A prose value above produces a not-a-number error. Use running(column)for a running total that works unchanged in the first row.

Conditional aggregates

Conditional aggregates select rows with one comparison. The value forms are sumif(column, predicate),avgif(column, predicate),minif(column, predicate), andmaxif(column, predicate). countif(predicate)counts selected rows without a target column.

& Task | Due | Amount

& Renew | 2026-08-27 | 15

& Launch | 2026-09-01 | 25

& Total | | {=sumif(Amount, Due < today())}

A predicate contains one of <, <=,>, >=, =, or!=. Mudlark evaluates it once for every candidate row. Compatible quantities convert before comparison. Date comparisons require dates on both sides. Comparisons outside predicates produce an error.

Every referenced predicate cell must contain a number, quantity, or date. A blank, absent, or prose cell in a candidate row makes the whole formula fail. Populate predicate columns completely. Blank or prose cells in the target column keep the ordinary aggregate rule and are skipped.

A conditional aggregate excludes the entire row that contains its formula. This lets a summary row leave its predicate cell blank and lets {=countif(Qty >= 3)} sit in the Qty column. Plain aggregates exclude only their own cell. Compound predicates, text comparisons, and stored boolean values are not supported.

Date targets follow the same aggregate rules. minif andmaxif can return the earliest or latest selected date.

Dates

A table cell becomes a calendar date when its resolved display text is a valid Gregorian date written exactly as YYYY-MM-DD. Other separators and invalid dates remain prose. Formula source has no date literals. Inside an expression, 2026-01-01 is subtraction.

& Task | Due | Days left

& Renew | 2026-09-01 | {=Due - today()}

& Follow up | 2026-09-08 | {=Due - today()}

Subtracting two dates returns a duration in calendar days. Add or subtract a duration to get another date. The duration must convert to a whole number of days. Adding two dates is an error, and so is any other date operator. Date columns work with min, max, and count. Other aggregates reject dates.

today() returns the local calendar date. It works in a math line, a math block, inline math, or a table formula. A note left open across midnight keeps the prior value until a normal resolve, such as an edit, reopen, or sync.

Results and editor help

Formula guarantees

Formulas never rewrite source text. The editor keeps the expression verbatim, and the right pane shows its computed projection. Errors also render in place without changing the formula or stopping the rest of the table from resolving.

Header and row matching is exact. Suggestions never change which cell is read. Direct and keyed dependency cycles render a circular error in the cells that take part.

Exports that render values, like plain text, Notion, Apple Notes, and HTML, get the computed value. Round-trip formats, like Mudlark files, Markdown folder exports, and Obsidian, keep the original formula.

Editor help

Typing {= in a table cell opens autocomplete for column names and functions. After a keyed reference’s[, autocomplete suggests row keys. Multi-word names are inserted with quotes.

The command palette has two table actions. Insert Total Row appends sum formulas for unique, referenceable numeric columns and skips date columns. Fill Down copies the current cell’s trimmed source into each later row that has a cell in that column when the source contains a formula.

Function reference

Arity counts function arguments. 1+ means one or more, and 2+ means two or more. Preserved functions keep the input unit. Stripped functions return a bare number. Scalar-only functions reject unit-bearing inputs.

List and table functions

FunctionArgumentsUnitsBehavior
sum1+PreservedAdds all arguments.
sumif2PreservedTable only. Sums a column where one predicate matches.
avg, mean, average1+PreservedReturns the arithmetic mean. All three names are equivalent.
avgif2PreservedTable only. Averages a column where one predicate matches.
stdev2+PreservedReturns sample standard deviation with an n - 1 denominator.
percentile2PreservedUses a bare percentile from 0 through 100 with inclusive linear interpolation.
min, max1+PreservedReturns the lowest or highest value. Date columns are supported.
minif, maxif2PreservedTable only. Finds the lowest or highest selected column value.
count1+StrippedCounts parsed values and returns a bare number.
countif1StrippedTable only. Counts rows where one predicate matches.
median1+PreservedReturns the middle value, or the mean of the two middle values.
product1+Scalar onlyMultiplies all arguments. Unit-bearing arguments are rejected.
range1+PreservedReturns the maximum minus the minimum.
today0Calendar dateReturns the local calendar date when the note resolves.
above0PreservedTable data rows only. Reads the computed cell directly above.
running1PreservedTable data rows only. Sums a column through the current row.
sequential0StrippedTable data rows only. Returns the 1-based data-row position.

Single-value functions

FunctionArgumentsUnitsBehavior
sqrt1Scalar onlyReturns the square root. Negative input is an error.
cbrt1Scalar onlyReturns the cube root. Negative input is accepted.
abs1PreservedReturns the absolute value.
sign1StrippedReturns -1, 0, or 1.
floor, ceil1PreservedRounds down or up to a whole value.
round1 or 2PreservedRounds to a whole value, or to 0 through 15 places with a second whole argument. Halves round away from zero.
mod2Scalar onlyTruncates toward zero. The sign follows the dividend, and a zero divisor errors.
gcd, lcm2+Scalar onlyUses whole numbers and returns a non-negative result. gcd(0, 0) is 0, and any 0 makes lcm 0.
log, log101Scalar onlyReturns the base-10 logarithm of a positive value.
ln1Scalar onlyReturns the natural logarithm of a positive value.
exp1Scalar onlyReturns e raised to the given power.
sin, cos, tan1Scalar onlyUses radians. Degrees are not a registered unit.