Skip to content

Commit 208ecbb

Browse files
committed
Allow unknown groups to be handled
1 parent 8c11a7a commit 208ecbb

File tree

5 files changed

+50
-39
lines changed

5 files changed

+50
-39
lines changed

lib/ex_doc/formatter/html.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ defmodule ExDoc.Formatter.HTML do
383383
if ids_count[extra.id] > 1, do: {disambiguate_id(extra, idx), idx + 1}, else: {extra, idx}
384384
end)
385385
|> elem(0)
386-
|> Enum.sort_by(fn extra -> GroupMatcher.group_index(groups, extra.group) end)
386+
|> Enum.sort_by(fn extra -> GroupMatcher.index(groups, extra.group) end)
387387
end
388388

389389
def generate_redirects(config, ext) do

lib/ex_doc/formatter/html/templates.ex

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,13 +203,12 @@ defmodule ExDoc.Formatter.HTML.Templates do
203203
end
204204

205205
def module_summary(module_node) do
206-
entries = docs_groups(module_node.docs_groups, module_node.docs ++ module_node.typespecs)
207-
208-
Enum.reject(entries, fn {_type, nodes} -> nodes == [] end)
209-
end
210-
211-
defp docs_groups(groups, docs) do
212-
for group <- groups, do: {group, Enum.filter(docs, &(&1.group == group))}
206+
# TODO: Maybe it should be moved to retriever and it already returned grouped metadata
207+
ExDoc.GroupMatcher.group_by(
208+
module_node.docs_groups,
209+
module_node.docs ++ module_node.typespecs,
210+
& &1.group
211+
)
213212
end
214213

215214
defp logo_path(%{logo: nil}), do: nil

lib/ex_doc/group_matcher.ex

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,32 @@ defmodule ExDoc.GroupMatcher do
88
@doc """
99
Finds the index of a given group.
1010
"""
11-
def group_index(groups, group) do
11+
def index(groups, group) do
1212
Enum.find_index(groups, fn {k, _v} -> k == group end) || -1
1313
end
1414

15+
@doc """
16+
Group the following entries and while preserving the order in `groups`.
17+
"""
18+
def group_by(groups, entries, by) do
19+
entries = Enum.group_by(entries, by)
20+
21+
{groups, leftovers} =
22+
Enum.flat_map_reduce(groups, entries, fn group, grouped_nodes ->
23+
case Map.pop(grouped_nodes, group, []) do
24+
{[], grouped_nodes} -> {[], grouped_nodes}
25+
{entries, grouped_nodes} -> {[{group, entries}], grouped_nodes}
26+
end
27+
end)
28+
29+
groups ++ Enum.sort(leftovers)
30+
end
31+
1532
@doc """
1633
Finds a matching group for the given function.
1734
"""
18-
@spec match_function(group_patterns, map) :: atom() | nil
19-
def match_function(group_patterns, metadata) do
35+
@spec match_doc(group_patterns, map) :: atom() | nil
36+
def match_doc(group_patterns, metadata) do
2037
match_group_patterns(group_patterns, fn pattern -> pattern.(metadata) end)
2138
end
2239

lib/ex_doc/retriever.ex

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ defmodule ExDoc.Retriever do
6969

7070
defp sort_modules(modules, config) when is_list(modules) do
7171
Enum.sort_by(modules, fn module ->
72-
{GroupMatcher.group_index(config.groups_for_modules, module.group), module.nested_context,
72+
{GroupMatcher.index(config.groups_for_modules, module.group), module.nested_context,
7373
module.nested_title, module.id}
7474
end)
7575
end
@@ -135,21 +135,14 @@ defmodule ExDoc.Retriever do
135135
{doc_line, doc_file, format, source_doc, doc, metadata} = get_module_docs(module_data, source)
136136

137137
# TODO: The default function groups must be returned by the language
138-
groups_for_docs =
139-
config.groups_for_docs ++
140-
[
141-
Types: &(&1[:kind] in [:type, :opaque, :nominal]),
142-
Callbacks: &(&1[:kind] in [:callback, :macrocallback]),
143-
Functions: fn _ -> true end
144-
]
145-
138+
groups_for_docs = config.groups_for_docs
146139
annotations_for_docs = config.annotations_for_docs
147140

148-
docs_groups = Enum.map(groups_for_docs, &elem(&1, 0)) |> Enum.uniq()
149-
function_docs = get_docs(module_data, source, groups_for_docs, annotations_for_docs)
141+
docs_groups =
142+
Enum.uniq(Enum.map(groups_for_docs, &elem(&1, 0)) ++ [:Types, :Callbacks, :Functions])
150143

151144
docs =
152-
function_docs ++
145+
get_docs(module_data, source, groups_for_docs, annotations_for_docs) ++
153146
get_callbacks(module_data, source, groups_for_docs, annotations_for_docs)
154147

155148
types = get_types(module_data, source, groups_for_docs, annotations_for_docs)
@@ -259,7 +252,7 @@ defmodule ExDoc.Retriever do
259252
(source_doc && doc_ast(content_type, source_doc, file: doc_file, line: doc_line + 1)) ||
260253
function_data.doc_fallback.()
261254

262-
group = GroupMatcher.match_function(groups_for_docs, metadata)
255+
group = GroupMatcher.match_doc(groups_for_docs, metadata) || :Functions
263256

264257
%ExDoc.FunctionNode{
265258
id: nil_or_name(name, arity),
@@ -342,11 +335,7 @@ defmodule ExDoc.Retriever do
342335
doc_ast(content_type, source_doc, file: doc_file, line: doc_line + 1) ||
343336
doc_fallback(callback_data)
344337

345-
group =
346-
GroupMatcher.match_function(
347-
groups_for_docs,
348-
metadata
349-
)
338+
group = GroupMatcher.match_doc(groups_for_docs, metadata) || :Callbacks
350339

351340
%ExDoc.FunctionNode{
352341
id: "c:" <> nil_or_name(name, arity),
@@ -403,11 +392,7 @@ defmodule ExDoc.Retriever do
403392
doc_ast(content_type, source_doc, file: doc_file, line: doc_line + 1) ||
404393
doc_fallback(type_data)
405394

406-
group =
407-
GroupMatcher.match_function(
408-
groups_for_docs,
409-
metadata
410-
)
395+
group = GroupMatcher.match_doc(groups_for_docs, metadata) || :Types
411396

412397
%ExDoc.TypeNode{
413398
id: "t:" <> nil_or_name(name, arity),

test/ex_doc/group_matcher_test.exs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,18 @@ defmodule ExDoc.GroupMatcherTest do
22
use ExUnit.Case, async: true
33
import ExDoc.GroupMatcher
44

5+
describe "group_by" do
6+
test "group by given data with leftovers" do
7+
assert group_by([1, 3, 5], [%{key: 1}, %{key: 3}, %{key: 2}], & &1.key) == [
8+
{1, [%{key: 1}]},
9+
{3, [%{key: 3}]},
10+
{2, [%{key: 2}]}
11+
]
12+
end
13+
end
14+
515
describe "module matching" do
6-
test "match modules by their atom names" do
16+
test "by atom names" do
717
patterns = [
818
Group: [MyApp.SomeModule, :lists]
919
]
@@ -22,7 +32,7 @@ defmodule ExDoc.GroupMatcherTest do
2232
nil
2333
end
2434

25-
test "match modules by their string names" do
35+
test "by string names" do
2636
patterns = [
2737
Group: ["MyApp.SomeModule", ":lists"]
2838
]
@@ -36,7 +46,7 @@ defmodule ExDoc.GroupMatcherTest do
3646
nil
3747
end
3848

39-
test "match modules by regular expressions" do
49+
test "by regular expressions" do
4050
patterns = [
4151
Group: ~r/MyApp\..?/
4252
]
@@ -53,7 +63,7 @@ defmodule ExDoc.GroupMatcherTest do
5363
end
5464

5565
describe "extras matching" do
56-
test "it can match extra files by their string names" do
66+
test "by string names" do
5767
patterns = [
5868
Group: ["docs/handling/testing.md"]
5969
]
@@ -62,7 +72,7 @@ defmodule ExDoc.GroupMatcherTest do
6272
assert match_extra(patterns, "docs/handling/setup.md") == nil
6373
end
6474

65-
test "it can match extra files by regular expressions" do
75+
test "by regular expressions" do
6676
patterns = [
6777
Group: ~r/docs\/handling?/
6878
]

0 commit comments

Comments
 (0)