diff --git a/README.md b/README.md index 6d1def4..907565f 100644 --- a/README.md +++ b/README.md @@ -20,24 +20,19 @@ end The following examples illustrate some examples on how to use the auto linker. -```iex +```elixir + iex> Linkify.link("google.com") -"google.com" +"google.com" -iex> Linkify.link("google.com", new_window: false, rel: false) -"google.com" +iex> Linkify.link("google.com", class: "linkified") +"google.com" -iex> Linkify.link("google.com", new_window: false, rel: false, class: false) -"google.com" +iex> Linkify.link("google.com", new_window: true) +"google.com" -iex> Linkify.link("call me at x9999", phone: true) -"call me at x9999" - -iex> Linkify.link("or at home on 555.555.5555", phone: true) -"or at home on 555.555.5555" - -iex> Linkify.link(", work (555) 555-5555", phone: true) -", work (555) 555-5555" +iex> Linkify.link("google.com", new_window: true, rel: "noopener noreferrer") +"google.com" ``` See the [Docs](https://hexdocs.pm/linkify/) for more examples diff --git a/lib/linkify.ex b/lib/linkify.ex index 66b8b67..5a5e720 100644 --- a/lib/linkify.ex +++ b/lib/linkify.ex @@ -3,52 +3,43 @@ defmodule Linkify do Create url links from text containing urls. Turns an input string like `"Check out google.com"` into - `Check out "google.com"` + `Check out "google.com"` ## Examples iex> Linkify.link("google.com") - ~s(google.com) - - iex> Linkify.link("google.com", new_window: false, rel: false) - ~s(google.com) - - iex> Linkify.link("google.com", new_window: false, rel: false, class: false) ~s(google.com) + + iex> Linkify.link("google.com", new_window: true, rel: "noopener noreferrer") + ~s(google.com) + + iex> Linkify.link("google.com", class: "linkified") + ~s(google.com) """ import Linkify.Parser @doc """ - Auto link a string. + Finds links and turns them into HTML `` tag. Options: - * `class: "linkified"` - specify the class to be added to the generated link. false to clear - * `rel: "noopener noreferrer"` - override the rel attribute. false to clear - * `new_window: true` - set to false to remove `target='_blank'` attribute - * `truncate: false` - Set to a number to truncate urls longer then the number. Truncated urls will end in `..` - * `strip_prefix: true` - Strip the scheme prefix - * `exclude_class: false` - Set to a class name when you don't want urls auto linked in the html of the give class - * `exclude_id: false` - Set to an element id when you don't want urls auto linked in the html of the give element - * `email: false` - link email links - * `mention: false` - link @mentions (when `true`, requires `mention_prefix` or `mention_handler` options to be set) - * `mention_prefix: nil` - a prefix to build a link for a mention (example: `https://example.com/user/`) - * `mention_handler: nil` - a custom handler to validate and formart a mention + * `class` - specify the class to be added to the generated link. + * `rel` - specify the rel attribute. + * `new_window` - set to `true` to add `target="_blank"` attribute + * `truncate` - Set to a number to truncate urls longer then the number. Truncated urls will end in `...` + * `strip_prefix` - Strip the scheme prefix (default: `false`) + * `exclude_class` - Set to a class name when you don't want urls auto linked in the html of the give class (default: `false`) + * `exclude_id` - Set to an element id when you don't want urls auto linked in the html of the give element (default: `false`) + * `email` - link email links (default: `false`) + * `mention` - link @mentions (when `true`, requires `mention_prefix` or `mention_handler` options to be set) (default: `false`) + * `mention_prefix` - a prefix to build a link for a mention (example: `https://example.com/user/`, default: `nil`) + * `mention_handler` - a custom handler to validate and formart a mention (default: `nil`) * `hashtag: false` - link #hashtags (when `true`, requires `hashtag_prefix` or `hashtag_handler` options to be set) * `hashtag_prefix: nil` - a prefix to build a link for a hashtag (example: `https://example.com/tag/`) * `hashtag_handler: nil` - a custom handler to validate and formart a hashtag * `extra: false` - link urls with rarely used schemes (magnet, ipfs, irc, etc.) * `validate_tld: true` - Set to false to disable TLD validation for urls/emails, also can be set to :no_scheme to validate TLDs only for urls without a scheme (e.g `example.com` will be validated, but `http://example.loki` won't) - - Each of the above options can be specified when calling `link(text, opts)` - or can be set in the `:linkify`'s configuration. For example: - - config :linkify, - class: false, - new_window: false - - Note that passing opts to `link/2` will override the configuration settings. """ def link(text, opts \\ []) do parse(text, opts) diff --git a/lib/linkify/builder.ex b/lib/linkify/builder.ex index bab5a25..9b3f1b0 100644 --- a/lib/linkify/builder.ex +++ b/lib/linkify/builder.ex @@ -25,18 +25,18 @@ defmodule Linkify.Builder do end defp build_attrs(attrs, _, opts, :rel) do - case Map.get(opts, :rel, "noopener noreferrer") do + case Map.get(opts, :rel) do rel when is_binary(rel) -> [{:rel, rel} | attrs] _ -> attrs end end defp build_attrs(attrs, _, opts, :target) do - if Map.get(opts, :new_window, true), do: [{:target, :_blank} | attrs], else: attrs + if Map.get(opts, :new_window), do: [{:target, :_blank} | attrs], else: attrs end defp build_attrs(attrs, _, opts, :class) do - case Map.get(opts, :class, "linkified") do + case Map.get(opts, :class) do cls when is_binary(cls) -> [{:class, cls} | attrs] _ -> attrs end diff --git a/lib/linkify/parser.ex b/lib/linkify/parser.ex index 4af1f26..b86e2c4 100644 --- a/lib/linkify/parser.ex +++ b/lib/linkify/parser.ex @@ -51,7 +51,7 @@ defmodule Linkify.Parser do ## Examples iex> Linkify.Parser.parse("Check out google.com") - ~s{Check out google.com} + ~s{Check out google.com} """ @types [:url, :email, :hashtag, :mention, :extra] diff --git a/test/builder_test.exs b/test/builder_test.exs index ac3f0b1..bfcd9bb 100644 --- a/test/builder_test.exs +++ b/test/builder_test.exs @@ -5,27 +5,30 @@ defmodule Linkify.BuilderTest do import Linkify.Builder test "create_link/2" do - expected = - "text" + expected = "text" assert create_link("text", %{}) == expected - expected = "text" - assert create_link("text", %{rel: nil}) == expected + expected = "text" - expected = "text" + assert create_link("text", %{new_window: true}) == expected + + expected = "text" + assert create_link("text", %{class: "linkified"}) == expected + + expected = "text" assert create_link("text", %{rel: "me"}) == expected - expected = "t..." + expected = "t..." - assert create_link("text", %{truncate: 3, rel: false}) == expected + assert create_link("text", %{truncate: 3}) == expected - expected = "text" - assert create_link("text", %{truncate: 2, rel: false}) == expected + expected = "text" + assert create_link("text", %{truncate: 2}) == expected - expected = "http://text" - assert create_link("http://text", %{rel: false, strip_prefix: false}) == expected + expected = "http://text" + assert create_link("http://text", %{strip_prefix: false}) == expected end test "format_hashtag/3" do @@ -46,14 +49,13 @@ defmodule Linkify.BuilderTest do end test "create_mention_link/3" do - expected = - "@navi" + expected = "@navi" assert create_mention_link("@navi", "hello @navi", %{mention_prefix: "/u/"}) == expected end test "create_email_link/3" do - expected = "user@example.org" + expected = "user@example.org" assert create_email_link("user@example.org", %{}) == expected assert create_email_link("user@example.org", %{href: "mailto:user@example.org"}) == expected end diff --git a/test/linkify_test.exs b/test/linkify_test.exs index 199a2b2..c50aace 100644 --- a/test/linkify_test.exs +++ b/test/linkify_test.exs @@ -4,7 +4,7 @@ defmodule LinkifyTest do test "default link" do assert Linkify.link("google.com") == - "google.com" + "google.com" end test "does on link existing links" do @@ -20,13 +20,20 @@ defmodule LinkifyTest do assert Linkify.link(text, email: true, - extra: true, - class: false, - new_window: false, - rel: false + extra: true ) == expected end + test "class attribute" do + assert Linkify.link("google.com", class: "linkified") == + "google.com" + end + + test "rel attribute" do + assert Linkify.link("google.com", rel: "noopener noreferrer") == + "google.com" + end + test "rel as function" do text = "google.com" @@ -36,11 +43,7 @@ defmodule LinkifyTest do url |> String.split(".") |> List.last() end - assert Linkify.link(text, - class: false, - new_window: false, - rel: custom_rel - ) == expected + assert Linkify.link(text, rel: custom_rel) == expected text = "google.com" @@ -48,17 +51,12 @@ defmodule LinkifyTest do custom_rel = fn _ -> nil end - assert Linkify.link(text, - class: false, - new_window: false, - rel: custom_rel - ) == expected + assert Linkify.link(text, rel: custom_rel) == expected end test "link_map/2" do assert Linkify.link_map("google.com", []) == - {"google.com", - []} + {"google.com", []} end describe "custom handlers" do @@ -100,8 +98,6 @@ defmodule LinkifyTest do hashtag: true, hashtag_handler: handler, hashtag_prefix: "https://example.com/user/", - class: false, - new_window: false, rel: false ) @@ -120,13 +116,14 @@ defmodule LinkifyTest do end expected = - ~s(Hello again, @@user.<script></script>\nThis is on another :moominmamma: line. #2hu #epic #phantasmagoric) + ~s(Hello again, @@user.<script></script>\nThis is on another :moominmamma: line. #2hu #epic #phantasmagoric) assert Linkify.link(text, mention: true, mention_handler: handler, hashtag: true, - hashtag_prefix: "/tag/" + hashtag_prefix: "/tag/", + new_window: true ) == expected end end @@ -134,11 +131,12 @@ defmodule LinkifyTest do describe "mentions" do test "simple mentions" do expected = - ~s{hello @user and @anotherUser.} + ~s{hello @user and @anotherUser.} assert Linkify.link("hello @user and @anotherUser.", mention: true, - mention_prefix: "https://example.com/user/" + mention_prefix: "https://example.com/user/", + new_window: true ) == expected end @@ -149,24 +147,19 @@ defmodule LinkifyTest do expected = "

hello world

\n

<`em>another @user__test and @user__test google.com paragraph

\n" - assert Linkify.link(text, - mention: true, - mention_prefix: "u/", - class: false, - rel: false, - new_window: false - ) == expected + assert Linkify.link(text, mention: true, mention_prefix: "u/") == expected end test "metion @user@example.com" do text = "hey @user@example.com" expected = - "hey @user@example.com" + "hey @user@example.com" assert Linkify.link(text, mention: true, - mention_prefix: "https://example.com/user/" + mention_prefix: "https://example.com/user/", + new_window: true ) == expected end end @@ -174,11 +167,12 @@ defmodule LinkifyTest do describe "hashtag links" do test "hashtag" do expected = - " one #2two three #four." + " one #2two three #four." assert Linkify.link(" one #2two three #four.", hashtag: true, - hashtag_prefix: "https://example.com/tag/" + hashtag_prefix: "https://example.com/tag/", + new_window: true ) == expected end @@ -188,9 +182,7 @@ defmodule LinkifyTest do assert Linkify.link("#1ok #42 #7", hashtag: true, hashtag_prefix: "/t/", - class: false, - rel: false, - new_window: false + rel: false ) == expected end @@ -203,9 +195,7 @@ defmodule LinkifyTest do assert Linkify.link(text, hashtag: true, hashtag_prefix: "/t/", - class: false, - rel: false, - new_window: false + rel: false ) == expected end @@ -218,9 +208,7 @@ defmodule LinkifyTest do assert Linkify.link(text, hashtag: true, hashtag_prefix: "/t/", - class: false, - rel: false, - new_window: false + rel: false ) == expected end @@ -232,8 +220,6 @@ defmodule LinkifyTest do assert Linkify.link(text, hashtag: true, - class: false, - new_window: false, rel: false, hashtag_prefix: "https://example.com/tag/" ) == expected @@ -246,8 +232,6 @@ defmodule LinkifyTest do "#漢字 #は #тест #ทดสอบ" assert Linkify.link(text, - class: false, - new_window: false, rel: false, hashtag: true, hashtag_prefix: "https://example.com/tag/" @@ -260,73 +244,71 @@ defmodule LinkifyTest do text = "Hey, check out http://www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla ." expected = - "Hey, check out youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla ." + "Hey, check out youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla ." - assert Linkify.link(text) == expected + assert Linkify.link(text, new_window: true) == expected # no scheme text = "Hey, check out www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla ." - assert Linkify.link(text) == expected + assert Linkify.link(text, new_window: true) == expected end test "turn urls with schema into urls" do text = "📌https://google.com" expected = "📌google.com" - assert Linkify.link(text, class: false, new_window: false, rel: false) == expected + assert Linkify.link(text, rel: false) == expected end test "hostname/@user" do text = "https://example.com/@user" - expected = - "example.com/@user" + expected = "example.com/@user" - assert Linkify.link(text) == expected + assert Linkify.link(text, new_window: true) == expected text = "https://example.com:4000/@user" expected = - "example.com:4000/@user" + "example.com:4000/@user" - assert Linkify.link(text) == expected + assert Linkify.link(text, new_window: true) == expected text = "https://example.com:4000/@user" expected = - "example.com:4000/@user" + "example.com:4000/@user" - assert Linkify.link(text) == expected + assert Linkify.link(text, new_window: true) == expected text = "@username" expected = "@username" - assert Linkify.link(text) == expected + assert Linkify.link(text, new_window: true) == expected text = "http://www.cs.vu.nl/~ast/intel/" - expected = - "cs.vu.nl/~ast/intel/" + expected = "cs.vu.nl/~ast/intel/" assert Linkify.link(text) == expected text = "https://forum.zdoom.org/viewtopic.php?f=44&t=57087" expected = - "forum.zdoom.org/viewtopic.php?f=44&t=57087" + "forum.zdoom.org/viewtopic.php?f=44&t=57087" assert Linkify.link(text) == expected text = "https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul" expected = - "en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul" + "en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul" assert Linkify.link(text) == expected text = "https://en.wikipedia.org/wiki/Duff's_device" expected = - "en.wikipedia.org/wiki/Duff's_device" + "en.wikipedia.org/wiki/Duff's_device" assert Linkify.link(text) == expected end @@ -336,14 +318,14 @@ defmodule LinkifyTest do test "xmpp" do text = "xmpp:user@example.com" - expected = "xmpp:user@example.com" + expected = "xmpp:user@example.com" - assert Linkify.link(text, extra: true, new_window: false, rel: false) == expected + assert Linkify.link(text, extra: true) == expected end test "email" do text = "user@example.com" - expected = "user@example.com" + expected = "user@example.com" assert Linkify.link(text, email: true) == expected end @@ -352,9 +334,9 @@ defmodule LinkifyTest do "magnet:?xt=urn:btih:a4104a9d2f5615601c429fe8bab8177c47c05c84&dn=ubuntu-18.04.1.0-live-server-amd64.iso&tr=http%3A%2F%2Ftorrent.ubuntu.com%3A6969%2Fannounce&tr=http%3A%2F%2Fipv6.torrent.ubuntu.com%3A6969%2Fannounce" expected = - "magnet:?xt=urn:btih:a4104a9d2f5615601c429fe8bab8177c47c05c84&dn=ubuntu-18.04.1.0-live-server-amd64.iso&tr=http%3A%2F%2Ftorrent.ubuntu.com%3A6969%2Fannounce&tr=http%3A%2F%2Fipv6.torrent.ubuntu.com%3A6969%2Fannounce" + "magnet:?xt=urn:btih:a4104a9d2f5615601c429fe8bab8177c47c05c84&dn=ubuntu-18.04.1.0-live-server-amd64.iso&tr=http%3A%2F%2Ftorrent.ubuntu.com%3A6969%2Fannounce&tr=http%3A%2F%2Fipv6.torrent.ubuntu.com%3A6969%2Fannounce" - assert Linkify.link(text, extra: true, new_window: false, rel: false) == expected + assert Linkify.link(text, extra: true) == expected end test "dweb" do @@ -362,9 +344,9 @@ defmodule LinkifyTest do "dweb://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1.0.0/path/to/file.txt" expected = - "dweb://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1.0.0/path/to/file.txt" + "dweb://584faa05d394190ab1a3f0240607f9bf2b7e2bd9968830a11cf77db0cea36a21+v1.0.0/path/to/file.txt" - assert Linkify.link(text, extra: true, new_window: false, rel: false) == expected + assert Linkify.link(text, extra: true) == expected end end @@ -372,8 +354,7 @@ defmodule LinkifyTest do test "parse with scheme" do text = "https://google.com" - expected = - "google.com" + expected = "google.com" assert Linkify.link(text) == expected end @@ -387,7 +368,7 @@ defmodule LinkifyTest do text = "this url https://google.foobar.com/ has valid TLD" expected = - "this url google.foobar.com/ has valid TLD" + "this url google.foobar.com/ has valid TLD" assert Linkify.link(text) == expected end @@ -399,7 +380,7 @@ defmodule LinkifyTest do text = "this url google.foobar.com/ has valid TLD" expected = - "this url google.foobar.com/ has valid TLD" + "this url google.foobar.com/ has valid TLD" assert Linkify.link(text) == expected end @@ -408,14 +389,14 @@ defmodule LinkifyTest do text = "this url http://google.foobar.com/ has valid TLD" expected = - "this url google.foobar.com/ has valid TLD" + "this url google.foobar.com/ has valid TLD" assert Linkify.link(text) == expected text = "this url google.foobar.com/ has valid TLD" expected = - "this url google.foobar.com/ has valid TLD" + "this url google.foobar.com/ has valid TLD" assert Linkify.link(text) == expected end diff --git a/test/parser_test.exs b/test/parser_test.exs index f83531d..9b74235 100644 --- a/test/parser_test.exs +++ b/test/parser_test.exs @@ -109,9 +109,7 @@ defmodule Linkify.ParserTest do describe "parse" do test "handle line breakes" do text = "google.com\r\nssss" - - expected = - "google.com\r\nssss" + expected = "google.com\r\nssss" assert parse(text) == expected end @@ -141,20 +139,20 @@ defmodule Linkify.ParserTest do expected = "
google.com
" - assert parse(text, class: false, rel: false, new_window: false) == expected + assert parse(text, class: false, rel: false) == expected text = "Check out
google.com
" expected = "Check out
google.com
" - assert parse(text, class: false, rel: false, new_window: false) == expected + assert parse(text, class: false, rel: false) == expected end test "links url inside nested html" do text = "

google.com

" expected = "

google.com

" - assert parse(text, class: false, rel: false, new_window: false) == expected + assert parse(text, class: false, rel: false) == expected end test "do not link parens" do @@ -163,14 +161,14 @@ defmodule Linkify.ParserTest do expected = " foo (example.com/path/folder/), bar" - assert parse(text, class: false, rel: false, new_window: false, scheme: true) == expected + assert parse(text, class: false, rel: false, scheme: true) == expected text = " foo (example.com/path/folder/), bar" expected = " foo (example.com/path/folder/), bar" - assert parse(text, class: false, rel: false, new_window: false) == expected + assert parse(text, class: false, rel: false) == expected end test "do not link urls" do