# Quickstart
Work through this in a terminal with a markdown file handy. The
examples use `README.md`, but any markdown works.
## Install
```sh
cargo install --path . --features tty
```
Without `--features tty` you still get markdown and JSON output.
The `tty` feature pulls in `mdcat-ng` for terminal rendering.
## The shape of a query
```sh
mdqy '<EXPR>' [FILE ...]
```
If you pipe markdown in on stdin, the path argument is optional:
```sh
Identity. Prints the file back, byte-for-byte.
## Step 1. Pull something out
The plaintext of each heading:
```sh
`headings` is a built-in filter that streams every heading node.
`.text` is the flattened plaintext on each one.
Link hrefs:
```sh
Fence language tags:
```sh
## Step 2. Filter
Only H2s:
```sh
Or the short form:
```sh
Only Rust code blocks:
```sh
## Step 3. Drill into a section
```sh
mdqy '# Install' README.md
```
`# Install` is sugar for `section("Install")`. It returns the
heading plus everything beneath it, up to the next heading of
equal or shallower level.
Grab every code fence inside the Install section:
```sh
The `>` combinator scopes the right-hand side inside the section
the left side picked. Nest it:
```sh
## Step 4. Shape the output
An object per heading:
```sh
`{level, text, anchor}` is jq shorthand for
`{level: .level, text: .text, anchor: .anchor}`.
Collect everything into one array:
```sh
mdqy '[headings | .text]' README.md
```
Group code blocks by language and count them:
```sh
```
## Step 5. Switch output format
```sh
mdqy --output json 'headings' README.md
mdqy --output md '# Install' README.md # valid markdown
mdqy --output tty '# Install' README.md # needs the tty feature
`auto` (the default) prints markdown for Node results, JSON for
scalars, and switches to `tty` when stdout is a terminal and the
feature is compiled in.
Without `--features tty` the markdown output still pipes into any
external renderer:
```sh
```
Same result, slightly more typing.
## Step 6. Many files at once
```sh
Pass a directory, and mdqy walks it recursively, honouring
`.gitignore`, `.ignore`, and hidden-file rules (same mental model
as `rg`).
Tag results with their source path:
```sh
Treat all files as one virtual document:
```sh
Collect all file roots into an array, then query once:
```sh
mdqy --slurp '[.[] | headings | .text] | add' docs/
```
## Step 7. Rewrite in place
Preview first:
```sh
That prints a unified diff. Nothing else changes. When you're
ready, swap `--dry-run` for `-U`:
```sh
`-U` writes atomically via a temp file in the same directory.
If it fails, the original is untouched.
Bump every heading one level deeper:
```sh
Strip image titles across a docs tree:
```sh
mdqy -U 'walk(if type == "image" then del(.title) else . end)' docs/
```
Unchanged subtrees round-trip byte-for-byte. Only the mutated
spans get regenerated. See [transforms.md](transforms.md) for why.
## Step 8. Pipe into jq, ripgrep, whatever
JSON output flattens each Node's attributes next to `kind` and
`children`, so standard jq pipelines work:
```sh
Raw output for shell loops:
```sh
## What to read next
- [language.md](language.md): the full query language.
- [selectors.md](selectors.md): `hN`, pseudos, `#`, `>`.
- [transforms.md](transforms.md): the write path in detail.
- [architecture.md](architecture.md): how mdqy fits together
internally.