Skip to content

Commit f62776a

Browse files
committed
feat!: update to MDEx 0.10
MDEx 0.10 has a few breaking changes which should have minimal impact on Tableau, but the larger change is that there is explicit support for plugins in MDEx, using the similar patterns as Req does. To simplify the use of plugins in Tableau, I have added a `plugins` key to `config.markdown.mdex` which is extracted and used to attach MDEx plugin modules prior to calling `MDEx.to_html!()`. This _could_ be implemented as a separate key `config.mdex_plugins`, but since it's part of the markdown converter, this felt more natural to me. If MDEx or one of its plugins adds a `plugins` option, this will break that -- but I think it's low probability.
1 parent de5e67c commit f62776a

4 files changed

Lines changed: 48 additions & 13 deletions

File tree

lib/tableau.ex

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ defmodule Tableau do
1010
* `:converters` - mapping of file extensions to converter module. Defaults to `[md: Tableau.MDExConverter]`
1111
* `:markdown` - keyword
1212
* `:mdex` - keyword - Options to pass to `MDEx.to_html/2`
13+
* `:plugins` - module list - MDEx plugin modules to attach to the processing pipeline
1314
* `:slug` - keyword - Options to pass to `Slug.slugify/2`
1415
1516
### Example
@@ -41,7 +42,8 @@ defmodule Tableau do
4142
footnotes: true
4243
],
4344
render: [unsafe: true],
44-
syntax_highlight: [formatter: {:html_inline, theme: "neovim_dark"}]
45+
syntax_highlight: [formatter: {:html_inline, theme: "neovim_dark"}],
46+
plugins: [MDExGFM]
4547
]
4648
]
4749
```
@@ -61,9 +63,5 @@ defmodule Tableau do
6163
6264
Will use the globally configured options, but you can also pass it overrides.
6365
"""
64-
def markdown(content, overrides \\ []) do
65-
{:ok, config} = Tableau.Config.get()
66-
67-
MDEx.to_html!(content, Keyword.merge(config.markdown[:mdex], overrides))
68-
end
66+
defdelegate markdown(content, overrides \\ []), to: Tableau.MDExConverter
6967
end
Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,45 @@
11
defmodule Tableau.MDExConverter do
22
@moduledoc """
3-
Converter to parse markdown content with `MDEx`
3+
Converter to parse markdown content with `MDEx` with support for MDEx plugins.
44
"""
5+
6+
@doc """
7+
Convert markdown content to HTML using `MDEx.to_html!/2`.
8+
9+
Will use the globally configured options, but you can also pass it overrides.
10+
"""
11+
def markdown(content, overrides \\ []) do
12+
{:ok, config} = Tableau.Config.get()
13+
14+
{plugins, mdex_config} = resolve_plugins(config, overrides)
15+
16+
render!(content, mdex_config, plugins)
17+
end
18+
519
def convert(_filepath, _front_matter, body, %{site: %{config: config}}) do
6-
MDEx.to_html!(body, config.markdown[:mdex])
20+
{plugins, mdex_config} = resolve_plugins(config)
21+
22+
render!(body, mdex_config, plugins)
23+
end
24+
25+
defp resolve_plugins(config, overrides \\ []) do
26+
config.markdown[:mdex]
27+
|> Keyword.merge(overrides, fn
28+
:plugins, left, right -> List.wrap(right) ++ List.wrap(left)
29+
_, _, v -> v
30+
end)
31+
|> Keyword.pop(:plugins, [])
32+
end
33+
34+
defp render!(content, mdex_config, plugins) do
35+
mdex_config
36+
|> Keyword.put(:markdown, content)
37+
|> MDEx.new()
38+
|> attach_plugins(plugins)
39+
|> MDEx.to_html!()
40+
end
41+
42+
defp attach_plugins(mdex, plugins) do
43+
Enum.reduce(plugins, mdex, fn mod, mdex -> mod.attach(mdex) end)
744
end
845
end

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ defmodule Tableau.MixProject do
3737
{:date_time_parser, "~> 1.2"},
3838
{:html_entities, "~> 0.5.2"},
3939
{:libgraph, "~> 0.16.0"},
40-
{:mdex, "~> 0.9.0"},
40+
{:mdex, "~> 0.10.0"},
4141
{:schematic, "~> 0.5.1"},
4242
{:slugify, "~> 1.3"},
4343
{:tz, "~> 0.28.1"},

mix.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
%{
2-
"autumn": {:hex, :autumn, "0.5.5", "05cda4e2b79957c8540eb0184f1ac00fba187a6dabd8461e78c40f9fc8417f2d", [:mix], [{:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:rustler, "~> 0.29", [hex: :rustler, repo: "hexpm", optional: false]}, {:rustler_precompiled, "~> 0.6", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}], "hexpm", "49e40b50e16fc49dcbf0bd4071b32e5f64755403c8073490aff2a536d442df36"},
2+
"autumn": {:hex, :autumn, "0.5.7", "f6bfdc30d3f8d5e82ba5648489db7a7b6b7479d7be07a8288d4db2437434e26d", [: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", "d272bfddeeea863420a8eb994d42af219ca5391191dd765bf045fbacf56a28d1"},
33
"bandit": {:hex, :bandit, "1.5.7", "6856b1e1df4f2b0cb3df1377eab7891bec2da6a7fd69dc78594ad3e152363a50", [:mix], [{:hpax, "~> 1.0.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "f2dd92ae87d2cbea2fa9aa1652db157b6cba6c405cb44d4f6dd87abba41371cd"},
4-
"castore": {:hex, :castore, "1.0.15", "8aa930c890fe18b6fe0a0cff27b27d0d4d231867897bd23ea772dee561f032a3", [:mix], [], "hexpm", "96ce4c69d7d5d7a0761420ef743e2f4096253931a3ba69e5ff8ef1844fe446d3"},
4+
"castore": {:hex, :castore, "1.0.17", "4f9770d2d45fbd91dcf6bd404cf64e7e58fed04fadda0923dc32acca0badffa2", [:mix], [], "hexpm", "12d24b9d80b910dd3953e165636d68f147a31db945d2dcb9365e441f8b5351e5"},
55
"date_time_parser": {:hex, :date_time_parser, "1.2.0", "3d5a816b91967f51e0f94dcb16a34b2cb780f22cd48931779e81d72f7d3eadb1", [:mix], [{:kday, "~> 1.0", [hex: :kday, repo: "hexpm", optional: false]}], "hexpm", "0cf09ada9f42c0b3bfba02dc0ea2e4b4d2f543d9d2bf99b831a29e6b4a4160e5"},
66
"earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"},
77
"ex_doc": {:hex, :ex_doc, "0.37.3", "f7816881a443cd77872b7d6118e8a55f547f49903aef8747dbcb345a75b462f9", [:mix], [{:earmark_parser, "~> 1.4.42", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "e6aebca7156e7c29b5da4daa17f6361205b2ae5f26e5c7d8ca0d3f7e18972233"},
@@ -15,14 +15,14 @@
1515
"makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"},
1616
"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"},
1717
"makeup_erlang": {:hex, :makeup_erlang, "1.0.2", "03e1804074b3aa64d5fad7aa64601ed0fb395337b982d9bcf04029d68d51b6a7", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "af33ff7ef368d5893e4a267933e7744e46ce3cf1f61e2dccf53a111ed3aa3727"},
18-
"mdex": {:hex, :mdex, "0.9.2", "d70e0a9116105733d7999cbbfcb52823b6e6a4b02174205f0d0815cb1ed68dd4", [:mix], [{:autumn, ">= 0.5.4", [hex: :autumn, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:rustler, "~> 0.32", [hex: :rustler, repo: "hexpm", optional: false]}, {:rustler_precompiled, "~> 0.7", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}], "hexpm", "d5a3371ec939141d971ed500bdbf3a23a22a91df80753356b256ec13dfadfd13"},
18+
"mdex": {:hex, :mdex, "0.10.0", "eae4d3bd4c0b77d6d959146a2d6faaec045686548ad1468630130095dbd93def", [:mix], [{:autumn, ">= 0.5.4", [hex: :autumn, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, 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]}, {:rustler, "~> 0.32", [hex: :rustler, repo: "hexpm", optional: false]}, {:rustler_precompiled, "~> 0.7", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}], "hexpm", "6ad76e32056c44027fe985da7da506e033b07037896d1f130f7d5c332b0d0ac0"},
1919
"mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"},
2020
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
2121
"nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"},
2222
"plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"},
2323
"plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"},
2424
"rustler": {:hex, :rustler, "0.37.1", "721434020c7f6f8e1cdc57f44f75c490435b01de96384f8ccb96043f12e8a7e0", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "24547e9b8640cf00e6a2071acb710f3e12ce0346692e45098d84d45cdb54fd79"},
25-
"rustler_precompiled": {:hex, :rustler_precompiled, "0.8.3", "4e741024b0b097fe783add06e53ae9a6f23ddc78df1010f215df0c02915ef5a8", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:rustler, "~> 0.23", [hex: :rustler, repo: "hexpm", optional: true]}], "hexpm", "c23f5f33cb6608542de4d04faf0f0291458c352a4648e4d28d17ee1098cddcc4"},
25+
"rustler_precompiled": {:hex, :rustler_precompiled, "0.8.4", "700a878312acfac79fb6c572bb8b57f5aae05fe1cf70d34b5974850bbf2c05bf", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:rustler, "~> 0.23", [hex: :rustler, repo: "hexpm", optional: true]}], "hexpm", "3b33d99b540b15f142ba47944f7a163a25069f6d608783c321029bc1ffb09514"},
2626
"schematic": {:hex, :schematic, "0.5.1", "be4b2c03115d5a593459c11a7249a6fbb45855947d9653e9250455dcd7df1d42", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "02f913c97e6e04ccdaa02004679a7a16bb16fe0449583ad647e296d8e8961546"},
2727
"slugify": {:hex, :slugify, "1.3.1", "0d3b8b7e5c1eeaa960e44dce94382bee34a39b3ea239293e457a9c5b47cc6fd3", [:mix], [], "hexpm", "cb090bbeb056b312da3125e681d98933a360a70d327820e4b7f91645c4d8be76"},
2828
"styler": {:hex, :styler, "1.1.1", "ccb55763316915b5de532bf14c587c211ddc86bc749ac676e74dfacd3894cc0d", [:mix], [], "hexpm", "80ce12fb862e13d998589eea7c1932f4e6ce9d6ded2182cb322f8f9b2b8d3632"},

0 commit comments

Comments
 (0)