mq_elixir

Elixir bindings for mq, a jq-like command-line tool for Markdown processing.

Features

Installation

Add mq_elixir to your list of dependencies in mix.exs:

def deps do
[
{:mq_elixir, "~> 0.1.0"}
]
end

Usage

Raw Query String

# Extract all H1 headings
{:ok, result} = Mq.run(".h1", "# Hello\n## World")
IO.inspect(result.values) # ["# Hello"]
# Filter with select
{:ok, result} = Mq.run(".h2 | select(contains(\"Feature\"))", content)

Query Builder

Build queries programmatically using Mq functions and the |> pipe operator.

# Selectors and transformations chain naturally
{:ok, result} =
Mq.h2()
|> Mq.select(Mq.Filter.contains("Feature"))
|> Mq.to_text()
|> Mq.run(content)

Selectors

Mq.h1() # .h1
Mq.h2() # .h2
Mq.code() # .code
Mq.link() # .link
Mq.list() # .[]
Mq.list_at(0) # .[0]
Mq.paragraph() # .p
Mq.task() # .task
Mq.todo() # .todo
Mq.done() # .done
# ... and more (heading, image, blockquote, table, etc.)

Attribute Access

Attribute selectors work as both standalone queries and as chained operations:

# Standalone
Mq.url() # ".url"
Mq.lang() # ".lang"
# Chained — access attributes of selected nodes
Mq.link() |> Mq.url() # ".link | .url"
Mq.code() |> Mq.lang() # ".code | .lang"

Filters

Mq.Filter provides composable filter expressions for select and map:

alias Mq.Filter
# Basic filters
Filter.contains("Feature")
Filter.starts_with("##")
Filter.ends_with("Guide")
Filter.eq("value")
Filter.gt(5)
# Combine with |>
Filter.contains("API")
|> Filter.and_filter(Filter.negate(Filter.contains("Internal")))
# Combine a list
Filter.all([Filter.contains("A"), Filter.contains("B"), Filter.ne("## Draft")])
Filter.any([Filter.contains("Alpha"), Filter.contains("Beta")])
# Negate
Filter.negate(Filter.contains("draft"))

Chaining Operations

Mq.h2()
|> Mq.select(Mq.Filter.contains("API"))
|> Mq.to_text()
|> Mq.downcase()
|> Mq.run(content)

Available transforms include: to_text, to_markdown, to_html, downcase, upcase, trim, split, join, limit, nth, reverse, sort, uniq, and many more.

Working with Results

{:ok, result} = Mq.run(".h", "# H1\n## H2\n### H3")
# Access values
result.values # ["# H1", "## H2", "### H3"]
result.text # "# H1\n## H2\n### H3"
# Enumerate
Enum.each(result, fn heading -> IO.puts(heading) end)
# Convert to string
to_string(result) # "# H1\n## H2\n### H3"

Input Formats

options = %Mq.Options{input_format: :text}
{:ok, result} = Mq.run("select(contains(\"needle\"))", content, options)

Supported formats: :markdown (default), :mdx, :html, :text, :raw, :null

HTML to Markdown

{:ok, markdown} = Mq.html_to_markdown("<h1>Hello</h1><p>World</p>")
# => "# Hello\n\nWorld"
opts = %Mq.ConversionOptions{use_title_as_h1: true}
{:ok, markdown} = Mq.html_to_markdown(html, opts)

Documentation

Full documentation is available on HexDocs.

For mq query language syntax, see the official mq documentation.

License

MIT License