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/html_parser.ex
defmodule Earmark.Parser.Helpers.HtmlParser do
@moduledoc false
import Earmark.Parser.Helpers.StringHelpers, only: [behead: 2]
import Earmark.Parser.LineScanner, only: [void_tag?: 1]
def parse_html(lines)
def parse_html([tag_line|rest]) do
case _parse_tag(tag_line) do
{ :ok, tag, "" } -> [_parse_rest(rest, tag, [])]
{ :ok, tag, suffix } -> [_parse_rest(rest, tag, [suffix])]
{ :ext, tag, "" } -> [_parse_rest(rest, tag, [])]
{ :ext, tag, suffix } -> [_parse_rest(rest, tag, []), [suffix]]
end
end
# Parse One Tag
# -------------
@quoted_attr ~r{\A ([-\w]+) \s* = \s* (["']) (.*?) \2 \s*}x
@unquoted_attr ~r{\A ([-\w]+) (?: \s* = \s* ([^&\s>]*))? \s*}x
defp _parse_atts(string, tag, atts) do
case Regex.run(@quoted_attr, string) do
[all, name, _delim, value] -> _parse_atts(behead(string, all), tag, [{name, value}|atts])
_ -> case Regex.run(@unquoted_attr, string) do
[all, name, value] -> _parse_atts(behead(string, all), tag, [{name, value}|atts])
[all, name] -> _parse_atts(behead(string, all), tag, [{name, name}|atts])
_ -> _parse_tag_tail(string, tag, atts)
end
end
end
# Are leading and trailing "-"s ok?
@tag_head ~r{\A \s* <([-\w]+) \s*}x
defp _parse_tag(string) do
case Regex.run(@tag_head, string) do
[all, tag] -> _parse_atts(behead(string, all), tag, [])
end
end
@tag_tail ~r{\A .*? (/?)> \s* (.*) \z}x
defp _parse_tag_tail(string, tag, atts) do
case Regex.run(@tag_tail, string) do
[_, closing, suffix] ->
suffix1 = String.replace(suffix, ~r{\s*</#{tag}>.*}, "")
_close_tag_tail(tag, atts, closing != "", suffix1)
end
end
defp _close_tag_tail(tag, atts, closing?, suffix) do
if closing? || void_tag?(tag) do
{:ext, {tag, Enum.reverse(atts)}, suffix }
else
{:ok, {tag, Enum.reverse(atts)}, suffix }
end
end
# Iterate over lines inside a tag
# -------------------------------
@verbatim %{verbatim: true}
defp _parse_rest(rest, tag_tpl, lines)
defp _parse_rest([], tag_tpl, lines) do
tag_tpl |> Tuple.append(Enum.reverse(lines)) |> Tuple.append(@verbatim)
end
defp _parse_rest([last_line], {tag, _}=tag_tpl, lines) do
case Regex.run(~r{\A\s*</#{tag}>\s*(.*)}, last_line) do
nil -> tag_tpl |> Tuple.append(Enum.reverse([last_line|lines])) |> Tuple.append(@verbatim)
[_, ""] -> tag_tpl |> Tuple.append(Enum.reverse(lines)) |> Tuple.append(@verbatim)
[_, suffix] -> [tag_tpl |> Tuple.append(Enum.reverse(lines)) |> Tuple.append(@verbatim), suffix]
end
end
defp _parse_rest([inner_line|rest], tag_tpl, lines) do
_parse_rest(rest, tag_tpl, [inner_line|lines])
end
end