Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add compact_output option #394

Merged
merged 1 commit into from
Nov 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions lib/earmark.ex
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,10 @@ defmodule Earmark do
Pure links of the form `~r{\\bhttps?://\\S+\\b}` are rendered as links from now on.
However, by setting the `pure_links` option to `false` this can be disabled and pre 1.4
behavior can be used.

* `compact_output`: boolean

If set to true, no cosmetic newlines will be emitted by Earmark. False by default.
"""
def as_html(lines, options \\ %Options{})

Expand Down
3 changes: 2 additions & 1 deletion lib/earmark/options.ex
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ defmodule Earmark.Options do
line: 1,
# [{:error|:warning, lnb, text},...]
messages: [],
pure_links: true
pure_links: true,
compact_output: false

@type t :: %__MODULE__{
breaks: boolean,
Expand Down
21 changes: 12 additions & 9 deletions lib/earmark/transform.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@ defmodule Earmark.Transform do
end


defp maybe_add_newline(%{compact_output: true}), do: []
defp maybe_add_newline(_), do: ?\n

defp to_html(ast, options) do
_to_html(ast, options, Map.get(options, :initial_indent, 0))|> IO.iodata_to_binary
end

defp _to_html(ast, options, level, verbatim \\ false)
defp _to_html({:comment, _, content, _}, _options, _level, _verbatim) do
"<!--#{content |> Enum.intersperse("\n")}-->\n"
defp _to_html({:comment, _, content, _}, options, _level, _verbatim) do
["<!--", Enum.intersperse(content, ?\n), "-->", maybe_add_newline(options)]
end
defp _to_html({"code", atts, children, meta}, options, level, _verbatim) do
verbatim = meta |> Map.get(:verbatim, false)
Expand All @@ -44,10 +47,10 @@ defmodule Earmark.Transform do
[open_tag(tag, atts),
children
|> Enum.map(&_to_html(&1, options, level, verbatim)),
"</#{tag}>"]
"</", tag, ?>]
end
defp _to_html({tag, atts, _, _}, options, level, _verbatim) when tag in @void_elements do
[ make_indent(options, level), open_tag(tag, atts), "\n" ]
[ make_indent(options, level), open_tag(tag, atts), maybe_add_newline(options) ]
end
defp _to_html(elements, options, level, verbatim) when is_list(elements) do
elements
Expand All @@ -64,19 +67,19 @@ defmodule Earmark.Transform do
[ make_indent(options, level),
open_tag("pre", atts),
_to_html(children, Map.put(options, :smartypants, false), level, verbatim),
"</pre>\n"]
"</pre>", maybe_add_newline(options)]
end
defp _to_html({tag, atts, children, meta}, options, level, _verbatim) do
verbatim = meta |> Map.get(:verbatim, false)
[ make_indent(options, level),
open_tag(tag, atts),
"\n",
maybe_add_newline(options),
_to_html(children, options, level+1, verbatim),
close_tag(tag, options, level)]
end

defp close_tag(tag, options, level) do
[make_indent(options, level), "</", tag, ">\n"]
[make_indent(options, level), "</", tag, ?>, maybe_add_newline(options)]
end

defp escape(element, options)
Expand All @@ -101,10 +104,10 @@ defmodule Earmark.Transform do

defp open_tag(tag, atts)
defp open_tag(tag, atts) when tag in @void_elements do
["<", "#{tag}", Enum.map(atts, &make_att(&1, tag)), " />"]
[?<, tag, Enum.map(atts, &make_att(&1, tag)), " />"]
end
defp open_tag(tag, atts) do
["<", "#{tag}", Enum.map(atts, &make_att(&1, tag)), ">"]
[?<, tag, Enum.map(atts, &make_att(&1, tag)), ?>]
end

@em_dash_rgx ~r{---}
Expand Down
22 changes: 22 additions & 0 deletions test/acceptance/html/compact_output_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule Acceptance.Html.CompactModeTest do
use Support.AcceptanceTestCase

describe "Compact output option" do
test "avoids creating newlines" do
markdown = "# h1\n## h2\n### h3\n\n**bold** text *italics*\n>blockquote\n1. list element\n2. list element \n\n `code` [link](http://example.com)"
{:ok, html, _} = as_html(markdown, compact_output: true)
refute html =~ "\n"
end
test "preserves newlines in code blocks" do
markdown = """
```elixir
Earmark.as_html!(markdown, compact_output: true)
Earmark.as_html!(markdown, compact_output: false)
```
"""
expected = "<pre><code class=\"elixir\"> Earmark.as_html!(markdown, compact_output: true)\n Earmark.as_html!(markdown, compact_output: false)</code></pre>"
{:ok, html, _} = as_html(markdown, compact_output: true)
assert html == expected
end
end
end