From d76471b03e8dda99b33ed722248d40691a7416d3 Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Sun, 8 Mar 2026 09:27:35 +0000 Subject: [PATCH] Use MDEx to consolidate Markdown handling --- lib/music_library_web/components/notes.ex | 2 +- lib/music_library_web/components/search_components.ex | 2 +- lib/music_library_web/live/record_set_live/index.ex | 2 +- lib/music_library_web/live/record_set_live/show.ex | 2 +- lib/music_library_web/markdown.ex | 7 +++++-- mix.exs | 3 +-- mix.lock | 4 +--- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/music_library_web/components/notes.ex b/lib/music_library_web/components/notes.ex index c8fe0570..d0c8c76c 100644 --- a/lib/music_library_web/components/notes.ex +++ b/lib/music_library_web/components/notes.ex @@ -157,7 +157,7 @@ defmodule MusicLibraryWeb.Components.Notes do end # sobelow_skip ["XSS.Raw"] - # Markdown.to_html/1 sanitizes HTML via HtmlSanitizeEx + # Markdown.to_html/1 sanitizes HTML via MDEx (ammonia) defp render_content(content) do content |> Markdown.to_html() diff --git a/lib/music_library_web/components/search_components.ex b/lib/music_library_web/components/search_components.ex index 102b8f41..ec380c23 100644 --- a/lib/music_library_web/components/search_components.ex +++ b/lib/music_library_web/components/search_components.ex @@ -347,7 +347,7 @@ defmodule MusicLibraryWeb.SearchComponents do end # sobelow_skip ["XSS.Raw"] - # Markdown.to_html/1 sanitizes HTML via HtmlSanitizeEx + # Markdown.to_html/1 sanitizes HTML via MDEx (ammonia) defp render_description(description) do description |> String.slice(0, 100) diff --git a/lib/music_library_web/live/record_set_live/index.ex b/lib/music_library_web/live/record_set_live/index.ex index cd6d12b0..4e25a9ea 100644 --- a/lib/music_library_web/live/record_set_live/index.ex +++ b/lib/music_library_web/live/record_set_live/index.ex @@ -475,7 +475,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do end # sobelow_skip ["XSS.Raw"] - # Markdown.to_html/1 sanitizes HTML via HtmlSanitizeEx + # Markdown.to_html/1 sanitizes HTML via MDEx (ammonia) defp render_description(description) do description |> Markdown.to_html() diff --git a/lib/music_library_web/live/record_set_live/show.ex b/lib/music_library_web/live/record_set_live/show.ex index 3bf53faa..7b735ee8 100644 --- a/lib/music_library_web/live/record_set_live/show.ex +++ b/lib/music_library_web/live/record_set_live/show.ex @@ -303,7 +303,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Show do defp page_title(:add_record, record_set), do: gettext("Add Record") <> " ยท " <> record_set.name # sobelow_skip ["XSS.Raw"] - # Markdown.to_html/1 sanitizes HTML via HtmlSanitizeEx + # Markdown.to_html/1 sanitizes HTML via MDEx (ammonia) defp render_description(description) do description |> Markdown.to_html() diff --git a/lib/music_library_web/markdown.ex b/lib/music_library_web/markdown.ex index 84a46d9e..59261e0a 100644 --- a/lib/music_library_web/markdown.ex +++ b/lib/music_library_web/markdown.ex @@ -21,8 +21,11 @@ defmodule MusicLibraryWeb.Markdown do result = markdown_text |> process_double_bracket_links() - |> Earmark.as_html!(%Earmark.Options{gfm: true}) - |> HtmlSanitizeEx.markdown_html() + |> MDEx.to_html!( + extension: [autolink: true, strikethrough: true, table: true], + render: [unsafe: true], + sanitize: MDEx.Document.default_sanitize_options() + ) {result, %{}} end diff --git a/mix.exs b/mix.exs index fb9b9469..9105f73c 100644 --- a/mix.exs +++ b/mix.exs @@ -104,8 +104,7 @@ defmodule MusicLibrary.MixProject do {:briefly, "~> 0.5.0"}, # Notes - {:earmark, "~> 1.4"}, - {:html_sanitize_ex, "~> 1.4"}, + {:mdex, "~> 0.11.6"}, # Syntax highlighting {:lumis, "~> 0.1"}, diff --git a/mix.lock b/mix.lock index 8dbbf363..650fd89a 100644 --- a/mix.lock +++ b/mix.lock @@ -13,7 +13,6 @@ "decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "dominant_colors": {:hex, :dominant_colors, "0.1.4", "afdc765c5156ad3eb9016827e86061f778c5b1d4d879977317be80f32be375ba", [:mix], [{:rustler, "~> 0.30.0", [hex: :rustler, repo: "hexpm", optional: true]}, {:rustler_precompiled, "~> 0.7", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}], "hexpm", "8196358f6491a051e84460c622bcbe01ef1daae9e539e13f9b304e3379f09e8b"}, - "earmark": {:hex, :earmark, "1.4.48", "5f41e579d85ef812351211842b6e005f6e0cef111216dea7d4b9d58af4608434", [:mix], [], "hexpm", "a461a0ddfdc5432381c876af1c86c411fd78a25790c75023c7a4c035fdc858f9"}, "ecto": {:hex, :ecto, "3.13.5", "9d4a69700183f33bf97208294768e561f5c7f1ecf417e0fa1006e4a91713a834", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "df9efebf70cf94142739ba357499661ef5dbb559ef902b68ea1f3c1fabce36de"}, "ecto_sql": {:hex, :ecto_sql, "3.13.5", "2f8282b2ad97bf0f0d3217ea0a6fff320ead9e2f8770f810141189d182dc304e", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "aa36751f4e6a2b56ae79efb0e088042e010ff4935fc8684e74c23b1f49e25fdc"}, "ecto_sqlite3": {:hex, :ecto_sqlite3, "0.22.0", "edab2d0f701b7dd05dcf7e2d97769c106aff62b5cfddc000d1dd6f46b9cbd8c3", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.13.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:exqlite, "~> 0.22", [hex: :exqlite, repo: "hexpm", optional: false]}], "hexpm", "5af9e031bffcc5da0b7bca90c271a7b1e7c04a93fecf7f6cd35bc1b1921a64bd"}, @@ -31,7 +30,6 @@ "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "0435d4ca364a608cc75e2f8683d374e55abbae26", [tag: "v2.2.0", sparse: "optimized", depth: 1]}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.4.4", "271455b4d300d5d53a5d92b5bd1c00ad14c5abf1c9ff87be069af5736496515c", [:mix], [{:mochiweb, "~> 2.15 or ~> 3.1", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm", "12e1754204e7db5df1750df0a5dba1bbdf89260800019ab081f2b046596be56b"}, "idna": {:hex, :idna, "7.1.0", "1067a13043538129602d2f2ce6899d8713125c7d19734aa557ce2e3ea55bd4f1", [:rebar3], [], "hexpm", "6ae959a025bf36df61a8cab8508d9654891b5426a84c44d82deaffd6ddf8c71f"}, "igniter": {:hex, :igniter, "0.7.3", "33dccf5f9e3def0358bf01735cfa26c6c25b307078b728e5e514f5df258fbc59", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "9c6144bb50202329cbcbe941c06aed87d7ddc212ce4ecf855f32ab0bbf175258"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, @@ -39,9 +37,9 @@ "live_debugger": {:hex, :live_debugger, "0.6.1", "da9c9813105380c92d3318a40d47c7514b078d85b2502238788dc22aa6e2f5c2", [:mix], [{:file_system, "~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.40 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.7", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.20.8 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "e0893569b427abc5e94fd43d24ddd9cbbe68e57d99364ae1efb8a6c1d597c9db"}, "live_toast": {:hex, :live_toast, "0.8.0", "d7e24801a9a966d8e48872767ac33c50fc14640ac5272128becfc534fabd99b7", [:mix], [{:ecto, ">= 3.11.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:gettext, ">= 0.26.2", [hex: :gettext, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.7.19", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_live_view, ">= 1.0.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "7e64435131b7731698908d59f7ba9f5092df8a3720814f26edf57e99d97a803c"}, "lumis": {:hex, :lumis, "0.1.2", "be5f65768c6be567f98d0a056f7055ea93470e0c34524f80e36e3f0b6589073c", [:mix], [{:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:rustler, "~> 0.29", [hex: :rustler, repo: "hexpm", optional: true]}, {:rustler_precompiled, "~> 0.6", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}], "hexpm", "729fc865753134999cf335de9e93188f384c62119dfdcc0ab8b0c06a1164434b"}, + "mdex": {:hex, :mdex, "0.11.6", "ee2d7661e6418eecdbcd451f33279727478d2d96f1c70d5bc7e8bab285f35fd1", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:lumis, "~> 0.1", [hex: :lumis, repo: "hexpm", optional: false]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:rustler, "~> 0.32", [hex: :rustler, repo: "hexpm", optional: true]}, {:rustler_precompiled, "~> 0.7", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}], "hexpm", "d08bbc554419d1c8e51af680af51a9cbffb576c96bf2e8df77f561d171ded6db"}, "mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"}, "mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"}, - "mochiweb": {:hex, :mochiweb, "3.3.0", "2898ad0bfeee234e4cbae623c7052abc3ff0d73d499ba6e6ffef445b13ffd07a", [:rebar3], [], "hexpm", "aa85b777fb23e9972ebc424e40b5d35106f19bc998873e026dedd876df8ee50c"}, "multipart": {:hex, :multipart, "0.6.0", "73eae40ac88b67a8dd7cf6a2972762c1152470efeb0e18d68c7651f3f70c471b", [:mix], [{:mime, "~> 1.2 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm", "818366054b1ff7215b7c091b73859968aa16e9620ec4a8a79a3a7362960b72bf"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"},