Skip to content

Commit a59e346

Browse files
committed
Add grouping of modules
1 parent cf155aa commit a59e346

File tree

7 files changed

+67
-6
lines changed

7 files changed

+67
-6
lines changed

lib/ex_doc.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ defmodule ExDoc do
4242
language: @default.language,
4343
logo: nil,
4444
main: nil,
45+
module_groups: [],
4546
output: @default.output,
4647
project: nil,
4748
retriever: @default.retriever,
@@ -70,6 +71,7 @@ defmodule ExDoc do
7071
language: String.t,
7172
logo: nil | Path.t,
7273
main: nil | String.t,
74+
module_groups: list(),
7375
output: nil | Path.t,
7476
project: nil | String.t,
7577
retriever: :atom,

lib/ex_doc/formatter/html/templates.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,9 @@ defmodule ExDoc.Formatter.HTML.Templates do
176176
|> Enum.map_join(",", &sidebar_items_by_type/1)
177177

178178
if items == "" do
179-
~s/{"id":"#{module_node.id}","title":"#{module_node.title}"}/
179+
~s/{"id":"#{module_node.id}","title":"#{module_node.title}","group":"#{module_node.group}"}/
180180
else
181-
~s/{"id":"#{module_node.id}","title":"#{module_node.title}",#{items}}/
181+
~s/{"id":"#{module_node.id}","title":"#{module_node.title}","group":"#{module_node.group}",#{items}}/
182182
end
183183
end
184184

lib/ex_doc/retriever.ex

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ defmodule ExDoc.ModuleNode do
33
Structure that represents a *module*
44
"""
55

6-
defstruct id: nil, title: nil, module: nil, doc: nil, doc_line: nil,
7-
docs: [], typespecs: [], source_path: nil, source_url: nil, type: nil
6+
defstruct id: nil, title: nil, module: nil, group: nil, doc: nil,
7+
doc_line: nil, docs: [], typespecs: [], source_path: nil,
8+
source_url: nil, type: nil
89

910
@type t :: %__MODULE__{
1011
id: nil | String.t,
1112
title: nil | String.t,
1213
module: nil | String.t,
14+
group: nil | String.t,
1315
docs: list(),
1416
doc: nil | String.t,
1517
doc_line: non_neg_integer(),
@@ -115,7 +117,7 @@ defmodule ExDoc.Retriever do
115117
modules
116118
|> Enum.map(&get_module(&1, config))
117119
|> Enum.filter(&(&1))
118-
|> Enum.sort(&(&1.id <= &2.id))
120+
|> Enum.sort_by(&({&1.group, &1.id}))
119121
end
120122

121123
defp filename_to_module(name) do
@@ -157,6 +159,7 @@ defmodule ExDoc.Retriever do
157159
end
158160

159161
defp generate_node(module, type, config) do
162+
module_group_patterns = config.module_groups
160163
source_url = config.source_url_pattern
161164
source_path = source_path(module, config)
162165
source = %{url: source_url, path: source_path}
@@ -171,10 +174,13 @@ defmodule ExDoc.Retriever do
171174

172175
{title, id} = module_title_and_id(module, type)
173176

177+
module_group = module_group(module, module_group_patterns)
178+
174179
%ExDoc.ModuleNode{
175180
id: id,
176181
title: title,
177182
module: module_info.name,
183+
group: module_group,
178184
type: type,
179185
docs: docs,
180186
doc: moduledoc,
@@ -458,6 +464,25 @@ defmodule ExDoc.Retriever do
458464
{id, id}
459465
end
460466

467+
defp module_group(module, group_patterns) do
468+
Enum.find_value(group_patterns, fn {group, patterns} ->
469+
patterns = List.wrap patterns
470+
module_in_patterns(module, patterns) && Atom.to_string(group)
471+
end)
472+
end
473+
474+
defp module_in_patterns(module, patterns) do
475+
"Elixir." <> module_string = Atom.to_string module
476+
477+
Enum.any?(patterns, fn pattern ->
478+
case pattern do
479+
%Regex{} = regex -> Regex.match?(regex, module_string)
480+
string when is_binary(string) -> module_string === string
481+
atom -> atom === module
482+
end
483+
end)
484+
end
485+
461486
defp module_id(module) do
462487
case inspect(module) do
463488
":" <> inspected -> inspected

test/ex_doc/retriever_test.exs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,15 @@ defmodule ExDoc.RetrieverTest do
55

66
defp docs_from_files(names, url_pattern \\ "http://example.com/%{path}#L%{line}") do
77
files = Enum.map names, fn(n) -> "test/tmp/Elixir.#{n}.beam" end
8-
config = %ExDoc.Config{source_url_pattern: url_pattern, source_root: File.cwd!}
8+
config = %ExDoc.Config{
9+
source_url_pattern: url_pattern,
10+
source_root: File.cwd!,
11+
module_groups: [
12+
"Group Atom": [GroupedExplicitlyAtom],
13+
"Group String": ["GroupedExplicitlyString"],
14+
"Group Implicit": ~r/GroupedImplicitly.?/
15+
]
16+
}
917
Retriever.docs_from_files(files, config)
1018
end
1119

@@ -44,6 +52,23 @@ defmodule ExDoc.RetrieverTest do
4452
assert module_node.module == CompiledWithDocs
4553
end
4654

55+
describe "docs_from_files returns the group" do
56+
test "atom" do
57+
[module_node] = docs_from_files ["GroupedExplicitlyAtom"]
58+
assert module_node.group == "Group Atom"
59+
end
60+
61+
test "string" do
62+
[module_node] = docs_from_files ["GroupedExplicitlyString"]
63+
assert module_node.group == "Group String"
64+
end
65+
66+
test "regex" do
67+
[module_node] = docs_from_files ["GroupedImplicitlyRegex"]
68+
assert module_node.group == "Group Implicit"
69+
end
70+
end
71+
4772
test "docs_from_files returns the moduledoc info" do
4873
[module_node] = docs_from_files ["CompiledWithDocs"]
4974
assert module_node.doc == "moduledoc\n\n\#\# Example ☃ Unicode > escaping\n CompiledWithDocs.example\n\n### Example H3 heading\n\nexample\n"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
defmodule GroupedExplicitlyAtom do
2+
@moduledoc false
3+
end
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
defmodule GroupedExplicitlyString do
2+
@moduledoc false
3+
end
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
defmodule GroupedImplicitlyRegex do
2+
@moduledoc false
3+
end

0 commit comments

Comments
 (0)