Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ def project do
name: "REPO",
source_url: "https://github.com/USER/REPO",
homepage_url: "http://YOUR_PROJECT_HOMEPAGE",
logo: "path/to/logo.png",
deps: deps]
deps: deps,
docs: [logo: "path/to/logo.png",
extras: ["README.md", "CONTRIBUTING.md"]]]
end
```

Expand Down
7 changes: 4 additions & 3 deletions lib/ex_doc.ex
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
defmodule ExDoc do
defmodule Config do
defstruct [
extras: [],
formatter: "html",
formatter_opts: [],
homepage_url: nil,
logo: nil,
main: nil,
output: "doc",
project: nil,
readme: nil,
retriever: ExDoc.Retriever,
source_beam: nil,
source_root: nil,
source_url: nil,
source_url_pattern: nil,
version: nil,
logo: nil
title: nil,
version: nil
]
end

Expand Down
27 changes: 23 additions & 4 deletions lib/ex_doc/cli.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ defmodule ExDoc.CLI do
def run(args, generator \\ &ExDoc.generate_docs/3) do
{opts, args, _} = OptionParser.parse(args,
aliases: [o: :output, f: :formatter, c: :config, r: :source_root,
u: :source_url, m: :main, p: :homepage_url])
u: :source_url, m: :main, p: :homepage_url, l: :logo,
e: :extra],
switches: [extra: :keep])

[project, version, source_beam] = parse_args(args)

Expand All @@ -16,6 +18,12 @@ defmodule ExDoc.CLI do
end

defp merge_config(opts) do
opts
|> formatter_options
|> extra_files_options
end

defp formatter_options(opts) do
case Keyword.fetch(opts, :config) do
{:ok, config} ->
opts
Expand All @@ -25,6 +33,17 @@ defmodule ExDoc.CLI do
end
end

defp extra_files_options(opts) do
extras = Keyword.get_values(opts, :extra)
if Enum.empty?(extras) do
opts
else
opts
|> Keyword.delete(:extra)
|> Keyword.put(:extras, extras)
end
end

defp read_config(path) do
config_str = case File.read(path) do
{:ok, str} -> str
Expand Down Expand Up @@ -64,16 +83,16 @@ defmodule ExDoc.CLI do
VERSION Version number
BEAMS Path to compiled beam files
-o, --output Path to output docs, default: "doc"
--readme Path to README.md file to generate a project README, default: `nil`
-f, --formatter Docs formatter to use, default: "html"
-c, --config Path to the formatter's config file
-r, --source-root Path to the source code root, default: "."
-u, --source-url URL to the source code
--source-ref Branch/commit/tag used for source link inference, default: "master"
-m, --main The main, entry-point module in docs,
default: "overview" when --formatter is "html"
-p --homepage-url URL to link to for the site name
-l --logo Path to the image logo of the project (only PNG or JPEG accepted)
-p, --homepage-url URL to link to for the site name
-e, --extra Allow users to include additional Markdown files, default: []
-l, --logo Path to the image logo of the project (only PNG or JPEG accepted)
The image size will be 64x64 when --formatter is "html"
default: `nil`

Expand Down
44 changes: 28 additions & 16 deletions lib/ex_doc/formatter/html.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ defmodule ExDoc.Formatter.HTML do
config = process_logo_metadata(config)
end

if config.readme do
generate_readme(output, module_nodes, config, modules, exceptions, protocols)
unless Enum.empty?(config.extras) do
generate_extras(output, module_nodes, config, modules, exceptions, protocols)
end

generate_index(output, config)
Expand Down Expand Up @@ -89,9 +89,32 @@ defmodule ExDoc.Formatter.HTML do
end
end

defp generate_readme(output, module_nodes, config, modules, exceptions, protocols) do
readme_path = Path.expand(config.readme)
write_readme(output, File.read(readme_path), module_nodes, config, modules, exceptions, protocols)
defp generate_extras(output, module_nodes, config, modules, exceptions, protocols) do
config.extras
|> Enum.map(&Task.async(fn -> generate_extra(&1, output, module_nodes, config, modules, exceptions, protocols) end))
|> Enum.map(&Task.await/1)
end

defp generate_extra(input, output, module_nodes, config, modules, exceptions, protocols) do
file_path = Path.expand(input)
file_extname =
Path.extname(file_path)
|> String.downcase

if file_extname == ".md" do
file_name =
Path.basename(file_path, ".md")
|> String.upcase
content =
File.read!(file_path)
|> Autolink.project_doc(module_nodes)

config = Map.put(config, :title, file_name)
extra_html = Templates.extra_template(config, modules, exceptions, protocols, content) |> pretty_codeblocks
File.write!("#{output}/#{file_name}.html", extra_html)
else
raise ArgumentError, "file format not recognized, allowed format is: .md"
end
end

defp process_logo_metadata(config) do
Expand All @@ -109,17 +132,6 @@ defmodule ExDoc.Formatter.HTML do
end
end

defp write_readme(output, {:ok, content}, module_nodes, config, modules, exceptions, protocols) do
content = Autolink.project_doc(content, module_nodes)
readme_html = Templates.readme_template(config, modules, exceptions, protocols, content) |> pretty_codeblocks
:ok = File.write("#{output}/README.html", readme_html)
true
end

defp write_readme(_, _, _, _, _, _, _) do
false
end

defp generate_redirect(output, file_name, config, redirect_to) do
content = Templates.redirect_template(config, redirect_to)
:ok = File.write("#{output}/#{file_name}", content)
Expand Down
4 changes: 3 additions & 1 deletion lib/ex_doc/formatter/html/templates.ex
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ defmodule ExDoc.Formatter.HTML.Templates do
defp logo_path(%{logo: nil}), do: nil
defp logo_path(%{logo: logo}), do: "assets/logo#{Path.extname(logo)}"

defp extra_title(path), do: path |> String.upcase |> Path.basename(".MD")

templates = [
detail_template: [:node, :_module],
footer_template: [],
Expand All @@ -118,7 +120,7 @@ defmodule ExDoc.Formatter.HTML.Templates do
not_found_template: [:config, :modules, :exceptions, :protocols],
overview_entry_template: [:node],
overview_template: [:config, :modules, :exceptions, :protocols],
readme_template: [:config, :modules, :exceptions, :protocols, :content],
extra_template: [:config, :modules, :exceptions, :protocols, :content],
sidebar_template: [:config, :modules, :exceptions, :protocols],
summary_template: [:node],
type_detail_template: [:node, :_module],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<%= head_template(config, %{id: :readme}) %>
<%= head_template(config, %{id: :extra}) %>
<%= sidebar_template(config, modules, exceptions, protocols) %>

<%= to_html(content) %>
Expand Down
4 changes: 2 additions & 2 deletions lib/ex_doc/formatter/html/templates/head_template.eex
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<%= cond do %>
<%= page.id == :module -> %>
<title><%= page.module %> – <%= config.project %> v<%= config.version %></title>
<%= page.id == :readme -> %>
<title>README – <%= config.project %> v<%= config.version %></title>
<%= page.id == :extra -> %>
<title><%= config.title %> – <%= config.project %> v<%= config.version %></title>
<%= page.id == :overview -> %>
<title>Overview – <%= config.project %> v<%= config.version %></title>
<% end %>
Expand Down
6 changes: 4 additions & 2 deletions lib/ex_doc/formatter/html/templates/sidebar_template.eex
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@
</div>

<ul class="sidebar-mainNav">
<%= if config.readme do %>
<li><a href="README.html">README</a></li>
<%= unless Enum.empty?(config.extras) do %>
<%= for extra <- Enum.sort(config.extras) do %>
<li><a href="<%= extra_title(extra) %>.html"><%= extra_title(extra) %></a></li>
<%= end %>
<% end %>

<li><a href="overview.html">Overview</a></li>
Expand Down
6 changes: 3 additions & 3 deletions lib/mix/tasks/docs.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ defmodule Mix.Tasks.Docs do
* `:output` - output directory for the generated docs; default: "doc".
May be overriden by command line argument.

* `:readme` - string denoting the source file for a project README
(e.g., "README.md"); default: `nil` (no README created).

* `:formatter` - doc formatter to use; default: "html".

* `:source_root` - path to the source code root directory;
Expand All @@ -47,6 +44,9 @@ defmodule Mix.Tasks.Docs do

* `:logo` - Path to the image logo of the project (only PNG or JPEG accepted)
The image size will be 64x64 when --formatter is "html".

* `:extras` - List of strings, each one must indicate the path to additional
Markdown pages (e.g. `["README.md", "CONTRIBUTING.md"]`); default: `[]`
"""

@doc false
Expand Down
4 changes: 2 additions & 2 deletions test/ex_doc/formatter/html/templates_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ defmodule ExDoc.Formatter.HTML.TemplatesTest do
source_root: File.cwd!,
source_url_pattern: "#{source_url}/blob/master/%{path}#L%{line}",
homepage_url: homepage_url,
source_url: source_url,
source_url: source_url
}
end

Expand Down Expand Up @@ -89,7 +89,7 @@ defmodule ExDoc.Formatter.HTML.TemplatesTest do
end

test "listing page has README link if present" do
config = Map.put(doc_config, :readme, "README.md")
config = Map.put(doc_config, :extras, ["README.md"])
content = Templates.sidebar_template(config, [], [], [])
assert content =~ ~r{<a href="README.html">README</a>}
end
Expand Down
4 changes: 2 additions & 2 deletions test/ex_doc/formatter/html_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ defmodule ExDoc.Formatter.HTMLTest do
output: "test/tmp/doc",
source_root: beam_dir,
source_beam: beam_dir,
readme: "test/tmp/README.md",
extras: ["test/tmp/README.md"]
]
end

Expand Down Expand Up @@ -151,7 +151,7 @@ defmodule ExDoc.Formatter.HTMLTest do
end

test "run should not generate the readme file" do
generate_docs(doc_config([readme: nil]))
generate_docs(doc_config([extras: []]))
refute File.regular?("#{output_dir}/README.html")
content = File.read!("#{output_dir}/index.html")
refute content =~ ~r{<title>README [^<]*</title>}
Expand Down
4 changes: 2 additions & 2 deletions test/ex_doc_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ defmodule ExDocTest do
test "command-line config" do
File.write!("test.config", ~s([key: "val"]))

{project, version, opts} = run(["ExDoc", "--readme", "README.md", "1.2.3", "...", "-c", "test.config"])
{project, version, opts} = run(["ExDoc", "--extra", "README.md", "1.2.3", "...", "-c", "test.config"])

assert project == "ExDoc"
assert version == "1.2.3"
assert Enum.sort(opts) == [formatter_opts: [key: "val"], readme: "README.md", source_beam: "..."]
assert Enum.sort(opts) == [extras: ["README.md"], formatter_opts: [key: "val"], source_beam: "..."]
after
File.rm!("test.config")
end
Expand Down