Packages
earmark
1.4.7
1.5.0-pre1
retired
1.5.0-pre
retired
1.4.49
retired
1.4.48
retired
1.4.47
retired
1.4.46
retired
1.4.45
retired
1.4.44
retired
1.4.43
retired
1.4.42
retired
1.4.41
retired
1.4.40
retired
1.4.39
retired
1.4.38
retired
1.4.37
retired
1.4.36
retired
1.4.35
retired
1.4.34
retired
1.4.33
retired
1.4.32
retired
1.4.31
retired
1.4.30
retired
1.4.29
retired
1.4.28
retired
1.4.27
retired
1.4.26
retired
1.4.25
retired
1.4.24
retired
1.4.23
retired
1.4.22
retired
1.4.21
retired
1.4.20
retired
1.4.19
retired
1.4.18
retired
1.4.17
retired
1.4.16
retired
1.4.16-pre2
retired
1.4.16-pre1
retired
1.4.16-pre
retired
1.4.15
retired
1.4.14
retired
1.4.13
retired
1.4.12
retired
1.4.10
retired
1.4.9
retired
1.4.8
retired
1.4.7
retired
1.4.6
retired
1.4.5
retired
1.4.4
retired
1.4.3
retired
1.4.2
retired
1.4.1
retired
1.4.0
retired
1.3.6
retired
1.3.5
retired
1.3.4
retired
1.3.3
retired
1.3.2
retired
1.3.1
retired
1.3.0
retired
1.2.6
retired
1.2.5
retired
1.2.4
retired
1.2.3
retired
1.2.2
retired
1.2.1
retired
1.2.0
retired
1.1.1
retired
1.1.0
retired
1.0.3
retired
1.0.2
retired
1.0.1
retired
1.0.0
retired
0.2.1
retired
0.2.0
retired
0.1.19
retired
0.1.18
retired
0.1.17
retired
0.1.16
retired
0.1.15
retired
0.1.14
retired
0.1.13
retired
0.1.12
retired
0.1.10
retired
0.1.9
retired
0.1.8
retired
0.1.7
retired
0.1.6
retired
0.1.5
retired
0.1.4
retired
0.1.3
retired
0.1.2
retired
0.1.1
retired
0.1.0
retired
Earmark is a pure-Elixir Markdown converter. It is intended to be used as a library (just call Earmark.as_html), but can also be used as a command-line tool (run mix escript.build first). Output generation is pluggable.
Retired package: Deprecated - Earmark is no longer maintained. Migrate to a replacement, for example MDEx (https://hex.pm/packages/mdex).
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/earmark/helpers/pure_link_helpers.ex
defmodule Earmark.Helpers.PureLinkHelpers do
@moduledoc false
import Earmark.Helpers.StringHelpers, only: [betail: 2]
import Earmark.Helpers.AstHelpers, only: [render_link: 2]
@pure_link_rgx ~r{\A(\s*)(\()?(https?://[[:alnum:]"'*@:+-_{\}()/.%\#]*)}u
def convert_pure_link(src) do
case Regex.run(@pure_link_rgx, src) do
[_match, spaces, "", link_text] -> reparse_link(String.length(spaces), link_text, 0)
[_match, spaces, _, link_text] -> remove_trailing_closing_parens(String.length(spaces), link_text)
_ -> nil
end
end
defp determine_ending_parens_by_count(leading_spaces_count, prefix, surplus_on_closing_parens) do
graphemes = String.graphemes(prefix)
open_parens_count = Enum.count(graphemes, &(&1 == "("))
close_parens_count = Enum.count(graphemes, &(&1 == ")"))
delta = open_parens_count - close_parens_count
take = min(delta, surplus_on_closing_parens)
needed =
:lists.duplicate(max(0, take), ")")
|> Enum.join
{link(prefix <> needed), String.length(prefix) + leading_spaces_count + max(0,take)}
end
@split_at_ending_parens ~r{(.*?)(\)*)\z}
defp remove_trailing_closing_parens(leading_spaces_count, link_text) do
[_, _prefix, suffix] = Regex.run(@split_at_ending_parens, link_text)
case suffix do
"" -> {"(", leading_spaces_count + 1}
_ -> case convert_pure_link(betail(link_text, 1)) do
{link, length} -> {["(", link, ")"], length + 2}
_ -> nil
end
end
end
defp reparse_link(leading_spaces_count, link_text, open_count) do
[_, prefix, suffix] = Regex.run(@split_at_ending_parens, link_text)
nof_closing_parens = String.length(suffix)
if nof_closing_parens >= open_count do
determine_ending_parens_by_count(leading_spaces_count, prefix, nof_closing_parens - open_count)
end
end
defp link(text), do: render_link(text, text)
end