{"id":31327971,"url":"https://github.com/kasvith/htmd","last_synced_at":"2025-09-25T23:39:58.196Z","repository":{"id":313227009,"uuid":"1050500887","full_name":"kasvith/htmd","owner":"kasvith","description":"A fast HTML to Markdown converter for Elixir, powered by Rust","archived":false,"fork":false,"pushed_at":"2025-09-09T14:27:42.000Z","size":67,"stargazers_count":33,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-20T01:36:54.875Z","etag":null,"topics":["elixir","elixir-lang","htmd","html","html-to-markdown","html2markdown","markdown","rustler","rustler-precompiled","turndown"],"latest_commit_sha":null,"homepage":"https://hexdocs.pm/htmd/readme.html","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kasvith.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-04T14:16:31.000Z","updated_at":"2025-09-19T21:35:59.000Z","dependencies_parsed_at":"2025-09-04T18:15:24.658Z","dependency_job_id":"02d20331-39be-4385-b926-0f5c44fb93de","html_url":"https://github.com/kasvith/htmd","commit_stats":null,"previous_names":["kasvith/htmd"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/kasvith/htmd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kasvith%2Fhtmd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kasvith%2Fhtmd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kasvith%2Fhtmd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kasvith%2Fhtmd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kasvith","download_url":"https://codeload.github.com/kasvith/htmd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kasvith%2Fhtmd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276127714,"owners_count":25589877,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-20T02:00:10.207Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","elixir-lang","htmd","html","html-to-markdown","html2markdown","markdown","rustler","rustler-precompiled","turndown"],"created_at":"2025-09-25T23:39:56.904Z","updated_at":"2025-09-25T23:39:58.190Z","avatar_url":"https://github.com/kasvith.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Htmd\n\n[![Hex Version](https://img.shields.io/hexpm/v/htmd.svg)](https://hex.pm/packages/htmd)\n![Hex.pm Downloads](https://img.shields.io/hexpm/dt/htmd)\n[![Hex Docs](http://img.shields.io/badge/hex.pm-docs-green.svg?style=flat)](https://hexdocs.pm/htmd)\n[![Mix Test](https://github.com/kasvith/htmd/actions/workflows/test.yml/badge.svg)](https://github.com/kasvith/htmd/actions/workflows/test.yml)\n\nA fast HTML to Markdown converter for Elixir, powered by Rust.\n\nHtmd 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.\n\n## Features\n\n- **High Performance**: Leverages Rust's speed for HTML parsing and Markdown generation\n- **Extensive Configuration**: Support for all major Markdown formatting options\n- **Tag Filtering**: Skip specific HTML tags during conversion\n- **Multiple Formats**: Support for different heading styles, list markers, link formats, and more\n- **Safe**: Uses Rustler for safe Rust-Elixir interop\n\n## Installation\n\nAdd `htmd` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:htmd, \"~\u003e 0.2.0\"}\n  ]\nend\n```\n\n## Basic Usage\n\n```elixir\n# Simple conversion\n{:ok, markdown} = Htmd.convert(\"\u003ch1\u003eHello World\u003c/h1\u003e\")\n# =\u003e {:ok, \"# Hello World\"}\n\n# Convert a paragraph\n{:ok, markdown} = Htmd.convert(\"\u003cp\u003eThis is a paragraph with \u003cstrong\u003ebold\u003c/strong\u003e text.\u003c/p\u003e\")\n# =\u003e {:ok, \"This is a paragraph with **bold** text.\"}\n\n# Convert links\n{:ok, markdown} = Htmd.convert(\"\u003ca href='https://example.com'\u003eExample\u003c/a\u003e\")\n# =\u003e {:ok, \"[Example](https://example.com)\"}\n\n# Use the bang version for direct result(shh!! we are silently ignoring errors here)\nmarkdown = Htmd.convert!(\"\u003ch2\u003eSubtitle\u003c/h2\u003e\")\n# =\u003e \"## Subtitle\"\n```\n\n## Advanced Usage with Options\n\n```elixir\nhtml = \"\"\"\n\u003ch1\u003eMy Document\u003c/h1\u003e\n\u003cul\u003e\n  \u003cli\u003eFirst item\u003c/li\u003e\n  \u003cli\u003eSecond item\u003c/li\u003e\n\u003c/ul\u003e\n\u003cimg src=\"image.jpg\" alt=\"Skip this\"\u003e\n\u003cp\u003eFinal paragraph\u003c/p\u003e\n\"\"\"\n\n{:ok, markdown} = Htmd.convert(html, [\n  heading_style: :setex,           # Use underline-style headers\n  bullet_list_marker: :dash,       # Use dashes for bullet points\n  skip_tags: [\"img\"],             # Skip image tags\n  link_style: :referenced         # Use reference-style links\n])\n```\n\n## Configuration Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `:heading_style` | `:atx` \\| `:setex` | `:atx` | Header format (# vs underline) |\n| `:hr_style` | `:dashes` \\| `:underscores` \\| `:stars` | `:dashes` | Horizontal rule style |\n| `:br_style` | `:two_spaces` \\| `:backslash` | `:two_spaces` | Line break format |\n| `:link_style` | `:inlined` \\| `:inlined_prefer_autolinks` \\| `:referenced` | `:inlined` | Link format style |\n| `:link_reference_style` | `:full` \\| `:collapsed` \\| `:shortcut` | `:full` | Reference link format |\n| `:code_block_style` | `:indented` \\| `:fenced` | `:indented` | Code block format |\n| `:code_block_fence` | `:backticks` \\| `:tildes` | `:backticks` | Fence character for code blocks |\n| `:bullet_list_marker` | `:asterisk` \\| `:dash` | `:asterisk` | Bullet point character |\n| `:ul_bullet_spacing` | `non_neg_integer()` | `3` | Spaces between bullet and content |\n| `:ol_number_spacing` | `non_neg_integer()` | `3` | Spaces between number and content |\n| `:preformatted_code` | `boolean()` | `false` | Preserve whitespace in inline code |\n| `:skip_tags` | `[String.t()]` | `[]` | HTML tags to skip during conversion |\n\n## Examples with Different Styles\n\n### Heading Styles\n\n```elixir\n# ATX style (default)\nHtmd.convert(\"\u003ch1\u003eTitle\u003c/h1\u003e\", heading_style: :atx)\n# =\u003e {:ok, \"# Title\"}\n\n# Setex style  \nHtmd.convert(\"\u003ch1\u003eTitle\u003c/h1\u003e\", heading_style: :setex)  \n# =\u003e {:ok, \"Title\\n=====\"}\n```\n\n### List Styles\n\n```elixir\n# Asterisk bullets (default)\nHtmd.convert(\"\u003cul\u003e\u003cli\u003eItem\u003c/li\u003e\u003c/ul\u003e\", bullet_list_marker: :asterisk)\n# =\u003e {:ok, \"*   Item\"}\n\n# Dash bullets\nHtmd.convert(\"\u003cul\u003e\u003cli\u003eItem\u003c/li\u003e\u003c/ul\u003e\", bullet_list_marker: :dash)  \n# =\u003e {:ok, \"-   Item\"}\n```\n\n### Link Styles\n\n```elixir\n# Inline links (default)\nHtmd.convert(\"\u003ca href='https://example.com'\u003eLink\u003c/a\u003e\", link_style: :inlined)\n# =\u003e {:ok, \"[Link](https://example.com)\"}\n\n# Reference links\nHtmd.convert(\"\u003ca href='https://example.com'\u003eLink\u003c/a\u003e\", link_style: :referenced)\n# =\u003e {:ok, \"[Link][1]\\n\\n[1]: https://example.com\"}\n```\n\n## Performance\n\nHtmd is designed for high-throughput applications. The Rust implementation provides:\n\n- Fast HTML parsing using html5ever\n- Efficient string processing  \n- Minimal memory allocations\n- Safe concurrent usage\n\n## Requirements\n\n- Elixir 1.12 or later\n- Rust toolchain (for compilation)\n- Compatible with OTP 24+\n\n## Documentation\n\nFull documentation is available on [HexDocs](https://hexdocs.pm/htmd).\n\n## License\n\nThis project is licensed under the MIT License.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkasvith%2Fhtmd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkasvith%2Fhtmd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkasvith%2Fhtmd/lists"}