Skip to content

Commit

Permalink
Add before_closing_body_tag mfa support (#1670)
Browse files Browse the repository at this point in the history
  • Loading branch information
yordis authored Mar 6, 2023
1 parent 1e73873 commit a62675e
Show file tree
Hide file tree
Showing 14 changed files with 120 additions and 11 deletions.
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,18 +215,57 @@ ExDoc renders Markdown content for you, but you can extend it to render complex
```elixir
docs: [
# ...
before_closing_head_tag: &before_closing_head_tag/1,
before_closing_body_tag: &before_closing_body_tag/1
]
# ...
defp before_closing_head_tag(:html) do
"""
<!-- HTML injected at the end of the <head> element -->
"""
end
defp before_closing_head_tag(:epub), do: ""
defp before_closing_body_tag(:html) do
"""
<!-- HTML injected at the end of the <body> element -->
"""
end
defp before_closing_body_tag(_), do: ""
defp before_closing_body_tag(:epub), do: ""
```

You could use `MFA` as well:

```elixir
docs: [
# ...
before_closing_head_tag: {MyModule, :before_closing_head_tag, ["Demo"]},
before_closing_body_tag: {MyModule, :before_closing_body_tag, ["Demo"]}
]
# ...
defmodule MyModule do
def before_closing_head_tag(:html, name) do
# ...
end
def before_closing_head_tag(:epub, name) do
# ...
end
def before_closing_body_tag(:html, name) do
# ...
end
def before_closing_body_tag(:html, name) do
# ...
end
end
```

### Rendering Math
Expand Down
4 changes: 2 additions & 2 deletions lib/ex_doc/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ defmodule ExDoc.Config do
apps: [atom()],
assets: nil | String.t(),
authors: nil | [String.t()],
before_closing_body_tag: (atom() -> String.t()),
before_closing_head_tag: (atom() -> String.t()),
before_closing_body_tag: (atom() -> String.t()) | mfa(),
before_closing_head_tag: (atom() -> String.t()) | mfa(),
canonical: nil | String.t(),
cover: nil | Path.t(),
deps: [{ebin_path :: String.t(), doc_url :: String.t()}],
Expand Down
2 changes: 2 additions & 0 deletions lib/ex_doc/formatter/epub/templates.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ defmodule ExDoc.Formatter.EPUB.Templates do

require EEx

import ExDoc.Utils, only: [before_closing_body_tag: 2, before_closing_head_tag: 2]

alias ExDoc.Formatter.HTML
alias ExDoc.Formatter.HTML.Templates, as: H

Expand Down
2 changes: 1 addition & 1 deletion lib/ex_doc/formatter/epub/templates/extra_template.eex
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
</h1>
<%= content %>
<%# Extra content specified by the user (e.g. custom Javascript) %>
<%= config.before_closing_body_tag.(:epub) %>
<%= before_closing_body_tag(config, :epub) %>
</body>
</html>
2 changes: 1 addition & 1 deletion lib/ex_doc/formatter/epub/templates/head_template.eex
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
href="<%= H.asset_rev "#{config.output}/OEBPS", "dist/epub-#{config.proglang}-*.css" %>" />
<script src="<%= H.asset_rev "#{config.output}/OEBPS", "dist/epub-*.js" %>"></script>
<%# Extra content specified by the user (e.g. custom CSS) %>
<%= config.before_closing_head_tag.(:epub) %>
<%= before_closing_head_tag(config, :epub) %>
</head>
<body class="content-inner">
2 changes: 1 addition & 1 deletion lib/ex_doc/formatter/epub/templates/module_template.eex
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@
</section>
<% end %>
<%# Extra content specified by the user (e.g. custom Javascript) %>
<%= config.before_closing_body_tag.(:epub) %>
<%= before_closing_body_tag(config, :epub) %>
</body>
</html>
2 changes: 1 addition & 1 deletion lib/ex_doc/formatter/epub/templates/nav_template.eex
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
</ol>
</nav>
<%# Extra content specified by the user (e.g. custom Javascript) %>
<%= config.before_closing_body_tag.(:epub) %>
<%= before_closing_body_tag(config, :epub) %>
</body>
</html>
2 changes: 1 addition & 1 deletion lib/ex_doc/formatter/epub/templates/title_template.eex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
<% end %>
</div>
<%# Extra content specified by the user (e.g. custom Javascript) %>
<%= config.before_closing_body_tag.(:epub) %>
<%= before_closing_body_tag(config, :epub) %>
</body>
</html>
2 changes: 1 addition & 1 deletion lib/ex_doc/formatter/html/templates.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule ExDoc.Formatter.HTML.Templates do
@moduledoc false
require EEx

import ExDoc.Utils, only: [h: 1]
import ExDoc.Utils, only: [h: 1, before_closing_body_tag: 2, before_closing_head_tag: 2]

# TODO: It should not depend on the parent module. Move required HTML functions to Utils.
# TODO: Add tests that assert on the returned structured, not on JSON
Expand Down
2 changes: 1 addition & 1 deletion lib/ex_doc/formatter/html/templates/footer_template.eex
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@
</section>
</div>
<%# Extra content specified by the user (e.g. custom Javascript) %>
<%= config.before_closing_body_tag.(:html) %>
<%= before_closing_body_tag(config, :html) %>
</body>
</html>
2 changes: 1 addition & 1 deletion lib/ex_doc/formatter/html/templates/head_template.eex
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<% end %>
<script async src="<%= asset_rev config.output, "dist/html-*.js" %>"></script>
<%# Extra content specified by the user (e.g. custom CSS) %>
<%= config.before_closing_head_tag.(:html) %>
<%= before_closing_head_tag(config, :html) %>
</head>
<body data-type="<%= sidebar_type(page.type) %>" class="page-<%= page.type %>">
<script>
Expand Down
22 changes: 22 additions & 0 deletions lib/ex_doc/utils.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
defmodule ExDoc.Utils do
@moduledoc false

@doc """
Runs the `before_closing_head_tag` callback.
"""
def before_closing_head_tag(%{before_closing_head_tag: {m, f, a}}, module) do
apply(m, f, [module | a])
end

def before_closing_head_tag(%{before_closing_head_tag: before_closing_head_tag}, module) do
before_closing_head_tag.(module)
end

@doc """
Runs the `before_closing_body_tag` callback.
"""
def before_closing_body_tag(%{before_closing_body_tag: {m, f, a}}, module) do
apply(m, f, [module | a])
end

def before_closing_body_tag(%{before_closing_body_tag: before_closing_body_tag}, module) do
before_closing_body_tag.(module)
end

@doc """
HTML escapes the given string.
Expand Down
22 changes: 22 additions & 0 deletions test/ex_doc/formatter/epub_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ defmodule ExDoc.Formatter.EPUBTest do
defp before_closing_head_tag(:epub), do: @before_closing_head_tag_content_epub
defp before_closing_body_tag(:epub), do: @before_closing_body_tag_content_epub

def before_closing_head_tag(:epub, name), do: "<meta name=#{name}>"
def before_closing_body_tag(:epub, name), do: "<p>#{name}</p>"

defp doc_config(%{tmp_dir: tmp_dir} = _context) do
[
app: :elixir,
Expand Down Expand Up @@ -188,6 +191,25 @@ defmodule ExDoc.Formatter.EPUBTest do
end
end

test "before_closing_*_tags required by the user are in the right place using MFA",
%{tmp_dir: tmp_dir} = context do
generate_docs_and_unzip(
context,
doc_config(context,
before_closing_head_tag: {__MODULE__, :before_closing_head_tag, ["Demo"]},
before_closing_body_tag: {__MODULE__, :before_closing_body_tag, ["Demo"]}
)
)

oebps_dir = tmp_dir <> "/epub/OEBPS"

for basename <- @example_basenames do
content = File.read!(Path.join(oebps_dir, basename))
assert content =~ ~r[<meta name=Demo>\s*</head>]
assert content =~ ~r[<p>Demo</p>\s*</body>]
end
end

test "assets required by the user end up in the right place", %{tmp_dir: tmp_dir} = context do
File.mkdir_p!("test/tmp/epub_assets/hello")
File.touch!("test/tmp/epub_assets/hello/world.png")
Expand Down
24 changes: 24 additions & 0 deletions test/ex_doc/formatter/html_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ defmodule ExDoc.Formatter.HTMLTest do
defp before_closing_head_tag(:html), do: @before_closing_head_tag_content_html
defp before_closing_body_tag(:html), do: @before_closing_body_tag_content_html

def before_closing_head_tag(:html, name), do: "<meta name=#{name}>"
def before_closing_body_tag(:html, name), do: "<p>#{name}</p>"

defp doc_config(%{tmp_dir: tmp_dir} = _context) do
[
apps: [:elixir],
Expand Down Expand Up @@ -548,6 +551,27 @@ defmodule ExDoc.Formatter.HTMLTest do
%{
tmp_dir: tmp_dir
} = context do
generate_docs(
doc_config(context,
before_closing_head_tag: {__MODULE__, :before_closing_head_tag, ["Demo"]},
before_closing_body_tag: {__MODULE__, :before_closing_body_tag, ["Demo"]},
extras: ["test/fixtures/README.md"]
)
)

content = File.read!(tmp_dir <> "/html/api-reference.html")
assert content =~ ~r[<meta name=Demo>\s*</head>]
assert content =~ ~r[<p>Demo</p>\s*</body>]

content = File.read!(tmp_dir <> "/html/readme.html")
assert content =~ ~r[<meta name=Demo>\s*</head>]
assert content =~ ~r[<p>Demo</p>\s*</body>]
end

test "before_closing_*_tags required by the user are placed in the right place using MFA",
%{
tmp_dir: tmp_dir
} = context do
generate_docs(
doc_config(context,
before_closing_head_tag: &before_closing_head_tag/1,
Expand Down

0 comments on commit a62675e

Please sign in to comment.