Skip to content

Commit bf032c3

Browse files
committed
Use List.key*/*, re-organize tests
keyfind/keystore didn't really improve things that much, so using keytake/prepend as originally suggested
1 parent 0d9ad85 commit bf032c3

File tree

2 files changed

+85
-35
lines changed

2 files changed

+85
-35
lines changed

lib/ex_doc/markdown/earmark.ex

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -82,34 +82,35 @@ defmodule ExDoc.Markdown.Earmark do
8282
blockquote_meta}
8383
)
8484
when tag in ["h3", "h4"] do
85-
{h_classes, h_attrs} = Enum.split_with(h_attrs, &match?({"class", _}, &1))
86-
8785
h_admonition =
88-
with [{"class", classes}] <- h_classes,
86+
with {{"class", classes}, attrs} <- List.keytake(h_attrs, "class", 0),
8987
class_list <- String.split(classes),
9088
adm_classes = [_ | _] <- Enum.filter(class_list, &(&1 in @admonition_classes)) do
91-
{Enum.join(adm_classes, " "), classes}
89+
{"admonition " <> Enum.join(adm_classes, " "),
90+
[{"class", "admonition-title #{classes}"} | attrs]}
9291
else
93-
[] -> nil
92+
_ -> nil
9493
end
9594

96-
blockquote_attrs_fn = fn admonition_classes ->
97-
case Enum.split_with(blockquote_attrs, &match?({"class", _}, &1)) do
98-
{[], attrs} ->
99-
[{"class", admonition_classes}, {"role", "note"} | attrs]
95+
section_attrs_fn = fn admonition_classes ->
96+
{classes, attrs} =
97+
case List.keytake(blockquote_attrs, "class", 0) do
98+
nil ->
99+
{admonition_classes, blockquote_attrs}
100100

101-
{[{"class", classes}], attrs} ->
102-
classes = String.trim_trailing(classes) <> " #{admonition_classes}"
103-
[{"class", classes}, {"role", "note"} | attrs]
104-
end
101+
{{"class", classes}, attrs} ->
102+
{"#{admonition_classes} #{classes}", attrs}
103+
end
104+
105+
[{"role", "note"}, {"class", classes} | attrs]
105106
end
106107

107108
if h_admonition do
108-
{h_admonition_classes, h_classes} = h_admonition
109-
blockquote_attrs = blockquote_attrs_fn.("admonition #{h_admonition_classes}")
110-
h_elem = {tag, [{"class", "admonition-title #{h_classes}"} | h_attrs], h_content, h_meta}
109+
{admonition_classes, h_attrs} = h_admonition
110+
section_attrs = section_attrs_fn.(admonition_classes)
111+
h_elem = {tag, h_attrs, h_content, h_meta}
111112

112-
fixup({"section", blockquote_attrs, [h_elem | rest], blockquote_meta})
113+
fixup({"section", section_attrs, [h_elem | rest], blockquote_meta})
113114
else
114115
# regular blockquote, copied fixup/1 here to avoid infinite loop
115116
{:blockquote, Enum.map(blockquote_attrs, &fixup_attr/1), fixup(ast), blockquote_meta}

test/ex_doc/markdown/earmark_test.exs

Lines changed: 67 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -75,20 +75,7 @@ defmodule ExDoc.Markdown.EarmarkTest do
7575
]
7676
end
7777

78-
test "converts blockquote admonitions to regular divs" do
79-
info = """
80-
> #### Info {: .info .ignore}
81-
> This is info.
82-
"""
83-
84-
assert Markdown.to_ast(info, []) == [
85-
{:section, [class: "admonition info", role: "note"],
86-
[
87-
{:h4, [class: "admonition-title ignore info"], ["Info"], %{}},
88-
{:p, [], ["This is info."], %{}}
89-
], %{}}
90-
]
91-
78+
test "leaves blockquotes with the wrong markup as is" do
9279
not_admonition = """
9380
> ### H3 {: .xyz}
9481
> This is NOT an admonition!
@@ -102,18 +89,80 @@ defmodule ExDoc.Markdown.EarmarkTest do
10289
], %{}}
10390
]
10491

92+
no_h_tag_beginning = """
93+
> {: .warning}
94+
> #### Warning {: .warning}
95+
> This blockquote didn't start with the h4 tag, so it wasn't converted.
96+
"""
97+
98+
assert Markdown.to_ast(no_h_tag_beginning, []) == [
99+
{:blockquote, [],
100+
[
101+
{:p, [], ["{: .warning}"], %{}},
102+
{:h4, [class: "warning"], ["Warning"], %{}},
103+
{:p, [],
104+
["This blockquote didn't start with the h4 tag, so it wasn't converted."], %{}}
105+
], %{}}
106+
]
107+
end
108+
109+
test "converts blockquotes with the appropriate markup to admonition sections" do
110+
info = """
111+
> #### Info {: .info .ignore}
112+
> This is info.
113+
"""
114+
115+
assert [
116+
{:section, section_attrs,
117+
[
118+
{:h4, h_attrs, ["Info"], %{}},
119+
{:p, [], ["This is info."], %{}}
120+
], %{}}
121+
] = Markdown.to_ast(info, [])
122+
123+
assert section_attrs[:role] == "note"
124+
assert section_attrs[:class] == "admonition info"
125+
126+
assert h_attrs[:class] == "admonition-title ignore info"
127+
105128
warning_error = """
106129
> ### Warning! Error! {: .warning .error}
107130
> A warning and an error.
108131
"""
109132

110-
assert Markdown.to_ast(warning_error, []) == [
111-
{:section, [class: "admonition error warning", role: "note"],
133+
assert [
134+
{:section, section_attrs,
112135
[
113-
{:h3, [class: "admonition-title error warning"], ["Warning! Error!"], %{}},
136+
{:h3, h_attrs, ["Warning! Error!"], %{}},
114137
{:p, [], ["A warning and an error."], %{}}
115138
], %{}}
116-
]
139+
] = Markdown.to_ast(warning_error, [])
140+
141+
assert section_attrs[:role] == "note"
142+
assert section_attrs[:class] == "admonition error warning"
143+
144+
assert h_attrs[:class] == "admonition-title error warning"
145+
146+
with_blockquote_level_attrs = """
147+
> ### Eggs and baskets {: .tip}
148+
> Don't put all your eggs in one basket, especially if they're golden.
149+
{: .egg-basket-bg #egg-basket-tip}
150+
"""
151+
152+
assert [
153+
{:section, section_attrs,
154+
[
155+
{:h3, h_attrs, ["Eggs and baskets"], %{}},
156+
{:p, [],
157+
["Don't put all your eggs in one basket, especially if they're golden."], %{}}
158+
], %{}}
159+
] = Markdown.to_ast(with_blockquote_level_attrs, [])
160+
161+
assert section_attrs[:role] == "note"
162+
assert section_attrs[:class] == "admonition tip egg-basket-bg"
163+
assert section_attrs[:id] == "egg-basket-tip"
164+
165+
assert h_attrs[:class] == "admonition-title tip"
117166
end
118167

119168
test "keeps math syntax without interpreting math as markdown" do

0 commit comments

Comments
 (0)