Packages
earmark_parser
1.4.18
1.4.46
1.4.45
1.4.44
1.4.43
1.4.42
1.4.41
1.4.40
1.4.39
1.4.38
1.4.37
1.4.36
1.4.35
1.4.34
1.4.33
1.4.32
1.4.31
1.4.30
1.4.29
1.4.28
1.4.27
1.4.26
1.4.25
1.4.24
1.4.23
1.4.22
1.4.21
1.4.20
1.4.20-pre
1.4.19
1.4.18
1.4.17
1.4.16
1.4.16-pre2
1.4.16-pre1
1.4.16-pre
1.4.15
1.4.13
1.4.12
1.4.11
1.4.10
1.4.9
1.4.8
AST parser and generator for Markdown
Current section
Files
Jump to
Current section
Files
lib/earmark_parser/helpers/pure_link_helpers.ex
defmodule EarmarkParser.Helpers.PureLinkHelpers do
@moduledoc false
import EarmarkParser.Helpers.StringHelpers, only: [betail: 2]
import EarmarkParser.Helpers.AstHelpers, only: [render_link: 1]
@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(spaces, link_text)
[_match, spaces, _, link_text] -> remove_trailing_closing_parens(spaces, link_text)
_ -> nil
end
end
defp determine_ending_parens_by_count(leading_spaces, 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 = render_link(prefix <> needed)
ast =
case leading_spaces do
"" -> link
_ -> [leading_spaces, link]
end
{ast, String.length(prefix) + String.length(leading_spaces) + max(0,take)}
end
@split_at_ending_parens ~r{(.*?)(\)*)\z}
defp remove_trailing_closing_parens(leading_spaces, link_text) do
[_, _prefix, suffix] = Regex.run(@split_at_ending_parens, link_text)
case suffix do
"" -> {"(", String.length(leading_spaces) + 1}
_ -> case convert_pure_link(betail(link_text, 1)) do
{link, length} -> {["(", link, ")"], length + 2}
_ -> nil
end
end
end
defp reparse_link(leading_spaces, link_text) do
[_, prefix, suffix] = Regex.run(@split_at_ending_parens, link_text)
nof_closing_parens = String.length(suffix)
determine_ending_parens_by_count(leading_spaces, prefix, nof_closing_parens)
end
end