Skip to content

Commit

Permalink
Use samp tags only on EPUB, closes #1062
Browse files Browse the repository at this point in the history
  • Loading branch information
José Valim committed Jul 20, 2019
1 parent 6b39170 commit 14ae130
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 29 deletions.
4 changes: 3 additions & 1 deletion lib/ex_doc/formatter/epub.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ defmodule ExDoc.Formatter.EPUB do
config = normalize_config(config)
File.rm_rf!(config.output)
File.mkdir_p!(Path.join(config.output, "OEBPS"))
{project_nodes, autolink} = HTML.autolink_and_render(project_nodes, ".xhtml", config)

{project_nodes, autolink} =
HTML.autolink_and_render(project_nodes, ".xhtml", config, highlight_tag: "samp")

nodes_map = %{
modules: HTML.filter_list(:module, project_nodes),
Expand Down
28 changes: 15 additions & 13 deletions lib/ex_doc/formatter/html.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ defmodule ExDoc.Formatter.HTML do
build = Path.join(config.output, ".build")
output_setup(build, config)

{project_nodes, autolink} = autolink_and_render(project_nodes, ".html", config)
{project_nodes, autolink} = autolink_and_render(project_nodes, ".html", config, [])
extras = build_extras(config, autolink)

# Generate search early on without api reference in extras
Expand Down Expand Up @@ -66,24 +66,26 @@ defmodule ExDoc.Formatter.HTML do
@doc """
Autolinks and renders all docs.
"""
def autolink_and_render(project_nodes, ext, config) do
def autolink_and_render(project_nodes, ext, config, opts) do
autolink = Autolink.compile(project_nodes, ext, config)
{project_nodes |> Autolink.all(autolink) |> render_docs(), autolink}
end

defp render_docs(nodes) do
for module <- nodes do
docs = Enum.map(module.docs, &render_doc/1)
typespecs = Enum.map(module.typespecs, &render_doc/1)
%{render_doc(module) | docs: docs, typespecs: typespecs}
end
rendered =
project_nodes
|> Autolink.all(autolink)
|> Enum.map(fn node ->
docs = Enum.map(node.docs, &render_doc(&1, opts))
typespecs = Enum.map(node.typespecs, &render_doc(&1, opts))
%{render_doc(node, opts) | docs: docs, typespecs: typespecs}
end)

{rendered, autolink}
end

defp render_doc(%{doc: nil} = node),
defp render_doc(%{doc: nil} = node, _opts),
do: node

defp render_doc(%{doc: doc, source_path: file, doc_line: line} = node),
do: %{node | rendered_doc: ExDoc.Markdown.to_html(doc, file: file, line: line + 1)}
defp render_doc(%{doc: doc, source_path: file, doc_line: line} = node, opts),
do: %{node | rendered_doc: ExDoc.Markdown.to_html(doc, [file: file, line: line + 1] ++ opts)}

defp output_setup(build, config) do
if File.exists?(build) do
Expand Down
14 changes: 8 additions & 6 deletions lib/ex_doc/highlighter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -34,30 +34,32 @@ defmodule ExDoc.Highlighter do
@doc """
Highlights all code block in an already generated HTML document.
"""
def highlight_code_blocks(html) do
def highlight_code_blocks(html, opts \\ []) do
Regex.replace(
~r/<pre><code(?:\s+class="(\w*)")?>([^<]*)<\/code><\/pre>/,
html,
&highlight_code_block/3
&highlight_code_block(&1, &2, &3, opts)
)
end

defp highlight_code_block(full_block, lang, code) do
defp highlight_code_block(full_block, lang, code, outer_opts) do
case pick_language_and_lexer(lang) do
{_language, nil, _opts} -> full_block
{language, lexer, opts} -> render_code(language, lexer, opts, code)
{language, lexer, opts} -> render_code(language, lexer, opts, code, outer_opts)
end
end

defp render_code(lang, lexer, lexer_opts, code) do
defp render_code(lang, lexer, lexer_opts, code, opts) do
highlight_tag = Keyword.get(opts, :highlight_tag, "span")

highlighted =
code
|> unescape_html()
|> IO.iodata_to_binary()
|> Makeup.highlight_inner_html(
lexer: lexer,
lexer_options: lexer_opts,
formatter_options: [highlight_tag: "samp"]
formatter_options: [highlight_tag: highlight_tag]
)

~s(<pre><code class="nohighlight makeup #{lang}">#{highlighted}</code></pre>)
Expand Down
10 changes: 7 additions & 3 deletions lib/ex_doc/markdown/cmark.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ defmodule ExDoc.Markdown.Cmark do
end

@doc """
Generate HTML output. Cmark takes no options.
Generate HTML output.
## Options
* `:highlight_tag` - the tag used for highlighting code, defaults to "span"
"""
def to_html(text, _opts) do
def to_html(text, opts) do
text
|> Cmark.to_html()
|> ExDoc.Highlighter.highlight_code_blocks()
|> ExDoc.Highlighter.highlight_code_blocks(opts)
end
end
8 changes: 6 additions & 2 deletions lib/ex_doc/markdown/earmark.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ defmodule ExDoc.Markdown.Earmark do
end

@doc """
Earmark specific options:
Generate HTML output.
## Options
* `:gfm` - boolean. Turns on Github Flavored Markdown extensions. True by default
Expand All @@ -35,6 +37,8 @@ defmodule ExDoc.Markdown.Earmark do
Earmark. See [Plugins](http://github.com/pragdave/earmark#plugins) for details on
how to write custom plugins.
* `:highlight_tag` - the tag used for highlighting code, defaults to "span"
"""
def to_html(text, opts) do
options =
Expand All @@ -49,6 +53,6 @@ defmodule ExDoc.Markdown.Earmark do

text
|> Earmark.as_html!(options)
|> ExDoc.Highlighter.highlight_code_blocks()
|> ExDoc.Highlighter.highlight_code_blocks(opts)
end
end
2 changes: 1 addition & 1 deletion test/ex_doc/formatter/epub/templates_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ defmodule ExDoc.Formatter.EPUB.TemplatesTest do
defp get_module_page(names, config \\ []) do
config = doc_config(config)
mods = ExDoc.Retriever.docs_from_modules(names, config)
{[mod | _], _} = HTML.autolink_and_render(mods, ".xhtml", config)
{[mod | _], _} = HTML.autolink_and_render(mods, ".xhtml", config, highlight_tag: "samp")
Templates.module_page(config, mod)
end

Expand Down
9 changes: 8 additions & 1 deletion test/ex_doc/formatter/epub_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ defmodule ExDoc.Formatter.EPUBTest do

test "generates all listing files" do
generate_docs_and_unzip(doc_config())

content = File.read!("#{output_dir()}/OEBPS/content.opf")

assert content =~ ~r{.*"CompiledWithDocs\".*}ms
Expand Down Expand Up @@ -164,6 +163,14 @@ defmodule ExDoc.Formatter.EPUBTest do
assert content =~ ~r{<li><a href="readme.xhtml">README</a></li>}
end


test "uses samp as highlight tag for markdown" do
generate_docs_and_unzip(doc_config())

assert File.read!("#{output_dir()}/OEBPS/CompiledWithDocs.xhtml") =~
"<samp class=\"nc\">CompiledWithDocs<\/samp>"
end

describe "before_closing_*_tags" do
# There are 3 possibilities for the `before_closing_*_tags`:
# - required by the user alone
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 @@ -31,7 +31,7 @@ defmodule ExDoc.Formatter.HTML.TemplatesTest do
defp get_module_page(names, config \\ []) do
config = doc_config(config)
mods = ExDoc.Retriever.docs_from_modules(names, config)
{[mod | _], _} = HTML.autolink_and_render(mods, ".html", config)
{[mod | _], _} = HTML.autolink_and_render(mods, ".html", config, [])
Templates.module_page(mod, @empty_nodes_map, config)
end

Expand Down Expand Up @@ -275,7 +275,7 @@ defmodule ExDoc.Formatter.HTML.TemplatesTest do
refute content =~ ~r{<small>module</small>}

assert content =~
~r{moduledoc.*Example.*<samp class="nc">CompiledWithDocs</samp><samp class="o">\.</samp><samp class="n">example</samp>.*}ms
~r{moduledoc.*Example.*<span class="nc">CompiledWithDocs</span><span class="o">\.</span><span class="n">example</span>.*}ms

assert content =~
~r{<h2 id="module-example-unicode-escaping" class="section-heading">.*<a href="#module-example-unicode-escaping" class="hover-link">.*<span class="icon-link" aria-hidden="true"></span>.*</a>.*Example.*</h2>}ms
Expand Down

0 comments on commit 14ae130

Please sign in to comment.