Browse Source

initial commit

Christian Kruse 3 years ago
parent
commit
06920218ab
8 changed files with 175 additions and 0 deletions
  1. 5
    0
      .gitignore
  2. 20
    0
      README.md
  3. 30
    0
      config/config.exs
  4. 37
    0
      lib/microformats2.ex
  5. 32
    0
      mix.exs
  6. 2
    0
      mix.lock
  7. 48
    0
      test/microformats2_test.exs
  8. 1
    0
      test/test_helper.exs

+ 5
- 0
.gitignore View File

@@ -0,0 +1,5 @@
1
+/_build
2
+/cover
3
+/deps
4
+erl_crash.dump
5
+*.ez

+ 20
- 0
README.md View File

@@ -0,0 +1,20 @@
1
+# Microformats2
2
+
3
+**TODO: Add description**
4
+
5
+## Installation
6
+
7
+If [available in Hex](https://hex.pm/docs/publish), the package can be installed as:
8
+
9
+  1. Add microformats2 to your list of dependencies in `mix.exs`:
10
+
11
+        def deps do
12
+          [{:microformats2, "~> 0.0.1"}]
13
+        end
14
+
15
+  2. Ensure microformats2 is started before your application:
16
+
17
+        def application do
18
+          [applications: [:microformats2]]
19
+        end
20
+

+ 30
- 0
config/config.exs View File

@@ -0,0 +1,30 @@
1
+# This file is responsible for configuring your application
2
+# and its dependencies with the aid of the Mix.Config module.
3
+use Mix.Config
4
+
5
+# This configuration is loaded before any dependency and is restricted
6
+# to this project. If another project depends on this project, this
7
+# file won't be loaded nor affect the parent project. For this reason,
8
+# if you want to provide default values for your application for
9
+# 3rd-party users, it should be done in your "mix.exs" file.
10
+
11
+# You can configure for your application as:
12
+#
13
+#     config :microformats2, key: :value
14
+#
15
+# And access this configuration in your application as:
16
+#
17
+#     Application.get_env(:microformats2, :key)
18
+#
19
+# Or configure a 3rd-party app:
20
+#
21
+#     config :logger, level: :info
22
+#
23
+
24
+# It is also possible to import configuration files, relative to this
25
+# directory. For example, you can emulate configuration per environment
26
+# by uncommenting the line below and defining dev.exs, test.exs and such.
27
+# Configuration from the imported file will override the ones defined
28
+# here (which is why it is important to import them last).
29
+#
30
+#     import_config "#{Mix.env}.exs"

+ 37
- 0
lib/microformats2.ex View File

@@ -0,0 +1,37 @@
1
+defmodule Microformats2 do
2
+  def parse(content) when is_bitstring(content) do
3
+    doc = Floki.parse(content)
4
+    rels = parse_rels(doc)
5
+
6
+    %{items: [], rels: rels[:rels], rel_urls: rels[:rel_urls]}
7
+  end
8
+
9
+  defp parse_rels(doc) do
10
+    link_rels = Floki.find(doc, "[rel][href]") |>
11
+      Enum.filter(fn(element) ->
12
+        rel = Floki.attribute(element, "rel") |> List.first
13
+        href = Floki.attribute(element, "href") |> List.first
14
+        String.strip(to_string(rel)) != "" and String.strip(to_string(href)) != ""
15
+      end) |>
16
+      Enum.reduce(%{rels: %{}, rel_urls: %{}}, fn(element, acc) ->
17
+        rel = Floki.attribute(element, "rel") |> List.first |> String.split(" ", trim: true)
18
+        url = Floki.attribute(element, "href") |> List.first # TODO convert to absolute URL
19
+
20
+        n_map = Enum.reduce(rel, acc, fn(rel, map) ->
21
+          if map[:rels][rel] == nil do
22
+            Map.put(map, :rels, Map.put(map[:rels], rel, [url]))
23
+          else
24
+            Map.put(map, :rels, Map.put(map[:rels], rel, Enum.uniq(map[:rels][rel] ++ [url])))
25
+          end
26
+        end)
27
+
28
+        if n_map[:rel_urls][url] == nil do
29
+          Map.put(n_map, :rel_urls, Map.put(n_map[:rel_urls], url, rel))
30
+        else
31
+          Map.put(n_map, :rel_urls, Map.put(n_map[:rel_urls], url, Enum.uniq(n_map[:rel_urls][url] ++ rel)))
32
+        end
33
+      end)
34
+
35
+    link_rels
36
+  end
37
+end

+ 32
- 0
mix.exs View File

@@ -0,0 +1,32 @@
1
+defmodule Microformats2.Mixfile do
2
+  use Mix.Project
3
+
4
+  def project do
5
+    [app: :microformats2,
6
+     version: "0.0.1",
7
+     elixir: "~> 1.2",
8
+     build_embedded: Mix.env == :prod,
9
+     start_permanent: Mix.env == :prod,
10
+     deps: deps]
11
+  end
12
+
13
+  # Configuration for the OTP application
14
+  #
15
+  # Type "mix help compile.app" for more information
16
+  def application do
17
+    [applications: [:logger]]
18
+  end
19
+
20
+  # Dependencies can be Hex packages:
21
+  #
22
+  #   {:mydep, "~> 0.3.0"}
23
+  #
24
+  # Or git/path repositories:
25
+  #
26
+  #   {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
27
+  #
28
+  # Type "mix help deps" for more examples and options
29
+  defp deps do
30
+    [{:floki, "~> 0.7"}]
31
+  end
32
+end

+ 2
- 0
mix.lock View File

@@ -0,0 +1,2 @@
1
+%{"floki": {:hex, :floki, "0.7.1"},
2
+  "mochiweb": {:hex, :mochiweb, "2.12.2"}}

+ 48
- 0
test/microformats2_test.exs View File

@@ -0,0 +1,48 @@
1
+defmodule Microformats2Test do
2
+  use ExUnit.Case
3
+  doctest Microformats2
4
+
5
+  test "parse successfully parses rels" do
6
+    assert(Microformats2.parse("<a rel=\"me\" href=\"http://blub\">blub</a>") ==
7
+      %{items: [],
8
+        rel_urls: %{"http://blub" => ["me"]},
9
+        rels: %{"me" => ["http://blub"]}})
10
+  end
11
+
12
+  test "parse successfully parses multiple rels" do
13
+    assert(Microformats2.parse("""
14
+<a rel=\"me\" href=\"http://blub\">blub</a>
15
+<a rel=\"me\" href=\"http://blah\">blub</a>
16
+""") ==
17
+      %{items: [],
18
+        rel_urls: %{"http://blub" => ["me"],
19
+                    "http://blah" => ["me"]},
20
+        rels: %{"me" => ["http://blub", "http://blah"]}})
21
+  end
22
+
23
+  test "parse only saves one URL" do
24
+    assert(Microformats2.parse("""
25
+<a rel=\"me\" href=\"http://blub\">blub</a>
26
+<a rel=\"me\" href=\"http://blub\">blub</a>
27
+""") ==
28
+      %{items: [],
29
+        rel_urls: %{"http://blub" => ["me"]},
30
+        rels: %{"me" => ["http://blub"]}})
31
+  end
32
+
33
+  test "parse saves all rels" do
34
+    assert(Microformats2.parse("""
35
+<a rel=\"me\" href=\"http://blub\">blub</a>
36
+<a rel=\"moo\" href=\"http://blub\">blub</a>
37
+""") ==
38
+      %{items: [],
39
+        rel_urls: %{"http://blub" => ["me", "moo"]},
40
+        rels: %{"me" => ["http://blub"],
41
+                "moo" => ["http://blub"]}})
42
+  end
43
+
44
+  test "parse generates an absolute URL" do
45
+    assert false, "TODO"
46
+  end
47
+
48
+end

+ 1
- 0
test/test_helper.exs View File

@@ -0,0 +1 @@
1
+ExUnit.start()

Loading…
Cancel
Save