commit: 45a252c6fa9071fabad1d23858a420e77af744b4
parent: 55debce3de6883485f77e88425dda710f5484b66
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Fri, 19 Apr 2019 18:59:06 +0200
Merge remote-tracking branch 'upstream/master' into lanodan/master
Diffstat:
5 files changed, 99 insertions(+), 20 deletions(-)
diff --git a/lib/auto_linker/builder.ex b/lib/auto_linker/builder.ex
@@ -67,6 +67,13 @@ defmodule AutoLinker.Builder do
Regex.replace(~r/\[(.+?)\]\((.+?)\)/, text, "<a href='\\2'#{attrs}>\\1</a>")
end
+ defp truncate(url, false), do: url
+ defp truncate(url, len) when len < 3, do: url
+
+ defp truncate(url, len) do
+ if String.length(url) > len, do: String.slice(url, 0, len - 2) <> "...", else: url
+ end
+
def create_phone_link([], buffer, _), do: buffer
def create_phone_link([h | t], buffer, opts) do
diff --git a/lib/auto_linker/parser.ex b/lib/auto_linker/parser.ex
@@ -109,20 +109,31 @@ defmodule AutoLinker.Parser do
defp do_parse({"", user_acc}, _opts, {"", acc, _}, _handler),
do: {acc, user_acc}
- defp do_parse({"", user_acc}, opts, {buffer, acc, _}, handler) do
- {buffer, user_acc} = run_handler(handler, buffer, opts, user_acc)
- {acc <> buffer, user_acc}
- end
-
defp do_parse({"<a" <> text, user_acc}, opts, {buffer, acc, :parsing}, handler),
do: do_parse({text, user_acc}, opts, {"", acc <> buffer <> "<a", :skip}, handler)
+ defp do_parse({"<pre" <> text, user_acc}, opts, {buffer, acc, :parsing}, handler),
+ do: do_parse({text, user_acc}, opts, {"", acc <> buffer <> "<pre", :skip}, handler)
+
+ defp do_parse({"<code" <> text, user_acc}, opts, {buffer, acc, :parsing}, handler),
+ do: do_parse({text, user_acc}, opts, {"", acc <> buffer <> "<code", :skip}, handler)
+
defp do_parse({"</a>" <> text, user_acc}, opts, {buffer, acc, :skip}, handler),
do: do_parse({text, user_acc}, opts, {"", acc <> buffer <> "</a>", :parsing}, handler)
+ defp do_parse({"</pre>" <> text, user_acc}, opts, {buffer, acc, :skip}, handler),
+ do: do_parse({text, user_acc}, opts, {"", acc <> buffer <> "</pre>", :parsing}, handler)
+
+ defp do_parse({"</code>" <> text, user_acc}, opts, {buffer, acc, :skip}, handler),
+ do: do_parse({text, user_acc}, opts, {"", acc <> buffer <> "</code>", :parsing}, handler)
+
defp do_parse({"<" <> text, user_acc}, opts, {"", acc, :parsing}, handler),
do: do_parse({text, user_acc}, opts, {"<", acc, {:open, 1}}, handler)
+ defp do_parse({"<" <> text, user_acc}, opts, {"", acc, {:html, level}}, handler) do
+ do_parse({text, user_acc}, opts, {"<", acc, {:open, level + 1}}, handler)
+ end
+
defp do_parse({">" <> text, user_acc}, opts, {buffer, acc, {:attrs, level}}, handler),
do:
do_parse(
@@ -159,19 +170,8 @@ defmodule AutoLinker.Parser do
handler
)
- defp do_parse(
- {<<char::bytes-size(1), text::binary>>, user_acc},
- opts,
- {buffer, acc, {:open, level}},
- handler
- )
- when char in [" ", "\r", "\n"] do
- do_parse(
- {text, user_acc},
- opts,
- {"", acc <> buffer <> char, {:attrs, level}},
- handler
- )
+ defp do_parse({text, user_acc}, opts, {buffer, acc, {:open, level}}, handler) do
+ do_parse({text, user_acc}, opts, {"", acc <> buffer, {:attrs, level}}, handler)
end
# default cases where state is not important
diff --git a/test/auto_linker_test.exs b/test/auto_linker_test.exs
@@ -53,6 +53,24 @@ defmodule AutoLinkerTest do
new_window: false,
rel: custom_rel
) == expected
+
+ text = "http://google.com"
+
+ expected = "<a href=\"http://google.com\">http://google.com</a>"
+
+ custom_rel = fn _ -> nil end
+
+ assert AutoLinker.link(text,
+ class: false,
+ new_window: false,
+ rel: custom_rel
+ ) == expected
+ end
+
+ test "link_map/2" do
+ assert AutoLinker.link_map("http://google.com", []) ==
+ {"<a href=\"http://google.com\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">http://google.com</a>",
+ []}
end
describe "custom handlers" do
@@ -136,6 +154,22 @@ defmodule AutoLinkerTest do
) == expected
end
+ test "mentions inside html tags" do
+ text =
+ "<p><strong>hello world</strong></p>\n<p><`em>another @user__test and @user__test http://google.com paragraph</em></p>\n"
+
+ expected =
+ "<p><strong>hello world</strong></p>\n<p><`em>another <a href=\"u/user__test\">@user__test</a> and <a href=\"u/user__test\">@user__test</a> <a href=\"http://google.com\">http://google.com</a> paragraph</em></p>\n"
+
+ assert AutoLinker.link(text,
+ mention: true,
+ mention_prefix: "u/",
+ class: false,
+ rel: false,
+ new_window: false
+ ) == expected
+ end
+
test "metion @user@example.com" do
text = "hey @user@example.com"
diff --git a/test/builder_test.exs b/test/builder_test.exs
@@ -17,6 +17,16 @@ defmodule AutoLinker.BuilderTest do
"<a href=\"http://text\" class=\"auto-linker\" target=\"_blank\" rel=\"me\">http://text</a>"
assert create_link("http://text", %{rel: "me"}) == expected
+
+ expected = "<a href=\"http://text\" class=\"auto-linker\" target=\"_blank\">http://text</a>"
+
+ assert create_link("http://text", %{truncate: 3, rel: false}) == expected
+
+ expected = "<a href=\"http://text\" class=\"auto-linker\" target=\"_blank\">http://text</a>"
+ assert create_link("http://text", %{truncate: 2, rel: false}) == expected
+
+ expected = "<a href=\"http://text\" class=\"auto-linker\" target=\"_blank\">http://text</a>"
+ assert create_link("http://text", %{rel: false, strip_prefix: false}) == expected
end
test "create_markdown_links/2" do
@@ -52,9 +62,9 @@ defmodule AutoLinker.BuilderTest do
phrase = "my exten is x888. Call me."
expected =
- ~s'my exten is <a href="#" class="phone-number" data-phone="888">x888</a>. Call me.'
+ ~s'my exten is <a href="#" class="phone-number" data-phone="888" test=\"test\">x888</a>. Call me.'
- assert create_phone_link([["x888", ""]], phrase, []) == expected
+ assert create_phone_link([["x888", ""]], phrase, attributes: [test: "test"]) == expected
end
test "handles multiple links" do
diff --git a/test/parser_test.exs b/test/parser_test.exs
@@ -62,7 +62,24 @@ defmodule AutoLinker.ParserTest do
assert parse(text) == text
end
+ test "does not link inside `<pre>` and `<code>`" do
+ text = "<pre>http://google.com</pre>"
+ assert parse(text) == text
+
+ text = "<code>http://google.com</code>"
+ assert parse(text) == text
+
+ text = "<pre><code>http://google.com</code></pre>"
+ assert parse(text) == text
+ end
+
test "links url inside html" do
+ text = "<div>http://google.com</div>"
+
+ expected = "<div><a href=\"http://google.com\">http://google.com</a></div>"
+
+ assert parse(text, class: false, rel: false, new_window: false, phone: false) == expected
+
text = "Check out <div class='section'>http://google.com</div>"
expected =
@@ -71,10 +88,21 @@ defmodule AutoLinker.ParserTest do
assert parse(text, class: false, rel: false, new_window: false) == expected
end
+ test "links url inside nested html" do
+ text = "<p><strong>http://google.com</strong></p>"
+ expected = "<p><strong><a href=\"http://google.com\">http://google.com</a></strong></p>"
+ assert parse(text, class: false, rel: false, new_window: false) == expected
+ end
+
test "excludes html with specified class" do
text = "```Check out <div class='section'>http://google.com</div>```"
assert parse(text, exclude_patterns: ["```"]) == text
end
+
+ test "do not link urls" do
+ text = "http://google.com"
+ assert parse(text, url: false, phone: true) == text
+ end
end
test "link_email/3" do