Current section

86 Versions

Jump to

Compare versions

10 files changed
+128 additions
-157 deletions
  @@ -7,14 +7,11 @@
7 7
8 8 Floki is a simple HTML parser that enables search for nodes using CSS selectors.
9 9
10 - You can perform searches using classes, attributes, tag names and IDs.
11 - You can also combine selectors and use groups, like: `"a.foo[data-action='bar'], .baz.zaz"`.
12 -
13 10 [Check the documentation](http://hexdocs.pm/floki).
14 11
15 12 ## Usage
16 13
17 - Assuming that you have the following HTML:
14 + Take this HTML as an example:
18 15
19 16 ```html
20 17 <!doctype html>
  @@ -97,7 +94,7 @@ It is simple as that!
97 94
98 95 ## Installation
99 96
100 - You can install Floki by adding a dependency to your mix file (mix.exs):
97 + Add Floki in your `mix.exs`, as a dependency:
101 98
102 99 ```elixir
103 100 defp deps do
  @@ -1,7 +1,7 @@
1 1 {<<"app">>,<<"floki">>}.
2 2 {<<"build_tools">>,[<<"mix">>]}.
3 3 {<<"description">>,
4 - <<"A HTML parser and searcher.\n\nYou can search inside HTML documents using CSS selectors.">>}.
4 + <<"Floki is a simple HTML parser that enables search for nodes using CSS selectors.">>}.
5 5 {<<"elixir">>,<<">= 1.0.0">>}.
6 6 {<<"files">>,
7 7 [<<"lib/floki.ex">>,<<"lib/floki/attribute_selector.ex">>,
  @@ -22,4 +22,4 @@
22 22 [{<<"app">>,<<"mochiweb">>},
23 23 {<<"optional">>,false},
24 24 {<<"requirement">>,<<"~> 2.12.2">>}]}]}.
25 - {<<"version">>,<<"0.7.1">>}.
25 + {<<"version">>,<<"0.7.2">>}.
  @@ -1,13 +1,10 @@
1 1 defmodule Floki do
2 2 alias Floki.Finder
3 3 alias Floki.Parser
4 + alias Floki.FilterOut
4 5
5 6 @moduledoc """
6 - A HTML parser and seeker.
7 -
8 - This is a simple HTML parser that enables searching using CSS like selectors.
9 -
10 - You can search elements by class, tag name and id.
7 + Floki is a simple HTML parser that enables search for nodes using CSS selectors.
11 8
12 9 ## Example
13 10
  @@ -26,14 +23,14 @@ defmodule Floki do
26 23 </html>
27 24 ```
28 25
29 - You can perform the following queries:
26 + Examples of queries that you can perform:
30 27
31 - * Floki.find(html, "#content") : returns the section with all children;
32 - * Floki.find(html, ".headline") : returns a list with the `p` element;
33 - * Floki.find(html, "a") : returns a list with the `a` element;
34 - * Floki.find(html, "[data-model=user]") : returns a list with elements that match that data attribute;
35 - * Floki.find(html, "#content a") # returns all links inside content section;
36 - * Floki.find(html, ".headline, a") # returns the .headline elements and links.
28 + * Floki.find(html, "#content")
29 + * Floki.find(html, ".headline")
30 + * Floki.find(html, "a")
31 + * Floki.find(html, "[data-model=user]")
32 + * Floki.find(html, "#content a")
33 + * Floki.find(html, ".headline, a")
37 34
38 35 Each HTML node is represented by a tuple like:
39 36
  @@ -91,6 +88,8 @@ defmodule Floki do
91 88
92 89 """
93 90
91 + @spec raw_html(html_tree) :: binary
92 +
94 93 def raw_html(html_tree), do: raw_html(html_tree, "")
95 94 defp raw_html([], html), do: html
96 95 defp raw_html(tuple, html) when is_tuple(tuple), do: raw_html([tuple], html)
  @@ -138,7 +137,7 @@ defmodule Floki do
138 137 @spec find(binary | html_tree, binary) :: html_tree
139 138
140 139 def find(html, selector) when is_binary(html) do
141 - parse(html) |> Finder.find(selector)
140 + html |> parse |> Finder.find(selector)
142 141 end
143 142 def find(html_tree, selector) do
144 143 Finder.find(html_tree, selector)
  @@ -170,14 +169,15 @@ defmodule Floki do
170 169
171 170 def text(html, opts \\ [deep: true, js: false]) do
172 171 html_tree =
173 - case is_binary(html) do
174 - true -> parse(html)
175 - false -> html
172 + if is_binary(html) do
173 + parse(html)
174 + else
175 + html
176 176 end
177 177
178 178 cleaned_html_tree =
179 179 case opts[:js] do
180 - true -> html_tree
180 + true -> html_tree
181 181 _ -> filter_out(html_tree, "script")
182 182 end
183 183
  @@ -262,6 +262,9 @@ defmodule Floki do
262 262 iex> Floki.filter_out([{"body", [], [{"script", [], []},{"div", [], []}]}], "script")
263 263 [{"body", [], [{"div", [], []}]}]
264 264
265 + iex> Floki.filter_out("<div><!-- comment --> text</div>", :comment)
266 + {"div", [], [" text"]}
267 +
265 268 """
266 269
267 270 @spec filter_out(binary | html_tree, binary) :: list
  @@ -269,11 +272,9 @@ defmodule Floki do
269 272 def filter_out(html_tree, selector) when is_binary(html_tree) do
270 273 html_tree
271 274 |> parse
272 - |> Floki.FilterOut.filter_out(selector)
275 + |> FilterOut.filter_out(selector)
273 276 end
274 277 def filter_out(elements, selector) do
275 - Floki.FilterOut.filter_out(elements, selector)
278 + FilterOut.filter_out(elements, selector)
276 279 end
277 -
278 -
279 280 end
  @@ -22,7 +22,7 @@ defmodule Floki.AttributeSelector do
22 22
23 23 whitespace_values = String.split(value, " ")
24 24
25 - Enum.any? whitespace_values, fn(v) -> v == s.value end
25 + Enum.any?(whitespace_values, fn(v) -> v == s.value end)
26 26 end
27 27 def match?(attributes, s = %AttributeSelector{match_type: :dash_match}) do
28 28 value = get_value(s.attribute, attributes)
  @@ -30,24 +30,24 @@ defmodule Floki.AttributeSelector do
30 30 value == s.value || String.starts_with?(value, "#{s.value}-")
31 31 end
32 32 def match?(attributes, s = %AttributeSelector{match_type: :prefix_match}) do
33 - get_value(s.attribute, attributes) |> String.starts_with?(s.value)
33 + s.attribute |> get_value(attributes) |> String.starts_with?(s.value)
34 34 end
35 35 def match?(attributes, s = %AttributeSelector{match_type: :sufix_match}) do
36 - get_value(s.attribute, attributes) |> String.ends_with?(s.value)
36 + s.attribute |> get_value(attributes) |> String.ends_with?(s.value)
37 37 end
38 38 def match?(attributes, s = %AttributeSelector{match_type: :substring_match}) do
39 - get_value(s.attribute, attributes) |> String.contains?(s.value)
39 + s.attribute |> get_value(attributes) |> String.contains?(s.value)
40 40 end
41 41
42 42 defp get_value(attr_name, attributes) do
43 - {_attr_name, value} = Enum.find attributes, {attr_name, ""}, fn({k, _v}) ->
43 + {_attr_name, value} = Enum.find(attributes, {attr_name, ""}, fn({k, _v}) ->
44 44 k == attr_name
45 - end
45 + end)
46 46
47 47 value
48 48 end
49 49
50 50 defp attribute_present?(name, attributes) do
51 - Enum.any? attributes, fn({k, _v}) -> k == name end
51 + Enum.any?(attributes, fn({k, _v}) -> k == name end)
52 52 end
53 53 end
  @@ -29,6 +29,7 @@ defmodule Floki.DeepText do
29 29 end
30 30 end
31 31 defp get_text({:comment, _}, acc), do: acc
32 + defp get_text({"br", _, _}, acc), do: acc <> "\n"
32 33 defp get_text({_, _, nodes}, acc) do
33 34 get_text(nodes, acc)
34 35 end
Loading more files…