Processing Markdown with mq
Quick Reference
Selectors
| Selector | Description |
| ---------------- | ---------------------- |
| .h | All headings |
| .h1–.h6 | Specific heading level |
| .text | Text nodes |
| .code | Code blocks |
| .code_inline | Inline code |
| .strong | Bold text |
| .emphasis | Italic text |
| .delete | Strikethrough |
| .link | Links |
| .image | Images |
| .list | List items |
| .blockquote | Block quotes |
| .[][] | Table cells |
| .html or .<> | HTML nodes |
| .footnote | Footnotes |
| .math | Math blocks |
| .yaml, .toml | Frontmatter |
Attribute Access
.h.level # Heading level (1-6)
.h.depth # Same as .h.level
.code.lang # Code block language
.code.value # Code block content
.link.url # Link URL
.link.title # Link title
.image.url # Image URL
.image.alt # Image alt text
.list.index # List item index
.list.level # Nesting level
.list.ordered # Whether ordered list
.list.checked # Checkbox state
.[0][0].row # Table cell row
.[0][0].column # Table cell column
Common Patterns
Extract Elements
mq '.h' file.md # All headings
mq '.h1' file.md # Only h1 headings
mq '.code' file.md # All code blocks
mq '.link.url' file.md # All URLs
mq '.image.alt' file.md # All image alt texts
Filter with select
mq 'select(.code)' file.md # Only code blocks
mq 'select(!.code)' file.md # Everything except code blocks
mq 'select(.h.level <= 2)' file.md # h1 and h2 only
mq 'select(.code.lang == "rust")' file.md # Rust code blocks only
mq 'select(contains("TODO"))' file.md # Nodes containing "TODO"
Transform Content
mq '.h | to_text()' file.md # Headings as plain text
mq '.code | to_text()' file.md # Code block content as text
mq '.link | to_string()' file.md # Links as strings
Generate Table of Contents
.h
| let link = to_link("#" + to_text(self), to_text(self), "")
| let level = .h.depth
| if (!is_none(level)): to_md_list(link, level - 1)
Multi-File Processing
mq -A 'pluck(.code.value)' *.md # Collect all code values
mq -S 's"\n---\n"' 'identity()' *.md # Merge files with separator
Important: HTML Input and Selectors
When using -I html, mq first converts HTML to Markdown, then queries the resulting Markdown AST. You must always use Markdown selectors, not HTML element names.
# WRONG: HTML element selectors do NOT work
curl -s https://example.com | mq -I html '.p | to_text()' # Error: Unknown selector `.p`
curl -s https://example.com | mq -I html '.a | to_text()' # Error: Unknown selector `.a`
curl -s https://example.com | mq -I html '.div | to_text()' # Error: Unknown selector `.div`
# CORRECT: Use Markdown selectors regardless of input format
curl -s https://example.com | mq -I html '.text | to_text()' # Extract text nodes
curl -s https://example.com | mq -I html '.link | to_text()' # Extract links (HTML <a> → .link)
curl -s https://example.com | mq -I html '.h | to_text()' # Extract headings (HTML <h1>-<h6> → .h)
curl -s https://example.com | mq -I html '.code | to_text()' # Extract code blocks (HTML <pre><code> → .code)
curl -s https://example.com | mq -I html '.image' # Extract images (HTML <img> → .image)
curl -s https://example.com | mq -I html '.strong' # Extract bold text (HTML <strong>/<b> → .strong)
curl -s https://example.com | mq -I html '.emphasis' # Extract italic text (HTML <em>/<i> → .emphasis)
curl -s https://example.com | mq -I html '.list' # Extract list items (HTML <ul>/<ol>/<li> → .list)
curl -s https://example.com | mq -I html '.blockquote' # Extract blockquotes (HTML <blockquote> → .blockquote)
The -I html flag only changes the input parser — the query language and selectors remain the same as for Markdown input.
CLI Options
| Flag | Purpose |
| ------------------------------ | -------------------------------------------------------------- |
| -A, --aggregate | Combine all inputs into single array |
| -I, --input-format | Input format: markdown, mdx, html, text, null, raw |
| -F, --output-format | Output format: markdown, html, text, json, none |
| -U, --update | Update file in place |
| -f, --from-file | Load query from .mq file |
| -o, --output | Write to output file |
| -S, --separator | Insert query result between files |
| --args NAME VALUE | Set runtime variable |
| --rawfile NAME FILE | Load file into variable |
| --stream | Process line by line |
| --csv, --yaml, --toml, --xml | Load built-in modules |
| -C, --color-output | Colorize output |
| -P THRESHOLD | Parallel processing threshold |
For complete function reference, see REFERENCE.md. For advanced patterns and examples, see EXAMPLES.md.
When NOT to Use mq
- Binary file processing
- Non-Markdown structured data (use jq for JSON, yq for YAML instead)
- Simple
catorechooperations where no transformation is needed
Scan to join WeChat group