Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Evaluation Model

This page describes how a query runs against its input and how None moves through it. The examples use this input, saved as doc.md:

# Title

para one

## Sub

- a
- b

Overview

 input            split into          query runs          None is          printed
 (doc.md)         top-level nodes     once per node       dropped          in input order

                  ┌─ # Title ──────▶  query ──▶ "# TITLE" ──────────────▶ # TITLE
                  ├─ para one ─────▶  query ──▶ None ──────╳
 Markdown text ──▶├─ ## Sub ───────▶  query ──▶ "## SUB" ───────────────▶ ## SUB
                  ├─ a ────────────▶  query ──▶ None ──────╳
                  └─ b ────────────▶  query ──▶ None ──────╳

                  (the query above is `.h | upcase()`)

Each node is processed on its own. The runs do not share a result, and the order of the output follows the order of the input.

One run per top-level node

The input is split into top-level nodes and the query runs once for each of them. A list is split into its items, so the input above has five nodes: the two headings, the paragraph, and the items a and b.

mq 'to_text() | len()' doc.md
5
8
3
1
1
Nodeselflen() of its text
1# Title5
2para one8
3## Sub3
4a1
5b1

Each run sees only its own node as self.

None produces no output

A run that ends with None prints nothing. This is what makes selectors and select filter:

mq '.h' doc.md
# Title
## Sub

.h returns None for the nodes that are not headings, and those runs are dropped.

 node         .h            printed?
 ──────────   ───────────   ────────
 # Title      # Title       yes
 para one     None          no
 ## Sub       ## Sub        yes
 a            None          no
 b            None          no

These forms all end in None for a non-matching node, so they drop it:

QueryNon-matching node
.h | upcase().h is None, and upcase() of None is None
select(.h) | upcase()select returns None
if (is_h()): upcase()the missing else branch evaluates to None

Adding an else keeps the node:

mq 'if (is_h()): upcase() else: self' doc.md
# TITLE

para one

## SUB

- a
- b

None does not stop a pipe

None is an ordinary value. A pipe keeps running after it, and a function that receives None decides what to do with it:

 1 ──▶ None ──▶ 2
       │         │
       │         └─ still runs: the result is 2
       └─ the pipe does not stop here
mq '1 | None | 2' doc.md

The query prints 2 five times, once per node. If you want a pipe to stop on a non-match, use select or an if, so the whole run ends in None.

Updating in place

With -U / --update, a run that ends with None keeps the original node instead of removing it, so only the nodes you touch change.

              without -U                     with -U
              ──────────                     ───────
 # Title  ──▶ # TITLE                        # TITLE
 para one ──▶ (dropped)                      para one
 ## Sub   ──▶ ## SUB                         ## SUB
 a        ──▶ (dropped)                      - a
 b        ──▶ (dropped)                      - b
mq -U '.h | upcase()' doc.md
# TITLE

para one

## SUB

- a
- b

select(.h) | upcase() and if (is_h()): upcase() give the same result with -U.

Running once over all nodes

Two things run the query once over the whole input instead of once per node:

  • -A / --aggregate collects the nodes into a single array before the query runs.
  • nodes collects the per-node results of everything before it into an array, and the rest of the query runs once against that array.
 per node (default)                    -A / nodes

 n1 ──▶ query ──▶ r1                   n1 ┐
 n2 ──▶ query ──▶ r2                   n2 ├──▶ [n1..n5] ──▶ query ──▶ r
 ...                                   ...┘
 n5 ──▶ query ──▶ r5                   n5 ┘
mq -A 'len()' doc.md
5

Null input

With -I null there is no input to split. The query runs once and self is None:

mq -I null '1 + 1'
2

Exit status

With -e / --exit-status, a run where every result is empty, such as None or a non-matching select, exits with 4. See Input and Output Behavior for the full table.