diff --git a/README.md b/README.md index 27baba34b..58463a987 100644 --- a/README.md +++ b/README.md @@ -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 ``` diff --git a/lib/ex_doc.ex b/lib/ex_doc.ex index d5e1a8f93..37b326830 100644 --- a/lib/ex_doc.ex +++ b/lib/ex_doc.ex @@ -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 diff --git a/lib/ex_doc/cli.ex b/lib/ex_doc/cli.ex index 1bbe221f7..72e974715 100644 --- a/lib/ex_doc/cli.ex +++ b/lib/ex_doc/cli.ex @@ -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) @@ -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 @@ -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 @@ -64,7 +83,6 @@ 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: "." @@ -72,8 +90,9 @@ defmodule ExDoc.CLI do --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` diff --git a/lib/ex_doc/formatter/html.ex b/lib/ex_doc/formatter/html.ex index c534500d0..4681c411c 100644 --- a/lib/ex_doc/formatter/html.ex +++ b/lib/ex_doc/formatter/html.ex @@ -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) @@ -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 @@ -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) diff --git a/lib/ex_doc/formatter/html/templates.ex b/lib/ex_doc/formatter/html/templates.ex index fd8190ac3..ef7d41494 100644 --- a/lib/ex_doc/formatter/html/templates.ex +++ b/lib/ex_doc/formatter/html/templates.ex @@ -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: [], @@ -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], diff --git a/lib/ex_doc/formatter/html/templates/readme_template.eex b/lib/ex_doc/formatter/html/templates/extra_template.eex similarity index 71% rename from lib/ex_doc/formatter/html/templates/readme_template.eex rename to lib/ex_doc/formatter/html/templates/extra_template.eex index 759469e08..b0cc30971 100644 --- a/lib/ex_doc/formatter/html/templates/readme_template.eex +++ b/lib/ex_doc/formatter/html/templates/extra_template.eex @@ -1,4 +1,4 @@ -<%= head_template(config, %{id: :readme}) %> +<%= head_template(config, %{id: :extra}) %> <%= sidebar_template(config, modules, exceptions, protocols) %> <%= to_html(content) %> diff --git a/lib/ex_doc/formatter/html/templates/head_template.eex b/lib/ex_doc/formatter/html/templates/head_template.eex index 24bbec1ea..029d3fe2c 100644 --- a/lib/ex_doc/formatter/html/templates/head_template.eex +++ b/lib/ex_doc/formatter/html/templates/head_template.eex @@ -7,8 +7,8 @@ <%= cond do %> <%= page.id == :module -> %> <%= page.module %> – <%= config.project %> v<%= config.version %> - <%= page.id == :readme -> %> - README – <%= config.project %> v<%= config.version %> + <%= page.id == :extra -> %> + <%= config.title %> – <%= config.project %> v<%= config.version %> <%= page.id == :overview -> %> Overview – <%= config.project %> v<%= config.version %> <% end %> diff --git a/lib/ex_doc/formatter/html/templates/sidebar_template.eex b/lib/ex_doc/formatter/html/templates/sidebar_template.eex index 50339c66c..94a3c911e 100644 --- a/lib/ex_doc/formatter/html/templates/sidebar_template.eex +++ b/lib/ex_doc/formatter/html/templates/sidebar_template.eex @@ -41,8 +41,10 @@