Packages
floki
0.13.2
0.38.4
0.38.3
0.38.2
0.38.1
0.38.0
0.37.1
0.37.0
0.36.3
0.36.2
0.36.1
0.36.0
0.35.4
0.35.3
0.35.2
0.35.1
0.35.0
0.34.3
0.34.2
0.34.1
0.34.0
0.33.1
0.33.0
0.32.1
0.32.0
0.31.0
0.30.1
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.1
0.23.0
0.22.0
0.21.0
0.20.4
0.20.3
0.20.2
0.20.1
0.20.0
0.19.3
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.2
0.17.1
0.17.0
0.16.0
0.15.0
0.14.0
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.0
0.10.1
0.10.0
0.9.0
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.0
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.1
0.1.0
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
Floki is a simple HTML parser that enables search for nodes using CSS selectors.
Current section
86 Versions
Jump to
Current section
86 Versions
Compare versions
6
files changed
+39
additions
-31
deletions
| @@ -34,13 +34,16 @@ Here are some queries that you can perform (with return examples): | |
| 34 34 | ```elixir |
| 35 35 | Floki.find(html, "#content") |
| 36 36 | # => [{"section", [{"id", "content"}], |
| 37 | - # => [{"p", [{"class", "headline"}], ["Floki"]}, |
| 38 | - # => {"a", [{"href", "http://github.com/philss/floki"}], ["Github page"]}]}] |
| 37 | + # => [{"p", [{"class", "headline"}], ["Floki"]}, |
| 38 | + # => {"span", [{"class", "headline"}], ["Enables search using CSS selectors"]}, |
| 39 | + # => {"a", [{"href", "http://github.com/philss/floki"}], ["Github page"]}, |
| 40 | + # => {"span", [{"data-model", "user"}], ["philss"]}]}] |
| 39 41 | |
| 40 42 | |
| 41 43 | Floki.find(html, "p.headline") |
| 42 44 | # => [{"p", [{"class", "headline"}], ["Floki"]}] |
| 43 45 | |
| 46 | + |
| 44 47 | Floki.find(html, "p.headline") |
| 45 48 | |> Floki.raw_html |
| 46 49 | # => <p class="headline">Floki</p> |
| @@ -52,8 +55,7 @@ Floki.find(html, "a") | |
| 52 55 | |
| 53 56 | |
| 54 57 | Floki.find(html, "a[href^=https]") |
| 55 | - # => [{"a", [{"href", "http://github.com/philss/floki"}], ["Github page"]}, |
| 56 | - # => {"a", [{"href", "https://hex.pm/packages/floki"}], ["Hex package"]}] |
| 58 | + # => [{"a", [{"href", "https://hex.pm/packages/floki"}], ["Hex package"]}] |
| 57 59 | |
| 58 60 | |
| 59 61 | Floki.find(html, "#content a") |
| @@ -64,7 +66,7 @@ Floki.find(html, "[data-model=user]") | |
| 64 66 | # => [{"span", [{"data-model", "user"}], ["philss"]}] |
| 65 67 | |
| 66 68 | |
| 67 | - Floki.find(html, ".headline, a") |
| 69 | + Floki.find(html, ".headline:nth-child(1), a") |
| 68 70 | # => [{"p", [{"class", "headline"}], ["Floki"]}, |
| 69 71 | # => {"a", [{"href", "http://github.com/philss/floki"}], ["Github page"]}, |
| 70 72 | # => {"a", [{"href", "https://hex.pm/packages/floki"}], ["Hex package"]}] |
| @@ -95,12 +97,12 @@ It is simple as that! | |
| 95 97 | |
| 96 98 | ## Installation |
| 97 99 | |
| 98 | - Add Floki in your `mix.exs`, as a dependency: |
| 100 | + Add Floki to your `mix.exs`: |
| 99 101 | |
| 100 102 | ```elixir |
| 101 103 | defp deps do |
| 102 104 | [ |
| 103 | - {:floki, "~> 0.13.1"} |
| 105 | + {:floki, "~> 0.13.2"} |
| 104 106 | ] |
| 105 107 | end |
| 106 108 | ``` |
| @@ -25,4 +25,4 @@ | |
| 25 25 | {<<"name">>,<<"mochiweb">>}, |
| 26 26 | {<<"optional">>,false}, |
| 27 27 | {<<"requirement">>,<<"~> 2.15">>}]]}. |
| 28 | - {<<"version">>,<<"0.13.1">>}. |
| 28 | + {<<"version">>,<<"0.13.2">>}. |
| @@ -154,9 +154,8 @@ defmodule Floki do | |
| 154 154 | end |
| 155 155 | |
| 156 156 | def transform(html_tree_list, transformation) when is_list(html_tree_list) do |
| 157 | - html_tree_list |> Enum.map(fn |
| 158 | - html_tree -> |
| 159 | - Finder.apply_transformation(html_tree, transformation) |
| 157 | + Enum.map(html_tree_list, fn(html_tree) -> |
| 158 | + Finder.apply_transformation(html_tree, transformation) |
| 160 159 | end) |
| 161 160 | end |
| 162 161 | def transform(html_tree, transformation) do |
| @@ -68,8 +68,7 @@ defmodule Floki.Finder do | |
| 68 68 | end |
| 69 69 | |
| 70 70 | defp get_matches_for_selectors(tree, html_node, selectors) do |
| 71 | - selectors |
| 72 | - |> Enum.flat_map(fn(selector) -> get_matches(tree, html_node, selector) end) |
| 71 | + Enum.flat_map(selectors, fn(selector) -> get_matches(tree, html_node, selector) end) |
| 73 72 | end |
| 74 73 | |
| 75 74 | defp get_matches(tree, html_node, selector = %Selector{combinator: nil}) do |
| @@ -157,8 +156,7 @@ defmodule Floki.Finder do | |
| 157 156 | results = |
| 158 157 | Enum.flat_map(stack, fn(html_node) -> |
| 159 158 | ids_to_match = get_descendant_ids(html_node.node_id, tree) |
| 160 | - nodes = ids_to_match |
| 161 | - |> get_nodes(tree) |
| 159 | + nodes = get_nodes(ids_to_match, tree) |
| 162 160 | |
| 163 161 | Enum.filter(nodes, fn(html_node) -> Selector.match?(html_node, s) end) |
| 164 162 | end) |
| @@ -202,7 +200,7 @@ defmodule Floki.Finder do | |
| 202 200 | defp get_descendant_ids(node_id, tree) do |
| 203 201 | case get_node(node_id, tree) do |
| 204 202 | %{children_nodes_ids: node_ids} -> |
| 205 | - Enum.reverse(node_ids) ++ Enum.flat_map(node_ids, &( get_descendant_ids(&1, tree) )) |
| 203 | + Enum.reverse(node_ids) ++ Enum.flat_map(node_ids, &(get_descendant_ids(&1, tree))) |
| 206 204 | _ -> |
| 207 205 | [] |
| 208 206 | end |
| @@ -13,11 +13,12 @@ defmodule Floki.HTMLTree do | |
| 13 13 | |
| 14 14 | def build({tag, attrs, children}) do |
| 15 15 | root_id = IDSeeder.seed([]) |
| 16 | + root_node = %HTMLNode{type: tag, attributes: attrs, node_id: root_id} |
| 16 17 | |
| 17 | - %HTMLTree{root_nodes_ids: [root_id], |
| 18 | - node_ids: [root_id], |
| 19 | - nodes: %{root_id => %HTMLNode{type: tag, attributes: attrs, node_id: root_id}}} |
| 20 | - |> build_tree(children, root_id, []) |
| 18 | + build_tree(%HTMLTree{root_nodes_ids: [root_id], |
| 19 | + node_ids: [root_id], |
| 20 | + nodes: %{root_id => root_node}}, |
| 21 | + children, root_id, []) |
| 21 22 | end |
| 22 23 | |
| 23 24 | def build(html_tuples) when is_list(html_tuples) do |
| @@ -27,10 +28,18 @@ defmodule Floki.HTMLTree do | |
| 27 28 | |
| 28 29 | root_node = %HTMLNode{type: tag, attributes: attrs, node_id: root_id} |
| 29 30 | |
| 30 | - %{tree | nodes: Map.put(tree.nodes, root_id, root_node), |
| 31 | - node_ids: [root_id | tree.node_ids], |
| 32 | - root_nodes_ids: tree.root_nodes_ids ++ [root_id]} |
| 33 | - |> build_tree(children, root_id, []) |
| 31 | + build_tree(%{tree | nodes: Map.put(tree.nodes, root_id, root_node), |
| 32 | + node_ids: [root_id | tree.node_ids], |
| 33 | + root_nodes_ids: tree.root_nodes_ids ++ [root_id]}, |
| 34 | + children, root_id, []) |
| 35 | + (text, tree) when is_binary(text) -> |
| 36 | + root_id = IDSeeder.seed(tree.node_ids) |
| 37 | + |
| 38 | + root_node = %Text{content: text, node_id: root_id} |
| 39 | + build_tree(%{tree | nodes: Map.put(tree.nodes, root_id, root_node), |
| 40 | + node_ids: [root_id | tree.node_ids], |
| 41 | + root_nodes_ids: tree.root_nodes_ids ++ [root_id]}, |
| 42 | + [], root_id, []) |
| 34 43 | (_, tree) -> |
| 35 44 | tree |
| 36 45 | end |
| @@ -97,8 +106,8 @@ defmodule Floki.HTMLTree do | |
| 97 106 | |
| 98 107 | nodes = put_new_node(tree.nodes, new_node) |
| 99 108 | |
| 100 | - %{tree | nodes: nodes, node_ids: [new_id | tree.node_ids]} |
| 101 | - |> build_tree(child_children, new_id, [{parent_id, children} | stack]) |
| 109 | + build_tree(%{tree | nodes: nodes, node_ids: [new_id | tree.node_ids]}, |
| 110 | + child_children, new_id, [{parent_id, children} | stack]) |
| 102 111 | end |
| 103 112 | defp build_tree(tree, [{:comment, comment} | children], parent_id, stack) do |
| 104 113 | new_id = IDSeeder.seed(tree.node_ids) |
| @@ -106,8 +115,8 @@ defmodule Floki.HTMLTree do | |
| 106 115 | |
| 107 116 | nodes = put_new_node(tree.nodes, new_node) |
| 108 117 | |
| 109 | - %{tree | nodes: nodes, node_ids: [new_id | tree.node_ids]} |
| 110 | - |> build_tree(children, parent_id, stack) |
| 118 | + build_tree(%{tree | nodes: nodes, node_ids: [new_id | tree.node_ids]}, |
| 119 | + children, parent_id, stack) |
| 111 120 | end |
| 112 121 | defp build_tree(tree, [text | children], parent_id, stack) when is_binary(text) do |
| 113 122 | new_id = IDSeeder.seed(tree.node_ids) |
| @@ -115,8 +124,8 @@ defmodule Floki.HTMLTree do | |
| 115 124 | |
| 116 125 | nodes = put_new_node(tree.nodes, new_node) |
| 117 126 | |
| 118 | - %{tree | nodes: nodes, node_ids: [new_id | tree.node_ids]} |
| 119 | - |> build_tree(children, parent_id, stack) |
| 127 | + build_tree(%{tree | nodes: nodes, node_ids: [new_id | tree.node_ids]}, |
| 128 | + children, parent_id, stack) |
| 120 129 | end |
| 121 130 | defp build_tree(tree, [_other | children], parent_id, stack) do |
| 122 131 | build_tree(tree, children, parent_id, stack) |
Loading more files…