DEV Community

Cover image for In-Place Markdown Editing with mq's --update Flag
Takahiro Sato
Takahiro Sato

Posted on

In-Place Markdown Editing with mq's --update Flag

When managing documentation across multiple markdown files, manual editing becomes inefficient. The mq command-line tool includes an --update flag that modifies files in place while preserving their markdown structure.

demo

In-Place File Modification

Most markdown processors output filtered results without modifying source files. The -U or --update flag changes this behavior by updating the original markdown structure, replacing specific nodes with query results.

# Basic syntax for updates
mq --update 'your_query_here' file.md
Enter fullscreen mode Exit fullscreen mode

Update Examples

1. Batch URL Updates

Replace URLs across multiple files:

# Update specific URLs across all markdown files
mq -U 'if (and(or(.link, .definition), matches_url("old-domain.com"))):
  update(replace("old-domain.com", "new-domain.com"))' docs/**/*.md
Enter fullscreen mode Exit fullscreen mode

Before:

See our [API docs](https://old-domain.com/api)
[Reference]: https://old-domain.com/reference
Enter fullscreen mode Exit fullscreen mode

After:

Check out our [API docs](https://new-domain.com/api)
[Reference]: https://new-domain.com/reference
Enter fullscreen mode Exit fullscreen mode

2. Content Standardization

Standardize code block languages across your documentation:

# Convert all 'js' code blocks to 'javascript'
mq -U '.code | if (attr("lang") == "js"): set_attr("lang", "javascript")' *.md
Enter fullscreen mode Exit fullscreen mode

3. Header Consistency

Ensure consistent header formatting:

# Remove trailing colons from headers
mq -U '.h | if (ends_with(":")): update(rtrimstr(":"))' documentation.md
Enter fullscreen mode Exit fullscreen mode

Before:

# Getting Started:
## Installation:
Enter fullscreen mode Exit fullscreen mode

After:

# Getting Started
## Installation
Enter fullscreen mode Exit fullscreen mode

4. Link Reference Cleanup

Update broken internal links:

# Fix internal link references
mq -U '.link | if (starts_with("#old-section")): update(replace("#old-section", "#new-section"))' README.md
Enter fullscreen mode Exit fullscreen mode

Advanced Update Patterns

Conditional Updates

Update content based on complex conditions:

# Update deprecated badges
mq -U 'if (and(.image, contains("deprecated"))): update(replace("deprecated", "legacy"))' CHANGELOG.md
Enter fullscreen mode Exit fullscreen mode

Selective Text Replacement

Replace text only in specific contexts:

# Update version numbers only in code blocks
mq -U '.code | if (contains("v1.0")): update(replace("v1.0", "v2.0"))' docs/*.md
Enter fullscreen mode Exit fullscreen mode

Nested Element Updates

Modify content within complex structures:

# Update URLs inside link text
mq -U '.link | if (matches_url("example.com")): update("newexample.com")' documentation/*.md
Enter fullscreen mode Exit fullscreen mode

Update Safety

Advanced Patterns

Update + Custom Functions

Create reusable update patterns:

# Save to custom.mq
def modernize_badges(badge_text):
  if (contains("build-passing")):
    replace("build-passing", "build%20passing")
  else:
    badge_text;

# Use it
mq -U 'include "custom" | .image | modernize_badges()' README.md
Enter fullscreen mode Exit fullscreen mode

Update + File Context

Use file information in updates:

# Add file-specific prefixes
mq -U 'let filename = __FILE__ | .h1 | let text = to_text() | update(s"[${filename}] ${text}")' docs/*.md
Enter fullscreen mode Exit fullscreen mode

Update Scenarios

Documentation Maintenance

# Remove outdated warning boxes
mq -U 'select(.blockquote) | if (contains("deprecated")): update("")' docs/*.md

# Update installation commands
mq -U '.code("bash") | if (contains("npm install old-package")): update("npm install new-package")' tutorials/*.md
Enter fullscreen mode Exit fullscreen mode

Link Management

# Convert relative to absolute URLs
mq -U '.link | if (starts_with("./")): update(replace("./", "https://docs.example.com/"))' *.md

# Update image CDN URLs
mq -U '.image | if (matches_url("old-cdn.com")): update(replace("old-cdn.com", "new-cdn.com"))' assets/*.md
Enter fullscreen mode Exit fullscreen mode

Implementation Details

Structure Preservation

mq parses markdown into an abstract syntax tree, unlike text replacement tools:

# This won't accidentally modify code blocks or URLs
mq -U '.text | if (contains("API")): update("Interface")' docs.md
Enter fullscreen mode Exit fullscreen mode

Element Targeting

Queries target specific markdown elements:

# Only update headers, not body text
mq -U '.h | if (contains("v1")): update(replace("v1", "v2"))' changelog.md
Enter fullscreen mode Exit fullscreen mode

Format Preservation

Updates maintain markdown formatting conventions:

# Preserves link formatting styles
mq -U --link-title-style=double '.link | update_text("New Title")' docs.md
Enter fullscreen mode Exit fullscreen mode

Integration with Workflows

CI/CD Automation

# GitHub Actions
- uses: harehare/setup-mq@v1
- name: Update Documentation URLs
  run: |
    mq -U '.link | if (contains("staging.example.com")):
      update(replace("staging.example.com", "example.com"))' docs/*.md
Enter fullscreen mode Exit fullscreen mode

Installation

The easiest way to install mq is through Cargo:

cargo install --git https://github.com/harehare/mq.git mq-cli --tag v0.2.7
Enter fullscreen mode Exit fullscreen mode

For other installation methods, including Homebrew, Docker, and pre-built binaries, check the official installation guide.

Summary

The --update flag modifies mq behavior from read-only filtering to in-place file editing. The feature handles markdown transformations by operating on parsed syntax trees rather than raw text, preserving document structure during modifications.

Start with simple text replacements, then implement conditional logic for complex transformations. This approach reduces manual editing overhead in documentation maintenance workflows.

Support

Resources

Top comments (0)