aphillipo
Excerpt implementation for Floki
Hello there! I’ve been working on an Excerpt implementation on top of Floki that greedily includes tags. I’d love for the next step to be able to preserve tags but this is a good starting point; any advice on that welcome.
Let me know if there is anything I could improve or if there are any performance issues I’m encountering by using recursion for this. It’s also worth noting this is an adaption
of the DeepText search that comes with Floki for my own needs.
defmodule PayPip.Text do
@moduledoc """
PayPip.Text is a strategy to get text nodes from a HTML tree using a deep search
algorithm limited to a certain length + the full content of the final node. It will
get all string nodes and concat them into an accumulator up to that point.
"""
@type html_tree :: tuple | list
@doc """
Get text nodes of a desired length + final node length.
## Examples
iex> PayPip.Text.get([{"a", [], ["The meaning of life is...", {"strong", [], ["something else"]}] }], 5)
{"The meaning of life is...", 20}
iex> PayPip.Text.get([{"a", [], ["The meaning of life is...", {"strong", [], ["something else"]}] }], 140, " ")
{"The meaning of life is... something else", -101}
"""
@spec get(html_tree, number, binary) :: {binary, number}
def get(html_tree, max_length \\ 255, sep \\ "") do
get_text(html_tree, {"", max_length}, sep)
end
# initial piece of text
defp get_text(text, {"", max_length}, _sep) when is_binary(text), do: {text, max_length - String.length(text)}
# all other text
defp get_text(text, {acc, max_length}, sep) when is_binary(text) do
{Enum.join([acc, text], sep), max_length - String.length(text)}
end
# deal with nodes lists and sort out over count to be correct (negative when under original max_length)
defp get_text(nodes, {acc, max_length}, sep) when is_list(nodes) do
Enum.reduce_while nodes, {acc, max_length}, fn(child, istr) ->
if max_length > 0 do
{final_acc, final_length} = get_text(child, istr, sep)
{:cont, {final_acc, -final_length}}
else
{:halt, {acc, -max_length}}
end
end
end
# ignore comments
defp get_text({:comment, _}, {acc, max_length}, _), do: {acc, max_length}
# turn BR tags into new lines
defp get_text({"br", _, _}, {acc, max_length}, _), do: {acc <> "\n", max_length - 1}
# process children
defp get_text({_, _, nodes}, acc, sep) do
get_text(nodes, acc, sep)
end
end
Popular in Discussions
Erlang :list.nth simple, but 1 - based
nth(1, [H|_]) -> H;
nth(N, [_|T]) when N > 1 ->
nth(N - 1, T).
Elixir Enum.at … coo...
New
If a newbie asked you about Phoenix Contexts, how would you explain the basics to them?
Feel free to be as concise or in-depth as you li...
New
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
New
Phoenix Live View is now publicly available on GitHub.
Here’s Chris McCord’s tweet announcing making it public.
New
Hi all,
In the last days, two things happened:
A blog post titled “They might never tell you it’s broken” made the rounds. It’s about ...
New
Background
This question comes mainly from my ignorance. Today is Black Friday, one of my favorite days of the year to buy books. One boo...
New
Hello everyone,
Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
Other popular topics
Hi,
I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
What is the idiomatic way of matching for not nil in Elixir?
E.g.,
First way:
defp halt_if_not_signed_in(conn, signed_in_account) when...
New
Hi,
I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
I am trying to run a deploy with docker and I successfully runned with this command:
docker build -t romenigld/blog-prod .
but when I t...
New
Chat & Discussions>Discussions
Latest on Elixir Forum
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









