alias Pleroma.Web.MediaProxy
@safe_mention_regex ~r/^(\s*(?<mentions>@.+?\s+)+)(?<rest>.*)/
+ @link_regex ~r"((?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~%:/?#[\]@!\$&'\(\)\*\+,;=.]+)|[0-9a-z+\-\.]+:[0-9a-z$-_.+!*'(),]+"ui
@markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/
- @link_regex ~r{((?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~%:/?#[\]@!\$&'\(\)\*\+,;=.]+)|[0-9a-z+\-\.]+:[0-9a-z$-_.+!*'(),]+}ui
- # credo:disable-for-previous-line Credo.Check.Readability.MaxLineLength
@auto_linker_config hashtag: true,
hashtag_handler: &Pleroma.Formatter.hashtag_handler/4,
mention: true,
mention_handler: &Pleroma.Formatter.mention_handler/4
+ def escape_mention_handler("@" <> nickname = mention, buffer, _, _) do
+ case User.get_cached_by_nickname(nickname) do
+ %User{} ->
+ # escape markdown characters with `\\`
+ # (we don't want something like @user__name to be parsed by markdown)
+ String.replace(mention, @markdown_characters_regex, "\\\\\\1")
+
+ _ ->
+ buffer
+ end
+ end
+
def mention_handler("@" <> nickname, buffer, opts, acc) do
case User.get_cached_by_nickname(nickname) do
%User{id: id} = user ->
ap_id = get_ap_id(user)
- nickname_text = get_nickname_text(nickname, opts) |> maybe_escape(opts)
+ nickname_text = get_nickname_text(nickname, opts)
link =
"<span class='h-card'><a data-user='#{id}' class='u-url mention' href='#{ap_id}'>@<span>#{
end
end
+ @doc """
+ Escapes a special characters in mention names.
+ """
+ def mentions_escape(text, options \\ []) do
+ options =
+ Keyword.merge(options,
+ mention: true,
+ url: false,
+ mention_handler: &Pleroma.Formatter.escape_mention_handler/4
+ )
+
+ if options[:safe_mention] && Regex.named_captures(@safe_mention_regex, text) do
+ %{"mentions" => mentions, "rest" => rest} = Regex.named_captures(@safe_mention_regex, text)
+ AutoLinker.link(mentions, options) <> AutoLinker.link(rest, options)
+ else
+ AutoLinker.link(text, options)
+ end
+ end
+
def emojify(text) do
emojify(text, Emoji.get_all())
end
defp get_nickname_text(nickname, %{mentions_format: :full}), do: User.full_nickname(nickname)
defp get_nickname_text(nickname, _), do: User.local_nickname(nickname)
-
- defp maybe_escape(str, %{mentions_escape: true}) do
- String.replace(str, @markdown_characters_regex, "\\\\\\1")
- end
-
- defp maybe_escape(str, _), do: str
end
Formatting text to markdown.
"""
def format_input(text, "text/markdown", options) do
- options = Keyword.put(options, :mentions_escape, true)
-
text
+ |> Formatter.mentions_escape(options)
+ |> Earmark.as_html!()
|> Formatter.linkify(options)
- |> (fn {text, mentions, tags} -> {Earmark.as_html!(text), mentions, tags} end).()
|> Formatter.html_escape("text/html")
end
%{
"accept": {:hex, :accept, "0.3.5", "b33b127abca7cc948bbe6caa4c263369abf1347cfa9d8e699c6d214660f10cd1", [:rebar3], [], "hexpm"},
- "auto_linker": {:git, "https://git.pleroma.social/pleroma/auto_linker.git", "479dd343f4e563ff91215c8275f3b5c67e032850", [ref: "479dd343f4e563ff91215c8275f3b5c67e032850"]},
+ "auto_linker": {:git, "https://git.pleroma.social/pleroma/auto_linker.git", "90613b4bae875a3610c275b7056b61ffdd53210d", [ref: "90613b4bae875a3610c275b7056b61ffdd53210d"]},
"base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"},
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
"cachex": {:hex, :cachex, "3.0.2", "1351caa4e26e29f7d7ec1d29b53d6013f0447630bbf382b4fb5d5bad0209f203", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm"},