From 4a67585e67e8fe72f3c9b754df3c0a32f799d05e Mon Sep 17 00:00:00 2001 From: Austin Ziegler Date: Sat, 4 Jul 2026 12:23:25 -0400 Subject: [PATCH] chore!: upgrade mdex to 0.14 If a Tableau blog uses MDEx syntax highlighting, the latest two versions of MDEx have breaking changes to how syntax highlighting works and your blog configuration must be modified for it to continue working. There are two supported syntax highlighters: Lumis (tree-sitter) and Syntect (Sublime Text grammars). This modification to Tableau does not include either syntax highlighter package and shows Syntect as its primary example with a documentation section added for the distinction while linking to the MDEx page for each. Neither syntax highlighter works without modification to the site `config/config.exs` for selecting the appropriate syntax highlighting NIF: ```elixir config :mdex_native, syntax_highlighter: :syntect config :mdex_native, syntax_highlighter: :lumis ``` The MDEx options configuration must also be updated: ```diff render: [unsafe: true], - syntax_highlight: [formatter: {:html_inline, theme: "neovim_dark"}], + syntax_highlight: [engine: :syntect, theme: "Catppuccin Macchiato"], plugins: [MDExGFM] ``` --- lib/tableau.ex | 47 ++++++++++++++++++++++++++++++++++++++++++++++- mix.exs | 2 +- mix.lock | 5 +++-- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/lib/tableau.ex b/lib/tableau.ex index a3b0619..d446ce3 100644 --- a/lib/tableau.ex +++ b/lib/tableau.ex @@ -19,6 +19,8 @@ defmodule Tableau do import Config + config :mdex_native, syntax_highlighter: :syntect + config :tableau, :config, url: "http://localhost:8080", timezone: "America/Indiana/Indianapolis", @@ -41,11 +43,54 @@ defmodule Tableau do footnotes: true ], render: [unsafe: true], - syntax_highlight: [formatter: {:html_inline, theme: "neovim_dark"}], + syntax_highlight: [engine: :syntect, theme: "Catppuccin Macchiato"], plugins: [MDExGFM] ] ] ``` + + ### Syntax Highlighting + + MDEx provides two syntax highlighting engines: [Lumis][lumis] and [Syntect][syntact]. + The Syntect engine requires less configuration; it uses Sublime Text highlighting + grammars (defined with regular expressions). Supported themes are part of the + [two-face][2face] crate. + + The Lumis engine requires more configuration and a defined package for each of the + languages rendered on your site. + + ```elixir + # config/config.exs + config :mdex_native, syntax_highlighter: :lumis + + config :tableau, :config, + # … + markdown: [ + # … + syntax_highlight: [engine: :lumis, theme: "neovim_dark"] + ] + + # mix.exs + defp defps do + [ + # … + {:lumis, "~> 0.10"}, + {:lumis_wasm_elixir, "~> 0.26"}, + {:lumis_wasm_ruby, "~> 0.26"}, + {:lumis_wasm_rust, "~> 0.26"} + ] + end + ``` + + The full list of tree-sitter syntax parsers can be loaded using the [full][lumis-full] + bundle, but note that Lumis enforces [highlighting budgets][lumis-budget] that can be + configured. + + [2face]: https://crates.io/crates/two-face + [lumis-budget]: https://mdex.hexdocs.pm/lumis.html#highlighting-budgets + [lumis-full]: https://hex.pm/packages/lumis_wasm_bundle_full + [lumis]: https://mdex.hexdocs.pm/lumis.html + [syntect]: https://mdex.hexdocs.pm/syntect.html """ @doc """ diff --git a/mix.exs b/mix.exs index a14124c..63cc9f0 100644 --- a/mix.exs +++ b/mix.exs @@ -35,7 +35,7 @@ defmodule Tableau.MixProject do {:date_time_parser, "~> 1.2"}, {:html_entities, "~> 0.5.2"}, {:libgraph, "~> 0.16.0"}, - {:mdex, "~> 0.11.1"}, + {:mdex, "~> 0.14.2"}, {:schematic, "~> 0.5.1"}, {:slugify, "~> 1.3"}, {:tz, "~> 0.28.1"}, diff --git a/mix.lock b/mix.lock index 38c835c..b95d86b 100644 --- a/mix.lock +++ b/mix.lock @@ -11,10 +11,11 @@ "makeup": {:hex, :makeup, "1.2.2", "882d46dc0905e9ff7abf2aab61a7e6b3dcc555533977d8a23b06019e6c89ac94", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "9a1a24e5b343b8ae16abea0822c10a6f75da27af7fa802ada5251f7579bfccfa"}, "makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"}, "makeup_erlang": {:hex, :makeup_erlang, "1.1.0", "835f7e60792e08824cda445639555d7bf1bbbddb1b60b306e33cb6f6db24dc74", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "1cd6780fb1dd1a03979abaed0fe82712b0625118fd5257d3ebbf73f960c73c3c"}, - "mdex": {:hex, :mdex, "0.11.7", "583b35c7160c4e26deab6233f967669d51de6f8b5f7b605adc55037abf7a20d2", [: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", "6dac3deb3ecb1a0a5ac9f383c9c57e46510b0a519e6fb21883d9ead34d0e4ffd"}, + "mdex": {:hex, :mdex, "0.14.2", "8d2b376f3de8f9f03a2ba0992eeb4f76d58fa790b0ed78dc90bcb5422ce7ff5d", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:lumis, "~> 0.10", [hex: :lumis, repo: "hexpm", optional: true]}, {:mdex_native, ">= 0.2.11", [hex: :mdex_native, 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, "~> 0.20.0 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}], "hexpm", "7003e60b8621ab1c9b3671221a8dcc27dee9f9086026c25ea7aed4057d07978f"}, + "mdex_native": {:hex, :mdex_native, "0.2.11", "439f8448bd349611dccce197c8822fc1e2d63907e346f3a68527905bae91c6d7", [:mix], [{:rustler, "~> 0.32", [hex: :rustler, repo: "hexpm", optional: true]}, {:rustler_precompiled, "~> 0.8", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}], "hexpm", "97e5c201fa016ad4dbd948a8014e314fc2d2e15a7fe88e73994ecfdd51a5dd08"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, - "rustler_precompiled": {:hex, :rustler_precompiled, "0.9.0", "3a052eda09f3d2436364645cc1f13279cf95db310eb0c17b0d8f25484b233aa0", [:mix], [{:rustler, "~> 0.23", [hex: :rustler, repo: "hexpm", optional: true]}], "hexpm", "471d97315bd3bf7b64623418b3693eedd8e47de3d1cb79a0ac8f9da7d770d94c"}, + "rustler_precompiled": {:hex, :rustler_precompiled, "0.10.0", "8f07ff0865cb09a6a0f75e11701e9a46e331e05f737da4e5b01374dcd25b68c0", [:mix], [{:rustler, "~> 0.28", [hex: :rustler, repo: "hexpm", optional: true]}], "hexpm", "c68c9dc732c12acfdf4a7fa06f4e6f48a641179e6be49a474c8a60809929c430"}, "schematic": {:hex, :schematic, "0.5.2", "07b666b971b780bcfbae7a5032945886dc9fb7e31834d7438c6e572ef80c2866", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cef597a88260823a806c106071213bd85670b855007cd70e21284a716fe44348"}, "slugify": {:hex, :slugify, "1.3.1", "0d3b8b7e5c1eeaa960e44dce94382bee34a39b3ea239293e457a9c5b47cc6fd3", [:mix], [], "hexpm", "cb090bbeb056b312da3125e681d98933a360a70d327820e4b7f91645c4d8be76"}, "styler": {:hex, :styler, "1.11.0", "35010d970689a23c2bcc8e97bd8bf7d20e3561d60c49be84654df5c37d051a9c", [:mix], [], "hexpm", "70f36165d0cf238a32b7a456fdef6a9c72e77e657d7ac4a0ace33aeba3f2b8c0"},