Elixir bindings for mq, a jq-like command-line tool for Markdown processing.
- Process markdown, MDX, HTML, and plain text
- Full mq query language support
- Programmatic query builder with Elixir pipe operator
- Multiple input and output format options
- Configurable rendering options
- Fast Rust-powered NIF implementation
Add mq_elixir to your list of dependencies in mix.exs:
def deps do
[
{:mq_elixir, "~> 0.1.0"}
]
end# 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)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)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 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"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"))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.
{: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"options = %Mq.Options{input_format: :text}
{:ok, result} = Mq.run("select(contains(\"needle\"))", content, options)Supported formats: :markdown (default), :mdx, :html, :text, :raw, :null
{: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)Full documentation is available on HexDocs.
For mq query language syntax, see the official mq documentation.
MIT License