Packages
earmark
1.4.45
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_parser/helpers/pure_link_helpers.ex
defmodule Earmark.Parser.Helpers.PureLinkHelpers do
@moduledoc false
import Earmark.Parser.Helpers.AstHelpers, only: [render_link: 2]
@pure_link_rgx ~r{
\A
(\s*)
(
(?:https?://|www\.)
[^\s<>]*
[^\s<>?!.,:*_~]
)
}ux
def convert_pure_link(src) do
case Regex.run(@pure_link_rgx, src) do
[_match, spaces, link_text] ->
if String.ends_with?(link_text, ")") do
remove_trailing_closing_parens(spaces, link_text)
else
make_result(spaces, link_text)
end
_ ->
nil
end
end
@split_at_ending_parens ~r{ (.*?) (\)*) \z}x
defp remove_trailing_closing_parens(leading_spaces, link_text) do
[_, link_text, trailing_parens] = Regex.run(@split_at_ending_parens, link_text)
trailing_paren_count = String.length(trailing_parens)
# try to balance parens from the rhs
unbalanced_count = balance_parens(String.reverse(link_text), trailing_paren_count)
balanced_parens = String.slice(trailing_parens, 0, trailing_paren_count - unbalanced_count)
make_result(leading_spaces, link_text <> balanced_parens)
end
defp make_result(leading_spaces, link_text) do
link =
if String.starts_with?(link_text, "www.") do
render_link("http://" <> link_text, link_text)
else
render_link(link_text, link_text)
end
if leading_spaces == "" do
{link, String.length(link_text)}
else
{[leading_spaces, link], String.length(leading_spaces) + String.length(link_text)}
end
end
# balance parens and return unbalanced *trailing* paren count
defp balance_parens(reverse_text, trailing_count, non_trailing_count \\ 0)
defp balance_parens(<<>>, trailing_paren_count, _non_trailing_count), do: trailing_paren_count
defp balance_parens(_reverse_text, 0, _non_trailing_count), do: 0
defp balance_parens(")" <> rest, trailing_paren_count, non_trailing_count) do
balance_parens(rest, trailing_paren_count, non_trailing_count + 1)
end
defp balance_parens("(" <> rest, trailing_paren_count, non_trailing_count) do
# non-trailing paren must be balanced before trailing paren
if non_trailing_count > 0 do
balance_parens(rest, trailing_paren_count, non_trailing_count - 1)
else
balance_parens(rest, trailing_paren_count - 1, non_trailing_count)
end
end
defp balance_parens(<<_::utf8,rest::binary>>, trailing_paren_count, non_trailing_count) do
balance_parens(rest, trailing_paren_count, non_trailing_count)
end
end