Packages
mdex
0.13.1
0.13.3
0.13.2
0.13.1
0.13.0
0.12.5
retired
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.2
0.6.1
0.6.0
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.1.13
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Fast and extensible Markdown for Elixir
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
README.md
# MDEx<!-- MDOC --><div align="center"> <img src="https://raw.githubusercontent.com/leandrocp/mdex/main/assets/images/mdex_logo.png" width="360" alt="MDEx logo" /> <br> <a href="https://hex.pm/packages/mdex"> <img alt="Hex Version" src="https://img.shields.io/hexpm/v/mdex"> </a> <a href="https://hexdocs.pm/mdex"> <img alt="Hex Docs" src="https://img.shields.io/badge/hex.pm-docs-green.svg?style=flat"> </a> <a href="https://opensource.org/licenses/MIT"> <img alt="MIT" src="https://img.shields.io/hexpm/l/mdex"> </a> <p align="center">Fast and Extensible Markdown for Elixir.</p></div>## Features- Fast- Compliant with the [CommonMark spec](https://commonmark.org)- [Plugins](https://hexdocs.pm/mdex/plugins.html)- Formats: - Markdown (CommonMark) - HTML - [Phoenix HEEx](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.Rendered.html) - JSON - XML - [Quill Delta](https://quilljs.com/docs/delta/)- Floki-like [Document AST](https://hexdocs.pm/mdex/MDEx.Document.html)- Req-like [Document pipeline API](https://hexdocs.pm/mdex/MDEx.Document.html)- [GitHub Flavored Markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax)- [GitLab Flavored Markdown](https://docs.gitlab.com/user/markdown)- Discord Flavored Markdown (Partial)- Wiki-style links- Phoenix HEEx components and expressions- [Streaming](https://hexdocs.pm/mdex/streaming.html) incomplete fragments- [Emoji](https://www.webfx.com/tools/emoji-cheat-sheet) shortcodes- Built-in Syntax Highlighting with [Lumis](https://mdex.hexdocs.pm/lumis.html) or [Syntect](https://mdex.hexdocs.pm/syntect.html)- [Code Block Decorators](https://hexdocs.pm/mdex/code_block_decorators-2.html)- HTML sanitization- [~MD Sigil](https://hexdocs.pm/mdex/MDEx.Sigil.html) for Markdown, HTML, HEEx, JSON, XML, and Quill Delta## Plugins- [mdex_gfm](https://hex.pm/packages/mdex_gfm) - Enable [GitHub Flavored Markdown](https://github.github.com/gfm) (GFM)- [mdex_mermaid](https://hex.pm/packages/mdex_mermaid) - Render [Mermaid](https://mermaid.js.org) diagrams in code blocks- [mdex_katex](https://hex.pm/packages/mdex_katex) - Render math formulas using [KaTeX](https://katex.org)- [mdex_video_embed](https://hex.pm/packages/mdex_video_embed) - Privacy-respecting video embeds from code blocks- [mdex_custom_heading_id](https://hex.pm/packages/mdex_custom_heading_id) - Custom heading IDs for markdown headings- [mdex_mermex](https://hex.pm/packages/mdex_mermex) - Render [Mermaid](https://mermaid.js.org) diagrams server-side using Mermex (Rust NIF)## InstallationAdd `:mdex` dependency:```elixirdef deps do [ {:mdex, "~> 0.12"} ]end```Or use [Igniter](https://hexdocs.pm/igniter):```shmix igniter.install mdex```## Usage#### Convert to HTML```elixiriex> MDEx.to_html!("# Hello :smile:", extension: [shortcodes: true])"<h1>Hello π</h1>"```#### Syntax HighlightingSyntax highlight code blocks using either [Lumis](https://mdex.hexdocs.pm/lumis.html) or [Syntect](https://mdex.hexdocs.pm/syntect.html),for example to use Lumis:```elixirdef deps do [ {:mdex, "~> 0.12"}, {:lumis, "~> 0.1"} ]end``````elixirconfig :mdex_native, syntax_highlighter: :lumis```#### GitHub Flavored Markdown (GFM)_Using the `:html_multi_themes` syntax highlighting formatter is not required but you get light/dark using it._````elixirMix.install([ {:mdex_gfm, "~> 0.1"}])markdown = """- [x] Set up project- [ ] Write docs```elixirspawn(fn -> send(current, {self(), 1 + 2}) end)```"""MDEx.new( markdown: markdown, syntax_highlight: [ engine: :lumis, opts: [ formatter: {:html_multi_themes, themes: [light: "github_light", dark: "github_dark"], default_theme: "light-dark()"} ] ])|> MDExGFM.attach()|> MDEx.to_html!()````#### Sigils```elixiriex> import MDEx.Sigiliex> ~MD[# Hello :smile:]HTML"<h1>Hello π</h1>"``````elixiriex> import MDEx.Sigiliex> assigns = %{project: "MDEx"}iex> ~MD[# {@project}]HEEX%Phoenix.LiveView.Rendered{...}``````elixiriex> import MDEx.Sigiliex> ~MD[# Hello :smile:]#MDEx.Document(3 nodes)<βββ 1 [heading] level: 1, setext: falseβ βββ 2 [text] literal: "Hello "β βββ 3 [short_code] code: "smile", emoji: "π">```#### Streaming```elixiriex> MDEx.new(streaming: true)...> |> MDEx.Document.put_markdown("**Install")...> |> MDEx.to_html!()"<p><strong>Install</strong></p>"```## Examples and GuidesIn docs you can find [Livebook examples](https://hexdocs.pm/mdex/gfm.html) covering options and usage, and [Guides](https://hexdocs.pm/mdex/plugins.html) for more info.## FoundationThe library is built on top of:- [comrak](https://crates.io/crates/comrak) - a fast Rust port of [GitHub's CommonMark parser](https://github.com/github/cmark-gfm)- [ammonia](https://crates.io/crates/ammonia) for HTML Sanitization- [lumis](https://crates.io/crates/lumis) for Syntax Highlighting<!-- MDOC -->## Used By- [00](https://github.com/technomancy-dev/00)- [Algora](https://github.com/algora-io/algora)- [Ash AI](https://github.com/ash-project/ash_ai)- [BeaconCMS](https://github.com/BeaconCMS/beacon)- [BeamLens Web](https://github.com/beamlens/beamlens_web)- [Bonfire](https://github.com/bonfire-networks/bonfire-app)- [Canada Navigator](https://github.com/canada-ca/navigator)- [Conpipe](https://github.com/andyl/conpipe)- [Exmeralda](https://github.com/bitcrowd/exmeralda)- [Hexpm](https://github.com/hexpm/hexpm)- [Jido](https://github.com/agentjido/jido)- [Loomkin](https://github.com/bleuropa/loomkin)- [Phoenix SEO](https://github.com/dbernheisel/phoenix_seo)- [Phoenix Storybook](https://github.com/phenixdigital/phoenix_storybook)- [Plural Console](https://github.com/pluralsh/console)- [Prosody](https://github.com/halostatue/prosody)- [Reposit](https://github.com/reposit-bot/reposit)- [Sagents Live Debugger](https://github.com/sagents-ai/sagents_live_debugger)- [Sayfa](https://github.com/furkanural/sayfa)- [Tableau](https://github.com/elixir-tools/tableau)- [Teiserver](https://github.com/beyond-all-reason/teiserver)- [TermUI](https://github.com/pcharbon70/term_ui)- [Tuist](https://github.com/tuist/tuist)- [Valentine](https://github.com/maxneuvians/valentine)- [Wraft](https://github.com/wraft/wraft)- And [more...](https://github.com/search?q=lang%3Aelixir+%3Amdex&type=code)_Are you using MDEx and want to list your project here? Please send a PR!_## Sponsorsπ **Support MDEx Development**If you or your company find MDEx useful, please consider sponsoring its development.β‘οΈ **[GitHub Sponsors](https://github.com/sponsors/leandrocp)**Your support helps maintain and improve MDEx for the entire Elixir community!**Current and previous sponsors**<a href="https://dockyard.com" target="_blank"><img src="assets/images/dockyard_logo.svg" width="200" alt="DockYard" /></a>## MotivationMDEx was born out of the necessity of parsing CommonMark files, to parse hundreds of files quickly, and to be easily extensible by consumers of the library.- [earmark](https://hex.pm/packages/earmark) is extensible but [can't parse](https://github.com/RobertDober/earmark_parser/issues/126) all kinds of documents and is slow to convert hundreds of markdowns.- [md](https://hex.pm/packages/md) is very extensible but the doc says "If one needs to perfectly parse the common markdown, Md is probably not the correct choice" and CommonMark was a requirement to parse many existing files.- [markdown](https://hex.pm/packages/markdown) is not precompiled and has not received updates in a while.- [cmark](https://hex.pm/packages/cmark) is a fast CommonMark parser but it requires compiling the C library, is hard to extend, and was archived on Apr 2024.## Comparison|Feature|MDEx|Earmark|md|cmark|| --- | --- | --- | --- | --- ||Active|β
|β|β
|β||Pure Elixir|β οΈΒΉ|β
|β
|β||Extensible|β
|β
|β
|β||Syntax Highlighting|β
|β|β|β||Code Block Decorators|β
|β|β|β||Streaming (fragments)|β
|β|β|β||Phoenix HEEx components|β
|β|β|β||AST|β
|β
|β
|β||AST to Markdown|β
|β οΈΒ²|β|β||To HTML|β
|β
|β
|β
||To JSON|β
|β|β|β||To XML|β
|β|β|β
||To Manpage|β|β|β|β
||To LaTeX|β|β|β|β
||To Quill Delta|β
|β|β|β||Emoji|β
|β|β|β||GFMΒ³|β
|β
|β|β||GLFMβ΄|β
|β|β|β||Discordβ΅|β οΈβΆ|β|β|β|1. MDEx depends on [mdex_native](https://hex.pm/packages/mdex_native) which uses Rustler2. Possible with [earmark_reversal](https://hex.pm/packages/earmark_reversal)3. GitHub Flavored Markdown4. GitLab Flavored Markdown5. Discord Flavored Markdown6. Partial support## BenchmarkA [benchmark](benchmark.exs) is available to compare existing libs:```Name ips average deviation median 99th %mdex 8983.16 0.111 ms Β±6.52% 0.110 ms 0.144 msmd 461.00 2.17 ms Β±2.64% 2.16 ms 2.35 msearmark 110.47 9.05 ms Β±3.17% 9.02 ms 10.01 msComparison:mdex 8983.16md 461.00 - 19.49x slower +2.06 msearmark 110.47 - 81.32x slower +8.94 msMemory usage statistics:Name average deviation median 99th %mdex 0.00184 MB Β±0.00% 0.00184 MB 0.00184 MBmd 6.45 MB Β±0.00% 6.45 MB 6.45 MBearmark 5.09 MB Β±0.00% 5.09 MB 5.09 MBComparison:mdex 0.00184 MBmd 6.45 MB - 3506.37x memory usage +6.45 MBearmark 5.09 MB - 2770.15x memory usage +5.09 MB```The most performance gain is using the `~MD` sigil to compile the Markdown instead of parsing it at runtime,prefer using it when possible.To finish, a friendly reminder that all libs have their own strengths and trade-offs so use the one that better suits your needs.## Acknowledgements- [comrak](https://crates.io/crates/comrak) crate for all the heavy work on parsing Markdown and rendering HTML- [Floki](https://hex.pm/packages/floki) for the AST- [Req](https://hex.pm/packages/req) for the pipeline API- Logo based on [markdown-mark](https://github.com/dcurtis/markdown-mark)