logo

auto_linker

AutoLinker-shim, based on https://git.pleroma.social/pleroma/auto_linker
commit: a08513aa7e879f056c44c5b8aea8c0fd073be5c8
parent: d3d75daff829e7b05fe87547337d4d2808436a75
Author: lain <lain@soykaf.club>
Date:   Mon, 13 Jul 2020 09:23:28 +0000

Merge branch 'mentions-fix' into 'master'

Don't parse mentions inside links

Closes pleroma/pleroma#1656

See merge request pleroma/elixir-libraries/linkify!21

Diffstat:

MREADME.md2+-
Mlib/linkify/parser.ex19++++++++++++-------
Mmix.lock16++++++++--------
Mtest/linkify_test.exs28++++++++++++++++++++++++++++
4 files changed, 49 insertions(+), 16 deletions(-)

diff --git a/README.md b/README.md @@ -35,7 +35,7 @@ iex> Linkify.link("google.com", new_window: true, rel: "noopener noreferrer") See the [Docs](https://hexdocs.pm/linkify/) for more examples -## Acknowledgements +## Acknowledgments This is a fork of [auto_linker](https://github.com/smpallen99/auto_linker) by [Steve Pallen](https://github.com/smpallen99). diff --git a/lib/linkify/parser.ex b/lib/linkify/parser.ex @@ -62,19 +62,24 @@ defmodule Linkify.Parser do def parse(input, opts) do opts = Map.merge(@default_opts, opts) - - Enum.reduce(opts, input, fn - {type, true}, input when type in @types -> - do_parse(input, opts, {"", "", :parsing}, type) - - _, input -> - input + opts_list = Map.to_list(opts) + + Enum.reduce(@types, input, fn + type, input -> + if {type, true} in opts_list do + do_parse(input, opts, {"", "", :parsing}, type) + else + input + end end) end defp do_parse({"", user_acc}, _opts, {"", acc, _}, _handler), do: {acc, user_acc} + defp do_parse({"@" <> text, user_acc}, opts, {buffer, acc, :skip}, type), + do: do_parse({text, user_acc}, opts, {"", acc <> buffer <> "@", :skip}, type) + defp do_parse({"<a" <> text, user_acc}, opts, {buffer, acc, :parsing}, type), do: do_parse({text, user_acc}, opts, {"", acc <> buffer <> "<a", :skip}, type) diff --git a/mix.lock b/mix.lock @@ -1,10 +1,10 @@ %{ - "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, - "credo": {:hex, :credo, "1.1.0", "e0c07b2fd7e2109495f582430a1bc96b2c71b7d94c59dfad120529f65f19872f", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, - "earmark": {:hex, :earmark, "1.3.2", "b840562ea3d67795ffbb5bd88940b1bed0ed9fa32834915125ea7d02e35888a5", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.20.2", "1bd0dfb0304bade58beb77f20f21ee3558cc3c753743ae0ddbb0fd7ba2912331", [:mix], [{:earmark, "~> 1.3", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, - "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, - "makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, - "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"}, + "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"}, + "credo": {:hex, :credo, "1.1.0", "e0c07b2fd7e2109495f582430a1bc96b2c71b7d94c59dfad120529f65f19872f", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7338d04b30026e30adbcaaedbf0eb7e4d749510d90c2708ff8cc100fa9c8291f"}, + "earmark": {:hex, :earmark, "1.3.2", "b840562ea3d67795ffbb5bd88940b1bed0ed9fa32834915125ea7d02e35888a5", [:mix], [], "hexpm", "e3be2bc3ae67781db529b80aa7e7c49904a988596e2dbff897425b48b3581161"}, + "ex_doc": {:hex, :ex_doc, "0.20.2", "1bd0dfb0304bade58beb77f20f21ee3558cc3c753743ae0ddbb0fd7ba2912331", [:mix], [{:earmark, "~> 1.3", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "8e24fc8ff9a50b9f557ff020d6c91a03cded7e59ac3e0eec8a27e771430c7d27"}, + "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fdf843bca858203ae1de16da2ee206f53416bbda5dc8c9e78f43243de4bc3afe"}, + "makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5fbc8e549aa9afeea2847c0769e3970537ed302f93a23ac612602e805d9d1e7f"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "adf0218695e22caeda2820eaba703fa46c91820d53813a2223413da3ef4ba515"}, + "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm", "5c040b8469c1ff1b10093d3186e2e10dbe483cd73d79ec017993fb3985b8a9b3"}, } diff --git a/test/linkify_test.exs b/test/linkify_test.exs @@ -126,6 +126,34 @@ defmodule LinkifyTest do new_window: true ) == expected end + + test "mentions handler with hostname/@user links" do + text = + "hi @user, take a look at this post: https://example.com/@valid_user/posts/9w5AkQp956XIh74apc" + + valid_users = ["user", "valid_user"] + + handler = fn "@" <> user = mention, buffer, _opts, acc -> + if Enum.member?(valid_users, user) do + link = ~s(<a href="https://example.com/user/#{user}" data-user="#{user}">#{mention}</a>) + {link, %{acc | mentions: MapSet.put(acc.mentions, {mention, user})}} + else + {buffer, acc} + end + end + + {result_text, %{mentions: mentions}} = + Linkify.link_map(text, %{mentions: MapSet.new()}, + mention: true, + mention_handler: handler, + new_window: true + ) + + assert result_text == + "hi <a href=\"https://example.com/user/user\" data-user=\"user\">@user</a>, take a look at this post: <a href=\"https://example.com/@valid_user/posts/9w5AkQp956XIh74apc\" target=\"_blank\">https://example.com/@valid_user/posts/9w5AkQp956XIh74apc</a>" + + assert mentions |> MapSet.to_list() |> Enum.map(&elem(&1, 1)) == ["user"] + end end describe "mentions" do