logo

auto_linker

AutoLinker-shim, based on https://git.pleroma.social/pleroma/auto_linker
commit: 86afaf49e5eceaaa2b2b72f1e290eeb6236ca020
parent 4764e1819e67774f063b9d19542d4611de654d09
Author: rinpatch <rinpatch@sdf.org>
Date:   Tue,  6 Oct 2020 19:39:23 +0000

Merge branch 'fix/hashtag-link-parsing' into 'master'

Handle hashtags followed by skipped html tags (a, pre, code)

Closes #22

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

Diffstat:

MCHANGELOG.md4++++
Mlib/linkify/parser.ex19+++++++++++++++++++
Mtest/linkify_test.exs55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Hashtags followed by HTML tags "a", "code" and "pre" were not detected + ## 0.2.0 - 2020-07-21 ### Added diff --git a/lib/linkify/parser.ex b/lib/linkify/parser.ex @@ -22,6 +22,8 @@ defmodule Linkify.Parser do @match_hashtag ~r/^(?<tag>\#[[:word:]_]*[[:alpha:]_·][[:word:]_·\p{M}]*)/u + @match_skipped_tag ~r/^(?<tag>(a|code|pre)).*>*/ + @prefix_extra [ "magnet:?", "dweb://", @@ -84,6 +86,23 @@ defmodule Linkify.Parser do defp do_parse({"@" <> text, user_acc}, opts, {buffer, acc, :skip}), do: do_parse({text, user_acc}, opts, {"", accumulate(acc, buffer, "@"), :skip}) + defp do_parse( + {"<" <> text, user_acc}, + %{hashtag: true} = opts, + {"#" <> _ = buffer, acc, :parsing} + ) do + {buffer, user_acc} = link(buffer, opts, user_acc) + + case Regex.run(@match_skipped_tag, text, capture: [:tag]) do + [tag] -> + text = String.trim_leading(text, tag) + do_parse({text, user_acc}, opts, {"", accumulate(acc, buffer, "<#{tag}"), :skip}) + + nil -> + do_parse({text, user_acc}, opts, {"<", acc, {:open, 1}}) + end + end + defp do_parse({"<a" <> text, user_acc}, opts, {buffer, acc, :parsing}), do: do_parse({text, user_acc}, opts, {"", accumulate(acc, buffer, "<a"), :skip}) diff --git a/test/linkify_test.exs b/test/linkify_test.exs @@ -178,6 +178,61 @@ defmodule LinkifyTest do "<a href=\"https://example.com/user/hello\">#hello</a> <a href=\"https://example.com/user/world\">#world</a>" assert MapSet.to_list(tags) == ["#hello", "#world"] + + text = "#cofe <br><a href=\"https://pleroma.social/\">Source</a>" + + {_result_text, %{tags: tags}} = + Linkify.link_map(text, %{tags: MapSet.new()}, + hashtag: true, + hashtag_handler: handler, + hashtag_prefix: "https://example.com/tag/" + ) + + assert MapSet.to_list(tags) == ["#cofe"] + + text = "#cofe<br><a href=\"https://pleroma.social/\">Source</a>" + + {_result_text, %{tags: tags}} = + Linkify.link_map(text, %{tags: MapSet.new()}, + hashtag: true, + hashtag_handler: handler, + hashtag_prefix: "https://example.com/tag/" + ) + + assert MapSet.to_list(tags) == ["#cofe"] + + text = "#cofe<a href=\"https://pleroma.social/\">Source</a>" + + {_result_text, %{tags: tags}} = + Linkify.link_map(text, %{tags: MapSet.new()}, + hashtag: true, + hashtag_handler: handler, + hashtag_prefix: "https://example.com/tag/" + ) + + assert MapSet.to_list(tags) == ["#cofe"] + + text = "#cofe<code>fetch()</code>" + + {_result_text, %{tags: tags}} = + Linkify.link_map(text, %{tags: MapSet.new()}, + hashtag: true, + hashtag_handler: handler, + hashtag_prefix: "https://example.com/tag/" + ) + + assert MapSet.to_list(tags) == ["#cofe"] + + text = "#cofe<pre>fetch()</pre>" + + {_result_text, %{tags: tags}} = + Linkify.link_map(text, %{tags: MapSet.new()}, + hashtag: true, + hashtag_handler: handler, + hashtag_prefix: "https://example.com/tag/" + ) + + assert MapSet.to_list(tags) == ["#cofe"] end test "mention handler and hashtag prefix" do