Packages
floki
0.27.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
9
files changed
+134
additions
-93
deletions
| @@ -15,9 +15,9 @@ Documentation is a very important portion of software. We want to always improve | |
| 15 15 | ### Ideas |
| 16 16 | |
| 17 17 | To contribute with ideas, you can [open issues](https://github.com/philss/floki/issues/new) using Github. Please write a clear description of |
| 18 | - what you want to propouse, along with a motivation and examples. |
| 18 | + what you want to propose, along with a motivation and examples. |
| 19 19 | |
| 20 | - This can make the project very rich, even if your propouse is not accepted. It worth the discussion and possible implementations. |
| 20 | + This can make the project very rich, even if your proposal is not accepted. It worth the discussion and possible implementations. |
| 21 21 | |
| 22 22 | ### Code |
| @@ -60,13 +60,15 @@ Add Floki to your `mix.exs`: | |
| 60 60 | ```elixir |
| 61 61 | defp deps do |
| 62 62 | [ |
| 63 | - {:floki, "~> 0.26.0"} |
| 63 | + {:floki, "~> 0.27.0"} |
| 64 64 | ] |
| 65 65 | end |
| 66 66 | ``` |
| 67 67 | |
| 68 68 | After that, run `mix deps.get`. |
| 69 69 | |
| 70 | + You can check the [change log](https://github.com/philss/floki/blob/master/CHANGELOG.md) for changes. |
| 71 | + |
| 70 72 | ## Dependencies |
| 71 73 | |
| 72 74 | Floki needs the `leex` module in order to compile. |
| @@ -113,7 +115,7 @@ After Rust is set up, you need to add `html5ever` NIF to your dependency list: | |
| 113 115 | ```elixir |
| 114 116 | defp deps do |
| 115 117 | [ |
| 116 | - {:floki, "~> 0.26.0"}, |
| 118 | + {:floki, "~> 0.27.0"}, |
| 117 119 | {:html5ever, "~> 0.7.0"} |
| 118 120 | ] |
| 119 121 | end |
| @@ -145,7 +147,7 @@ First, add `fast_html` to your dependencies: | |
| 145 147 | ```elixir |
| 146 148 | defp deps do |
| 147 149 | [ |
| 148 | - {:floki, "~> 0.26.0"}, |
| 150 | + {:floki, "~> 0.27.0"}, |
| 149 151 | {:fast_html, "~> 1.0"} |
| 150 152 | ] |
| 151 153 | end |
| @@ -32,4 +32,4 @@ | |
| 32 32 | {<<"optional">>,false}, |
| 33 33 | {<<"repository">>,<<"hexpm">>}, |
| 34 34 | {<<"requirement">>,<<"~> 0.5.0">>}]]}. |
| 35 | - {<<"version">>,<<"0.26.0">>}. |
| 35 | + {<<"version">>,<<"0.27.0">>}. |
| @@ -61,11 +61,13 @@ defmodule Floki do | |
| 61 61 | inside a list. |
| 62 62 | """ |
| 63 63 | |
| 64 | + @type html_declaration :: {:pi, String.t(), [html_attribute()]} |
| 64 65 | @type html_comment :: {:comment, String.t()} |
| 65 66 | @type html_doctype :: {:doctype, String.t(), String.t(), String.t()} |
| 66 67 | @type html_attribute :: {String.t(), String.t()} |
| 67 68 | @type html_tag :: {String.t(), [html_attribute()], [html_tag() | String.t() | html_comment()]} |
| 68 | - @type html_tree :: [html_comment() | html_doctype() | html_tag()] |
| 69 | + @type html_node :: html_comment() | html_doctype() | html_tag() | html_declaration() |
| 70 | + @type html_tree :: [html_node()] |
| 69 71 | |
| 70 72 | @doc """ |
| 71 73 | Parses a HTML Document from a String. |
| @@ -166,13 +168,13 @@ defmodule Floki do | |
| 166 168 | |
| 167 169 | ## Examples |
| 168 170 | |
| 169 | - iex> Floki.raw_html({:div, [class: "wrapper"], ["my content"]}) |
| 171 | + iex> Floki.raw_html({"div", [{"class", "wrapper"}], ["my content"]}) |
| 170 172 | ~s(<div class="wrapper">my content</div>) |
| 171 173 | |
| 172 | - iex> Floki.raw_html({:div, [class: "wrapper"], ["10 > 5"]}, encode: true) |
| 174 | + iex> Floki.raw_html({"div", [{"class", "wrapper"}], ["10 > 5"]}, encode: true) |
| 173 175 | ~s(<div class="wrapper">10 > 5</div>) |
| 174 176 | |
| 175 | - iex> Floki.raw_html({:div, [class: "wrapper"], ["10 > 5"]}, encode: false) |
| 177 | + iex> Floki.raw_html({"div", [{"class", "wrapper"}], ["10 > 5"]}, encode: false) |
| 176 178 | ~s(<div class="wrapper">10 > 5</div>) |
| 177 179 | """ |
| 178 180 | |
| @@ -326,7 +328,8 @@ defmodule Floki do | |
| 326 328 | Traverses and updates a HTML tree structure. |
| 327 329 | |
| 328 330 | This function returns a new tree structure that is the result of applying the |
| 329 | - given `fun` on all nodes. |
| 331 | + given `fun` on all nodes. The tree is traversed in a post-walk fashion, where |
| 332 | + the children are traversed before the parent. |
| 330 333 | |
| 331 334 | The function `fun` receives a tuple with `{name, attributes, children}`, and |
| 332 335 | should either return a similar tuple or `nil` to delete the current node. |
| @@ -347,7 +350,7 @@ defmodule Floki do | |
| 347 350 | {"div", [], []} |
| 348 351 | """ |
| 349 352 | |
| 350 | - @spec traverse_and_update(html_tree(), (html_tag() -> html_tag() | nil)) :: html_tree() |
| 353 | + @spec traverse_and_update(html_tree(), (html_node() -> html_node() | nil)) :: html_tree() |
| 351 354 | |
| 352 355 | defdelegate traverse_and_update(html_tree, fun), to: Floki.Traversal |
| 353 356 | |
| @@ -355,7 +358,9 @@ defmodule Floki do | |
| 355 358 | Traverses and updates a HTML tree structure with an accumulator. |
| 356 359 | |
| 357 360 | This function returns a new tree structure and the final value of accumulator |
| 358 | - which are the result of applying the given `fun` on all nodes. |
| 361 | + which are the result of applying the given `fun` on all nodes. The tree is |
| 362 | + traversed in a post-walk fashion, where the children are traversed before |
| 363 | + the parent. |
| 359 364 | |
| 360 365 | The function `fun` receives a tuple with `{name, attributes, children}` and |
| 361 366 | an accumulator, and should return a 2-tuple like `{new_node, new_acc}`, where |
| @@ -383,12 +388,12 @@ defmodule Floki do | |
| 383 388 | {{"div", [], []}, [deleted: 1]} |
| 384 389 | """ |
| 385 390 | |
| 386 | - @type traverse_acc :: any() |
| 387 391 | @spec traverse_and_update( |
| 388 392 | html_tree(), |
| 389 | - traverse_acc(), |
| 390 | - (html_tag(), traverse_acc() -> {html_tag() | nil, traverse_acc()}) |
| 391 | - ) :: {html_tree(), traverse_acc()} |
| 393 | + traverse_acc, |
| 394 | + (html_node(), traverse_acc -> {html_node() | nil, traverse_acc}) |
| 395 | + ) :: {html_node(), traverse_acc} |
| 396 | + when traverse_acc: any() |
| 392 397 | |
| 393 398 | defdelegate traverse_and_update(html_tree, acc, fun), to: Floki.Traversal |
| 394 399 | |
| @@ -454,8 +459,10 @@ defmodule Floki do | |
| 454 459 | @doc """ |
| 455 460 | Returns the direct child nodes of a HTML tree. |
| 456 461 | |
| 457 | - By default, it will also include all texts. You can disable this behaviour |
| 458 | - by using the option `include_text` to `false` |
| 462 | + By default, it will also include all texts. You can disable |
| 463 | + this behaviour by using the option `include_text` to `false`. |
| 464 | + |
| 465 | + If the given node is not an HTML tag, then it returns nil. |
| 459 466 | |
| 460 467 | ## Examples |
| 461 468 | |
| @@ -465,9 +472,12 @@ defmodule Floki do | |
| 465 472 | iex> Floki.children({"div", [], ["text", {"span", [], []}]}, include_text: false) |
| 466 473 | [{"span", [], []}] |
| 467 474 | |
| 475 | + iex> Floki.children({:comment, "comment"}) |
| 476 | + nil |
| 477 | + |
| 468 478 | """ |
| 469 479 | |
| 470 | - @spec children(html_tree, Keyword.t()) :: html_tree |
| 480 | + @spec children(html_tree, Keyword.t()) :: html_tree | nil |
| 471 481 | |
| 472 482 | def children(html, opts \\ [include_text: true]) do |
| 473 483 | case html do |
| @@ -537,14 +547,18 @@ defmodule Floki do | |
| 537 547 | Enum.reduce( |
| 538 548 | elements, |
| 539 549 | [], |
| 540 | - fn {_, attributes, _}, acc -> |
| 541 | - case attribute_match?(attributes, attr_name) do |
| 542 | - {_attr_name, value} -> |
| 543 | - [value | acc] |
| 550 | + fn |
| 551 | + {_, attributes, _}, acc -> |
| 552 | + case attribute_match?(attributes, attr_name) do |
| 553 | + {_attr_name, value} -> |
| 554 | + [value | acc] |
| 544 555 | |
| 545 | - _ -> |
| 546 | - acc |
| 547 | - end |
| 556 | + _ -> |
| 557 | + acc |
| 558 | + end |
| 559 | + |
| 560 | + _, acc -> |
| 561 | + acc |
| 548 562 | end |
| 549 563 | ) |
| 550 564 | |
| @@ -591,6 +605,9 @@ defmodule Floki do | |
| 591 605 | iex> Floki.filter_out({"div", [], [{:comment, "comment"}, " text"]}, :comment) |
| 592 606 | {"div", [], [" text"]} |
| 593 607 | |
| 608 | + iex> Floki.filter_out({"div", [], ["text"]}, :text) |
| 609 | + {"div", [], []} |
| 610 | + |
| 594 611 | """ |
| 595 612 | |
| 596 613 | @spec filter_out(binary | html_tree, FilterOut.selector()) :: list |
| @@ -6,12 +6,12 @@ defmodule Floki.FilterOut do | |
| 6 6 | # Helper functions for filtering out a specific element from the tree. |
| 7 7 | |
| 8 8 | @type html_tree :: tuple | list |
| 9 | - @type selector :: :comment | Finder.selector() |
| 9 | + @type selector :: :comment | :text | Finder.selector() |
| 10 10 | |
| 11 11 | @spec filter_out(html_tree, selector) :: tuple | list |
| 12 12 | |
| 13 | - def filter_out(html_tree, :comment) do |
| 14 | - mapper(html_tree, :comment) |
| 13 | + def filter_out(html_tree, type) when type in [:text, :comment] do |
| 14 | + mapper(html_tree, type) |
| 15 15 | end |
| 16 16 | |
| 17 17 | def filter_out(html_tree, selector) do |
| @@ -49,6 +49,7 @@ defmodule Floki.FilterOut do | |
| 49 49 | |
| 50 50 | defp filter({nodetext, _, _}, selector) when nodetext === selector, do: false |
| 51 51 | defp filter({nodetext, _}, selector) when nodetext === selector, do: false |
| 52 | + defp filter(text, :text) when is_binary(text), do: false |
| 52 53 | defp filter(_, _), do: true |
| 53 54 | |
| 54 55 | defp mapper(nodes, selector) when is_list(nodes) do |
Loading more files…