Packages
floki
0.22.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
5
files changed
+52
additions
-11
deletions
| @@ -70,7 +70,7 @@ Add Floki to your `mix.exs`: | |
| 70 70 | ```elixir |
| 71 71 | defp deps do |
| 72 72 | [ |
| 73 | - {:floki, "~> 0.21.0"} |
| 73 | + {:floki, "~> 0.22.0"} |
| 74 74 | ] |
| 75 75 | end |
| 76 76 | ``` |
| @@ -105,7 +105,7 @@ After setup Rust, you need to add `html5ever` NIF to your dependency list: | |
| 105 105 | ```elixir |
| 106 106 | defp deps do |
| 107 107 | [ |
| 108 | - {:floki, "~> 0.21.0"}, |
| 108 | + {:floki, "~> 0.22.0"}, |
| 109 109 | {:html5ever, "~> 0.7.0"} |
| 110 110 | ] |
| 111 111 | end |
| @@ -2,7 +2,7 @@ | |
| 2 2 | {<<"build_tools">>,[<<"mix">>]}. |
| 3 3 | {<<"description">>, |
| 4 4 | <<"Floki is a simple HTML parser that enables search for nodes using CSS selectors.">>}. |
| 5 | - {<<"elixir">>,<<">= 1.4.0">>}. |
| 5 | + {<<"elixir">>,<<">= 1.5.0">>}. |
| 6 6 | {<<"files">>, |
| 7 7 | [<<"lib">>,<<"lib/floki">>,<<"lib/floki/html_parser.ex">>, |
| 8 8 | <<"lib/floki/html_parser">>,<<"lib/floki/html_parser/mochiweb.ex">>, |
| @@ -13,11 +13,11 @@ | |
| 13 13 | <<"lib/floki/selector/tokenizer.ex">>, |
| 14 14 | <<"lib/floki/selector/combinator.ex">>,<<"lib/floki/deep_text.ex">>, |
| 15 15 | <<"lib/floki/filter_out.ex">>,<<"lib/floki/flat_text.ex">>, |
| 16 | - <<"lib/floki/finder.ex">>,<<"lib/floki/raw_html.ex">>, |
| 17 | - <<"lib/floki/html_tree">>,<<"lib/floki/html_tree/id_seeder.ex">>, |
| 18 | - <<"lib/floki/html_tree/comment.ex">>,<<"lib/floki/html_tree/text.ex">>, |
| 19 | - <<"lib/floki/html_tree/html_node.ex">>,<<"lib/floki/selector.ex">>, |
| 20 | - <<"lib/floki/html_tree.ex">>,<<"lib/floki.ex">>, |
| 16 | + <<"lib/floki/finder.ex">>,<<"lib/floki/traversal.ex">>, |
| 17 | + <<"lib/floki/raw_html.ex">>,<<"lib/floki/html_tree">>, |
| 18 | + <<"lib/floki/html_tree/id_seeder.ex">>,<<"lib/floki/html_tree/comment.ex">>, |
| 19 | + <<"lib/floki/html_tree/text.ex">>,<<"lib/floki/html_tree/html_node.ex">>, |
| 20 | + <<"lib/floki/selector.ex">>,<<"lib/floki/html_tree.ex">>,<<"lib/floki.ex">>, |
| 21 21 | <<"src/floki_selector_lexer.xrl">>,<<"mix.exs">>,<<"README.md">>, |
| 22 22 | <<"LICENSE">>,<<"CODE_OF_CONDUCT.md">>,<<"CONTRIBUTING.md">>]}. |
| 23 23 | {<<"licenses">>,[<<"MIT">>]}. |
| @@ -34,4 +34,4 @@ | |
| 34 34 | {<<"optional">>,false}, |
| 35 35 | {<<"repository">>,<<"hexpm">>}, |
| 36 36 | {<<"requirement">>,<<"~> 0.4.0">>}]]}. |
| 37 | - {<<"version">>,<<"0.21.0">>}. |
| 37 | + {<<"version">>,<<"0.22.0">>}. |
| @@ -228,6 +228,22 @@ defmodule Floki do | |
| 228 228 | |
| 229 229 | def map(html_tree, fun), do: Finder.map(html_tree, fun) |
| 230 230 | |
| 231 | + @doc """ |
| 232 | + Traverses a HTML tree structure and returns a new tree structure that is the result of executing a function on all nodes. The function receives a tuple with {name, attributes, children}, and should either return a similar tuple or `nil` to delete the current node. |
| 233 | + |
| 234 | + ## Examples |
| 235 | + |
| 236 | + iex> html = {"div", [], ["hello"]} |
| 237 | + iex> Floki.traverse_and_update(html, fn {"div", attrs, children} -> {"p", attrs, children} end) |
| 238 | + {"p", [], ["hello"]} |
| 239 | + |
| 240 | + iex> html = {"div", [], [{"span", [], ["hello"]}]} |
| 241 | + iex> Floki.traverse_and_update(html, fn {"span", _attrs, _children} -> nil; tag -> tag end) |
| 242 | + {"div", [], []} |
| 243 | + """ |
| 244 | + |
| 245 | + defdelegate traverse_and_update(html_tree, fun), to: Floki.Traversal |
| 246 | + |
| 231 247 | @doc """ |
| 232 248 | Returns the text nodes from a HTML tree. |
| 233 249 | By default, it will perform a deep search through the HTML tree. |
| @@ -0,0 +1,25 @@ | |
| 1 | + defmodule Floki.Traversal do |
| 2 | + @moduledoc false |
| 3 | + |
| 4 | + def traverse_and_update(text, _fun) when is_binary(text), do: text |
| 5 | + |
| 6 | + def traverse_and_update([head | tail], fun) do |
| 7 | + case traverse_and_update(head, fun) do |
| 8 | + nil -> traverse_and_update(tail, fun) |
| 9 | + mapped_head -> [mapped_head | traverse_and_update(tail, fun)] |
| 10 | + end |
| 11 | + end |
| 12 | + |
| 13 | + def traverse_and_update([], _fun), do: [] |
| 14 | + |
| 15 | + def traverse_and_update(xml_tag = {:pi, _, _}, fun), do: fun.(xml_tag) |
| 16 | + |
| 17 | + def traverse_and_update({elem, attrs, children}, fun) do |
| 18 | + mapped_children = traverse_and_update(children, fun) |
| 19 | + fun.({elem, attrs, mapped_children}) |
| 20 | + end |
| 21 | + |
| 22 | + def traverse_and_update({:comment, children}, fun), do: fun.({:comment, children}) |
| 23 | + |
| 24 | + def traverse_and_update(doctype = {:doctype, _, _, _}, fun), do: fun.(doctype) |
| 25 | + end |
| @@ -2,7 +2,7 @@ defmodule Floki.Mixfile do | |
| 2 2 | use Mix.Project |
| 3 3 | |
| 4 4 | @description "Floki is a simple HTML parser that enables search for nodes using CSS selectors." |
| 5 | - @version "0.21.0" |
| 5 | + @version "0.22.0" |
| 6 6 | |
| 7 7 | def project do |
| 8 8 | [ |
| @@ -10,7 +10,7 @@ defmodule Floki.Mixfile do | |
| 10 10 | name: "Floki", |
| 11 11 | version: @version, |
| 12 12 | description: @description, |
| 13 | - elixir: ">= 1.4.0", |
| 13 | + elixir: ">= 1.5.0", |
| 14 14 | package: package(), |
| 15 15 | deps: deps(), |
| 16 16 | source_url: "https://github.com/philss/floki", |