logo

auto_linker

AutoLinker-shim, based on https://git.pleroma.social/pleroma/auto_linker
commit: 0b0c75cab3e34177309e7e9735b9e00ed293edf8
parent: a95a6aa9fd80cda12f2ad1c5228fa8ad3c4c0d41
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Wed, 27 Feb 2019 05:56:01 +0100

Stash

Diffstat:

Mlib/auto_linker.ex6+++---
Mlib/auto_linker/builder.ex44++------------------------------------------
Mlib/auto_linker/parser.ex19+++++--------------
Mtest/auto_linker_test.exs11+++--------
Mtest/parser_test.exs28+++++++++++-----------------
5 files changed, 24 insertions(+), 84 deletions(-)

diff --git a/lib/auto_linker.ex b/lib/auto_linker.ex @@ -7,13 +7,13 @@ defmodule AutoLinker do ## Examples - iex> AutoLinker.link("google.com") + iex> AutoLinker.link("http://google.com") ~s(<a href="http://google.com" class="auto-linker" target="_blank" rel="noopener noreferrer">http://google.com</a>) - iex> AutoLinker.link("google.com", new_window: false, rel: false) + iex> AutoLinker.link("http://google.com", new_window: false, rel: false) ~s(<a href="http://google.com" class="auto-linker">http://google.com</a>) - iex> AutoLinker.link("google.com", new_window: false, rel: false, class: false) + iex> AutoLinker.link("http://google.com", new_window: false, rel: false, class: false) ~s(<a href="http://google.com">http://google.com</a>) iex> AutoLinker.link("[Google](http://google.com)", markdown: true, new_window: false, rel: false, class: false) diff --git a/lib/auto_linker/builder.ex b/lib/auto_linker/builder.ex @@ -6,15 +6,13 @@ defmodule AutoLinker.Builder do @doc """ Create a link. """ - def create_link(text, opts) do - url = add_scheme(text) - + def create_link(url, opts) do [] |> build_attrs(url, opts, :rel) |> build_attrs(url, opts, :target) |> build_attrs(url, opts, :class) |> build_attrs(url, opts, :href) - |> format_url(text, opts) + |> format_url(url, opts) end def create_markdown_links(text, opts) do @@ -48,16 +46,7 @@ defmodule AutoLinker.Builder do [{:href, url} | attrs] end - defp add_scheme("http://" <> _ = url), do: url - defp add_scheme("https://" <> _ = url), do: url - defp add_scheme(url), do: "http://" <> url - defp format_url(attrs, url, opts) do - url = - url - |> strip_prefix(Map.get(opts, :strip_prefix, false)) - |> truncate(Map.get(opts, :truncate, false)) - attrs = format_attrs(attrs) "<a #{attrs}>#{url}</a>" end @@ -78,21 +67,6 @@ 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 - - defp strip_prefix(url, true) do - url - |> String.replace(~r/^https?:\/\//, "") - |> String.replace(~r/^www\./, "") - end - - defp strip_prefix(url, _), do: url - def create_phone_link([], buffer, _), do: buffer def create_phone_link([h | t], buffer, opts) do @@ -154,15 +128,6 @@ defmodule AutoLinker.Builder do |> format_email(email, opts) end - def create_extra_link(uri, opts) do - [] - |> build_attrs(uri, opts, :class) - |> build_attrs(uri, opts, :rel) - |> build_attrs(uri, opts, :target) - |> build_attrs(uri, opts, :href) - |> format_extra(uri, opts) - end - def format_mention(attrs, name, _opts) do attrs = format_attrs(attrs) "<a #{attrs}>@#{name}</a>" @@ -178,11 +143,6 @@ defmodule AutoLinker.Builder do ~s(<a #{attrs}>#{email}</a>) end - def format_extra(attrs, uri, _opts) do - attrs = format_attrs(attrs) - ~s(<a #{attrs}>#{uri}</a>) - end - defp format_attributes(attrs) do Enum.reduce(attrs, "", fn {name, value}, acc -> acc <> ~s' #{name}="#{value}"' diff --git a/lib/auto_linker/parser.ex b/lib/auto_linker/parser.ex @@ -12,17 +12,8 @@ defmodule AutoLinker.Parser do ## Examples - iex> AutoLinker.Parser.parse("Check out google.com") - ~s{Check out <a href="http://google.com" class="auto-linker" target="_blank" rel="noopener noreferrer">google.com</a>} - - iex> AutoLinker.Parser.parse("call me at x9999", phone: true) - ~s{call me at <a href="#" class="phone-number" data-phone="9999">x9999</a>} - - iex> AutoLinker.Parser.parse("or at home on 555.555.5555", phone: true) - ~s{or at home on <a href="#" class="phone-number" data-phone="5555555555">555.555.5555</a>} - - iex> AutoLinker.Parser.parse(", work (555) 555-5555", phone: true) - ~s{, work <a href="#" class="phone-number" data-phone="5555555555">(555) 555-5555</a>} + iex> AutoLinker.Parser.parse("Check out http://google.com/") + ~s{Check out <a href="http://google.com" class="auto-linker" target="_blank" rel="noopener noreferrer">http://google.com</a>} """ @valid_url ~r/[0-9a-z+\-\.]+:[0-9a-z$-_.+!*'(),]+/ui @@ -263,15 +254,15 @@ defmodule AutoLinker.Parser do # @doc false def is_url?(buffer, _) do - is_url(buffer) + is_url?(buffer) end def is_url?(buffer) do - Regex.match?(@valid_url, buffer) + is_prefixed_url?(buffer, ["http://", "https://", "xmpp:", "mailto:"]) end def is_prefixed_url?(buffer, prefixes) do - is_url?(buffer) and String.starts_with?(buffer, prefixes) + Regex.match?(@valid_url, buffer) and String.starts_with?(buffer, prefixes) end def is_email?(buffer) do diff --git a/test/auto_linker_test.exs b/test/auto_linker_test.exs @@ -2,13 +2,8 @@ defmodule AutoLinkerTest do use ExUnit.Case, async: true doctest AutoLinker - test "phone number" do - assert AutoLinker.link(", work (555) 555-5555", phone: true) == - ~s{, work <a href="#" class="phone-number" data-phone="5555555555">(555) 555-5555</a>} - end - test "default link" do - assert AutoLinker.link("google.com") == + assert AutoLinker.link("http://google.com") == "<a href=\"http://google.com\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">google.com</a>" end @@ -193,10 +188,10 @@ defmodule AutoLinkerTest do end test "do not turn urls with hashes into hashtags" do - text = "google.com#test #test google.com/#test #tag" + text = "#test http://google.com/#test #tag" expected = - "<a href=\"http://google.com#test\">google.com#test</a> <a href=\"https://example.com/tag/test\">#test</a> <a href=\"http://google.com/#test\">google.com/#test</a> <a href=\"https://example.com/tag/tag\">#tag</a>" + "<a href=\"https://example.com/tag/test\">#test</a> <a href=\"http://google.com/#test\">google.com/#test</a> <a href=\"https://example.com/tag/tag\">#tag</a>" assert AutoLinker.link(text, scheme: true, diff --git a/test/parser_test.exs b/test/parser_test.exs @@ -19,16 +19,9 @@ defmodule AutoLinker.ParserTest do end) end - test "valid non-scheme" do + test "treats non-scheme as invalid" do valid_non_scheme_urls() |> Enum.each(fn url -> - assert is_url?(url) - end) - end - - test "invalid non-scheme" do - invalid_non_scheme_urls() - |> Enum.each(fn url -> refute is_url?(url) end) end @@ -52,34 +45,34 @@ defmodule AutoLinker.ParserTest do describe "parse" do test "handle line breakes" do - text = "google.com\r\nssss" + text = "http://google.com\r\nssss" expected = - "<a href=\"http://google.com\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">google.com</a>\r\nssss" + "<a href=\"http://google.com\" class=\"auto-linker\" target=\"_blank\" rel=\"noopener noreferrer\">http://google.com</a>\r\nssss" assert parse(text) == expected end test "does not link attributes" do - text = "Check out <a href='google.com'>google</a>" + text = "Check out <a href='http://google.com'>http://google</a>" assert parse(text) == text - text = "Check out <img src='google.com' alt='google.com'/>" + text = "Check out <img src='http://google.com' alt='http://google.com'/>" assert parse(text) == text - text = "Check out <span><img src='google.com' alt='google.com'/></span>" + text = "Check out <span><img src='http://google.com' alt='http://google.com'/></span>" assert parse(text) == text end test "links url inside html" do - text = "Check out <div class='section'>google.com</div>" + text = "Check out <div class='section'>http://google.com</div>" expected = - "Check out <div class='section'><a href=\"http://google.com\">google.com</a></div>" + "Check out <div class='section'><a href=\"http://google.com\">http://google.com</a></div>" 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'>google.com</div>```" + text = "```Check out <div class='section'>http://google.com</div>```" assert parse(text, exclude_patterns: ["```"]) == text end end @@ -105,7 +98,8 @@ defmodule AutoLinker.ParserTest do def invalid_scheme_urls, do: [ - "http://invalid.com/perl.cgi?key= | http://web-site.com/cgi-bin/perl.cgi?key1=value1&key2" + "2019:02:27", + "2a01:e0a:d6:9930::35" ] def valid_non_scheme_urls,