File: helpers.ex

package info (click to toggle)
elixir-earmark-parser 1.4.44-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,148 kB
  • sloc: makefile: 9
file content (108 lines) | stat: -rw-r--r-- 2,445 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
defmodule EarmarkParser.Helpers do
  @moduledoc false
  @doc """
  Expand tabs to multiples of 4 columns
  """
  def expand_tabs(line) do
    Regex.replace(~r{(.*?)\t}, line, &expander/2)
  end

  @doc ~S"""
  Returns a tuple containing a potentially present IAL and the line w/o the IAL

      iex(1)> extract_ial("# A headline")
      {nil, "# A headline"}

      iex(2)> extract_ial("# A classy headline{:.classy}")
      {".classy", "# A classy headline"}

  An IAL line, remains an IAL line though

      iex(3)> extract_ial("{:.line-ial}")
      {nil, "{:.line-ial}"}
  """
  def extract_ial(line) do
    trailing_ial_rgx = ~r< (?<!^)(?'ial'{: \s* [^}]+ \s* }) \s* \z >x

    case Regex.split(trailing_ial_rgx, line, include_captures: true, parts: 2, on: [:ial]) do
      [_] ->
        {nil, line}

      [line_, "{:" <> ial, _] ->
        ial_ =
          ial
          |> String.trim_trailing("}")
          |> String.trim()

        {ial_, String.trim_trailing(line_)}
    end
  end

  defp expander(_, leader) do
    extra = 4 - rem(String.length(leader), 4)
    leader <> pad(extra)
  end

  @doc """
  Remove newlines at end of line and optionally annotations
  """
  # def remove_line_ending(line, annotation \\ nil)
  def remove_line_ending(line, nil) do
    _trim_line({line, nil})
  end

  def remove_line_ending(line, annotation) do
    case Regex.run(annotation, line) do
      nil -> _trim_line({line, nil})
      match -> match |> tl() |> List.to_tuple() |> _trim_line()
    end
  end

  defp _trim_line({line, annot}) do
    {line |> String.trim_trailing("\n") |> String.trim_trailing("\r"), annot}
  end

  defp pad(1) do
    " "
  end

  defp pad(2) do
    "  "
  end

  defp pad(3) do
    "   "
  end

  defp pad(4) do
    "    "
  end

  @doc """
  `Regex.replace` with the arguments in the correct order
  """

  def replace(text, regex, replacement, options \\ []) do
    Regex.replace(regex, text, replacement, options)
  end

  @doc """
  Replace <, >, and quotes with the corresponding entities. If
  `encode` is true, convert ampersands, too, otherwise only
   convert non-entity ampersands.
  """

  def escape(html) do
    _escape(Regex.replace(~r{&(?!#?\w+;)}, html, "&amp;"))
  end

  defp _escape(html) do
    html
    |> String.replace("<", "&lt;")
    |> String.replace(">", "&gt;")
    |> String.replace("\"", "&quot;")
    |> String.replace("'", "&#39;")
  end
end

# SPDX-License-Identifier: Apache-2.0