Packages
floki
0.9.0
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
+62
additions
-29
deletions
| @@ -3,6 +3,7 @@ | |
| 3 3 | [](https://travis-ci.org/philss/floki) |
| 4 4 | [](https://hex.pm/packages/floki) |
| 5 5 | [](https://hex.pm/packages/floki) |
| 6 | + [](https://beta.hexfaktor.org/github/philss/floki) |
| 6 7 | [](http://inch-ci.org/github/philss/floki) |
| 7 8 | |
| 8 9 | Floki is a simple HTML parser that enables search for nodes using CSS selectors. |
| @@ -18,8 +18,8 @@ | |
| 18 18 | {<<"maintainers">>,[<<"Philip Sampaio Silva">>]}. |
| 19 19 | {<<"name">>,<<"floki">>}. |
| 20 20 | {<<"requirements">>, |
| 21 | - [{<<"mochiweb_html">>, |
| 22 | - [{<<"app">>,<<"mochiweb_html">>}, |
| 23 | - {<<"optional">>,false}, |
| 24 | - {<<"requirement">>,<<"~> 2.15">>}]}]}. |
| 25 | - {<<"version">>,<<"0.8.1">>}. |
| 21 | + [[{<<"app">>,<<"mochiweb_html">>}, |
| 22 | + {<<"name">>,<<"mochiweb_html">>}, |
| 23 | + {<<"optional">>,false}, |
| 24 | + {<<"requirement">>,<<"~> 2.15">>}]]}. |
| 25 | + {<<"version">>,<<"0.9.0">>}. |
| @@ -135,6 +135,9 @@ defmodule Floki do | |
| 135 135 | iex> Floki.find("<p><a href='https://google.com'>Google</a></p>", "a") |
| 136 136 | [{"a", [{"href", "https://google.com"}], ["Google"]}] |
| 137 137 | |
| 138 | + iex> Floki.find([{ "div", [], [{"a", [{"href", "https://google.com"}], ["Google"]}]}], "div a") |
| 139 | + [{"a", [{"href", "https://google.com"}], ["Google"]}] |
| 140 | + |
| 138 141 | """ |
| 139 142 | |
| 140 143 | @spec find(binary | html_tree, binary) :: html_tree |
| @@ -151,6 +154,7 @@ defmodule Floki do | |
| 151 154 | By default, it will perform a deep search through the HTML tree. |
| 152 155 | You can disable deep search with the option `deep` assigned to false. |
| 153 156 | You can include content of script tags with the option `js` assigned to true. |
| 157 | + You can specify a separator between nodes content. |
| 154 158 | |
| 155 159 | ## Examples |
| 156 160 | |
| @@ -166,11 +170,17 @@ defmodule Floki do | |
| 166 170 | iex> Floki.text("<div><script>hello</script> world</div>", js: true) |
| 167 171 | "hello world" |
| 168 172 | |
| 173 | + iex> Floki.text("<ul><li>hello</li><li>world</li></ul>", sep: " ") |
| 174 | + "hello world" |
| 175 | + |
| 176 | + iex> Floki.text([{"div", [], ["hello world"]}]) |
| 177 | + "hello world" |
| 178 | + |
| 169 179 | """ |
| 170 180 | |
| 171 181 | @spec text(html_tree | binary) :: binary |
| 172 182 | |
| 173 | - def text(html, opts \\ [deep: true, js: false]) do |
| 183 | + def text(html, opts \\ [deep: true, js: false, sep: ""]) do |
| 174 184 | html_tree = |
| 175 185 | if is_binary(html) do |
| 176 186 | parse(html) |
| @@ -190,7 +200,11 @@ defmodule Floki do | |
| 190 200 | _ -> Floki.DeepText |
| 191 201 | end |
| 192 202 | |
| 193 | - search_strategy.get(cleaned_html_tree) |
| 203 | + case opts[:sep] do |
| 204 | + nil -> search_strategy.get(cleaned_html_tree) |
| 205 | + sep -> search_strategy.get(cleaned_html_tree, sep) |
| 206 | + end |
| 207 | + |
| 194 208 | end |
| 195 209 | |
| 196 210 | @doc """ |
| @@ -201,6 +215,9 @@ defmodule Floki do | |
| 201 215 | iex> Floki.attribute("<a href='https://google.com'>Google</a>", "a", "href") |
| 202 216 | ["https://google.com"] |
| 203 217 | |
| 218 | + iex> Floki.attribute([{"a", [{"href", "https://google.com"}], ["Google"]}], "a", "href") |
| 219 | + ["https://google.com"] |
| 220 | + |
| 204 221 | """ |
| 205 222 | |
| 206 223 | @spec attribute(binary | html_tree, binary, binary) :: list |
| @@ -219,6 +236,9 @@ defmodule Floki do | |
| 219 236 | iex> Floki.attribute("<a href=https://google.com>Google</a>", "href") |
| 220 237 | ["https://google.com"] |
| 221 238 | |
| 239 | + iex> Floki.attribute([{"a", [{"href", "https://google.com"}], ["Google"]}], "href") |
| 240 | + ["https://google.com"] |
| 241 | + |
| 222 242 | """ |
| 223 243 | |
| 224 244 | @spec attribute(binary | html_tree, binary) :: list |
| @@ -6,7 +6,7 @@ defmodule Floki.DeepText do | |
| 6 6 | |
| 7 7 | @type html_tree :: tuple | list |
| 8 8 | |
| 9 | - @spec get(html_tree) :: binary |
| 9 | + @spec get(html_tree, binary) :: binary |
| 10 10 | |
| 11 11 | @doc """ |
| 12 12 | Get text nodes from a deep tree of HTML nodes. |
| @@ -17,20 +17,24 @@ defmodule Floki.DeepText do | |
| 17 17 | iex> Floki.DeepText.get([{"a", [], ["The meaning of life is...", {"strong", [], ["something else"]}] }]) |
| 18 18 | "The meaning of life is...something else" |
| 19 19 | |
| 20 | + iex> Floki.DeepText.get([{"a", [], ["The meaning of life is...", {"strong", [], ["something else"]}] }], " ") |
| 21 | + "The meaning of life is... something else" |
| 22 | + |
| 20 23 | """ |
| 21 | - def get(html_tree) do |
| 22 | - get_text(html_tree, "") |
| 24 | + def get(html_tree, sep \\ "") do |
| 25 | + get_text(html_tree, "", sep) |
| 23 26 | end |
| 24 27 | |
| 25 | - defp get_text(text, acc) when is_binary(text), do: acc <> text |
| 26 | - defp get_text(nodes, acc) when is_list(nodes) do |
| 28 | + defp get_text(text, "", _sep) when is_binary(text), do: text |
| 29 | + defp get_text(text, acc, sep) when is_binary(text), do: Enum.join([acc, text], sep) |
| 30 | + defp get_text(nodes, acc, sep) when is_list(nodes) do |
| 27 31 | Enum.reduce nodes, acc, fn(child, istr) -> |
| 28 | - get_text(child, istr) |
| 32 | + get_text(child, istr, sep) |
| 29 33 | end |
| 30 34 | end |
| 31 | - defp get_text({:comment, _}, acc), do: acc |
| 32 | - defp get_text({"br", _, _}, acc), do: acc <> "\n" |
| 33 | - defp get_text({_, _, nodes}, acc) do |
| 34 | - get_text(nodes, acc) |
| 35 | + defp get_text({:comment, _}, acc, _), do: acc |
| 36 | + defp get_text({"br", _, _}, acc, _), do: acc <> "\n" |
| 37 | + defp get_text({_, _, nodes}, acc, sep) do |
| 38 | + get_text(nodes, acc, sep) |
| 35 39 | end |
| 36 40 | end |
| @@ -6,7 +6,7 @@ defmodule Floki.FlatText do | |
| 6 6 | |
| 7 7 | @type html_tree :: tuple | list |
| 8 8 | |
| 9 | - @spec get(html_tree) :: binary |
| 9 | + @spec get(html_tree, binary) :: binary |
| 10 10 | |
| 11 11 | @doc """ |
| 12 12 | Get text nodes from first level of HTML nodes. |
| @@ -17,22 +17,30 @@ defmodule Floki.FlatText do | |
| 17 17 | iex> Floki.FlatText.get([{"a", [], ["The meaning of life is...", {"strong", [], ["something else"]}] }]) |
| 18 18 | "The meaning of life is..." |
| 19 19 | |
| 20 | + iex> Floki.FlatText.get([{"a", [], ["The meaning of life is...", {"strong", [], ["something else"]}] }], " ") |
| 21 | + "The meaning of life is..." |
| 22 | + |
| 20 23 | """ |
| 21 | - def get(html_nodes) when is_list(html_nodes) do |
| 24 | + def get(html_nodes, sep \\ "") |
| 25 | + def get(html_nodes, sep) when is_list(html_nodes) do |
| 22 26 | Enum.reduce(html_nodes, "", fn(html_node, acc) -> |
| 23 | - text_from_node(html_node, acc) |
| 27 | + text_from_node(html_node, acc, sep) |
| 24 28 | end) |
| 25 29 | end |
| 26 | - def get(html_node) do |
| 27 | - text_from_node(html_node, "") |
| 30 | + def get(html_node, sep) do |
| 31 | + text_from_node(html_node, "", sep) |
| 28 32 | end |
| 29 33 | |
| 30 | - defp text_from_node({ _tag, _attrs, html_nodes}, acc) do |
| 31 | - Enum.reduce(html_nodes, acc, &capture_text/2) |
| 34 | + defp text_from_node({ _tag, _attrs, html_nodes}, acc, sep) do |
| 35 | + Enum.reduce(html_nodes, acc, fn(node, acc) -> |
| 36 | + capture_text(node, acc, sep) |
| 37 | + end) |
| 32 38 | end |
| 33 | - defp text_from_node(text, acc) when is_binary(text), do: acc <> text |
| 34 | - defp text_from_node(_, acc), do: acc |
| 39 | + defp text_from_node(text, "", _sep) when is_binary(text), do: text |
| 40 | + defp text_from_node(text, acc, sep) when is_binary(text), do: Enum.join([acc, text], sep) |
| 41 | + defp text_from_node(_, acc, _), do: acc |
| 35 42 | |
| 36 | - defp capture_text(text, acc) when is_binary(text), do: acc <> text |
| 37 | - defp capture_text(_html_node, acc), do: acc |
| 43 | + defp capture_text(text, "", _sep) when is_binary(text), do: text |
| 44 | + defp capture_text(text, acc, sep) when is_binary(text), do: Enum.join([acc, text], sep) |
| 45 | + defp capture_text(_html_node, acc, _), do: acc |
| 38 46 | end |
Loading more files…