cover/Elixir.Tools.User.Cfg.html

1 defmodule Tools.User.Cfg do
2 import Enum, only: [join: 2, map: 2, reduce: 3]
3 import File, only: [read!: 1]
4 import List, only: [first: 1]
5 import Map, only: [new: 2, put: 3]
6 import Regex, only: [replace: 3, scan: 3]
7 import String, only: [split: 2, to_atom: 1, trim: 1]
8
9 @code ~r/```elixir\n(.*?)\n```/s
10
11 def parse(path) do
12 10 path |> read!() |> sever() |> extract()
13 end
14
15 defp sever(content) do
16 10 split(content, "---")
17 end
18
19 defp extract([_, header | rest]) do
20 yaml(header)
21 |> atomize()
22 |> enrich(rest)
23 10 |> finish(rest)
24 end
25
26 defp enrich(cfg, rest) do
27 10 put(cfg, :code, blocks(join(rest, "---")))
28 end
29
30 defp finish(cfg, rest) do
31 10 put(cfg, :body, body(join(rest, "---")))
32 end
33
34 defp blocks(markdown) do
35 scan(@code, markdown, capture: :all_but_first)
36 10 |> map(&first/1)
37 end
38
39 defp body(markdown) do
40 10 replace(@code, markdown, "") |> trim()
41 end
42
43 defp atomize(map) do
44 10 map |> new(fn {k, v} -> {to_atom(k), v} end)
45 end
46
47 defp yaml(header) do
48 10 split(trim(header), "\n") |> reduce(%{}, &line/2)
49 end
50
51 defp line(text, acc) do
52 40 split(text, ":") |> build(acc)
53 end
54
55 40 defp build([key, value], acc), do: put(acc, trim(key), trim(value))
56
:-(
defp build(_, acc), do: acc
57 end
Line Hits Source