1defmodule Earmark.Helpers do
2
3  @doc """
4  Expand tabs to multiples of 4 columns
5  """
6  def expand_tabs(line) do
7    Regex.replace(~r{(.*?)\t}, line, &expander/2)
8  end
9
10  defp expander(_, leader) do
11    extra = 4 - rem(String.length(leader), 4)
12    leader <> pad(extra)
13  end
14
15  @doc """
16  Remove newlines at end of line
17  """
18  def remove_line_ending(line) do
19    line |> String.trim_trailing("\n") |> String.trim_trailing("\r")
20  end
21
22  defp pad(1), do: " "
23  defp pad(2), do: "  "
24  defp pad(3), do: "   "
25  defp pad(4), do: "    "
26
27  @doc """
28  `Regex.replace` with the arguments in the correct order
29  """
30
31  def replace(text, regex, replacement, options \\ []) do
32    Regex.replace(regex, text, replacement, options)
33  end
34
35  @doc """
36  Encode URIs to be included in the `<a>` elements.
37
38  Percent-escapes a URI, and after that escapes any
39  `&`, `<`, `>`, `"`, `'`.
40  """
41  def encode(html) do
42    URI.encode(html) |> escape(true)
43  end
44
45  @doc """
46  Replace <, >, and quotes with the corresponding entities. If
47  `encode` is true, convert ampersands, too, otherwise only
48   convert non-entity ampersands.
49  """
50
51  def escape(html, encode \\ false)
52
53  def escape(html, false), do: _escape(Regex.replace(~r{&(?!#?\w+;)}, html, "&amp;"))
54  def escape(html, _), do: _escape(String.replace(html, "&", "&amp;"))
55
56  defp _escape(html) do
57    html
58    |> String.replace("<",  "&lt;")
59    |> String.replace(">",  "&gt;")
60    |> String.replace("\"", "&quot;")
61    |> String.replace("'",  "&#39;")
62  end
63
64
65end
66
67# SPDX-License-Identifier: Apache-2.0
68