https://github.com/kasvith/htmd
A fast HTML to Markdown converter for Elixir, powered by Rust
https://github.com/kasvith/htmd
elixir elixir-lang htmd html html-to-markdown html2markdown markdown rustler rustler-precompiled turndown
Last synced: 4 months ago
JSON representation
A fast HTML to Markdown converter for Elixir, powered by Rust
- Host: GitHub
- URL: https://github.com/kasvith/htmd
- Owner: kasvith
- License: mit
- Created: 2025-09-04T14:16:31.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2025-09-09T14:27:42.000Z (5 months ago)
- Last Synced: 2025-09-20T01:36:54.875Z (4 months ago)
- Topics: elixir, elixir-lang, htmd, html, html-to-markdown, html2markdown, markdown, rustler, rustler-precompiled, turndown
- Language: Elixir
- Homepage: https://hexdocs.pm/htmd/readme.html
- Size: 65.4 KB
- Stars: 33
- Watchers: 0
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Htmd
[](https://hex.pm/packages/htmd)

[](https://hexdocs.pm/htmd)
[](https://github.com/kasvith/htmd/actions/workflows/test.yml)
A fast HTML to Markdown converter for Elixir, powered by Rust.
Htmd provides high-performance HTML to Markdown conversion using the Rust [htmd crate](https://crates.io/crates/htmd) as a Native Implemented Function (NIF). It offers extensive customization options for controlling the output format and is designed for applications that need to process large amounts of HTML content efficiently.
## Features
- **High Performance**: Leverages Rust's speed for HTML parsing and Markdown generation
- **Extensive Configuration**: Support for all major Markdown formatting options
- **Tag Filtering**: Skip specific HTML tags during conversion
- **Multiple Formats**: Support for different heading styles, list markers, link formats, and more
- **Safe**: Uses Rustler for safe Rust-Elixir interop
## Installation
Add `htmd` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:htmd, "~> 0.2.0"}
]
end
```
## Basic Usage
```elixir
# Simple conversion
{:ok, markdown} = Htmd.convert("
Hello World
")
# => {:ok, "# Hello World"}
# Convert a paragraph
{:ok, markdown} = Htmd.convert("
This is a paragraph with bold text.
")
# => {:ok, "This is a paragraph with **bold** text."}
# Convert links
{:ok, markdown} = Htmd.convert("Example")
# => {:ok, "[Example](https://example.com)"}
# Use the bang version for direct result(shh!! we are silently ignoring errors here)
markdown = Htmd.convert!("
Subtitle
")
# => "## Subtitle"
```
## Advanced Usage with Options
```elixir
html = """
My Document
- First item
- Second item
Final paragraph
"""
{:ok, markdown} = Htmd.convert(html, [
heading_style: :setex, # Use underline-style headers
bullet_list_marker: :dash, # Use dashes for bullet points
skip_tags: ["img"], # Skip image tags
link_style: :referenced # Use reference-style links
])
```
## Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `:heading_style` | `:atx` \| `:setex` | `:atx` | Header format (# vs underline) |
| `:hr_style` | `:dashes` \| `:underscores` \| `:stars` | `:dashes` | Horizontal rule style |
| `:br_style` | `:two_spaces` \| `:backslash` | `:two_spaces` | Line break format |
| `:link_style` | `:inlined` \| `:inlined_prefer_autolinks` \| `:referenced` | `:inlined` | Link format style |
| `:link_reference_style` | `:full` \| `:collapsed` \| `:shortcut` | `:full` | Reference link format |
| `:code_block_style` | `:indented` \| `:fenced` | `:indented` | Code block format |
| `:code_block_fence` | `:backticks` \| `:tildes` | `:backticks` | Fence character for code blocks |
| `:bullet_list_marker` | `:asterisk` \| `:dash` | `:asterisk` | Bullet point character |
| `:ul_bullet_spacing` | `non_neg_integer()` | `3` | Spaces between bullet and content |
| `:ol_number_spacing` | `non_neg_integer()` | `3` | Spaces between number and content |
| `:preformatted_code` | `boolean()` | `false` | Preserve whitespace in inline code |
| `:skip_tags` | `[String.t()]` | `[]` | HTML tags to skip during conversion |
## Examples with Different Styles
### Heading Styles
```elixir
# ATX style (default)
Htmd.convert("
Title
", heading_style: :atx)# => {:ok, "# Title"}
# Setex style
Htmd.convert("
Title
", heading_style: :setex)# => {:ok, "Title\n====="}
```
### List Styles
```elixir
# Asterisk bullets (default)
Htmd.convert("
- Item
# => {:ok, "* Item"}
# Dash bullets
Htmd.convert("
- Item
# => {:ok, "- Item"}
```
### Link Styles
```elixir
# Inline links (default)
Htmd.convert("Link", link_style: :inlined)
# => {:ok, "[Link](https://example.com)"}
# Reference links
Htmd.convert("Link", link_style: :referenced)
# => {:ok, "[Link][1]\n\n[1]: https://example.com"}
```
## Performance
Htmd is designed for high-throughput applications. The Rust implementation provides:
- Fast HTML parsing using html5ever
- Efficient string processing
- Minimal memory allocations
- Safe concurrent usage
## Requirements
- Elixir 1.12 or later
- Rust toolchain (for compilation)
- Compatible with OTP 24+
## Documentation
Full documentation is available on [HexDocs](https://hexdocs.pm/htmd).
## License
This project is licensed under the MIT License.