f34nk

f34nk

ModestEx - Pipeable transformations on html strings (with CSS selectors)

Hello!

I just published my first draft of ModestEx, a Elixir/Erlang binding to lexborisov’s Modest library.

Modest is a fast HTML renderer implemented as a pure C99 library with no outside dependencies.

ModestEx exposes features to do pipeable transformations on html strings with CSS selectors, e.g. find(), prepend(), append(), replace() etc.

iex> ModestEx.find("<p><a>Hello</a> World</p>", "p a")
{:ok, "<a>Hello</a>"}

iex> ModestEx.serialize("<div>Hello<span>World")
{:ok, "<html><head></head><body><div>Hello<span>World</span></div></body></html>"}

The binding is implemented as a C-Node following the excellent example in @Overbryd 's package nodex. If you want to learn how to set up bindings to C/C++, you should definitely check it out.

Before that I experimented with a lot of other Html parser libraries like gumbo-parser, gumbo-query and GQ. I even implemented a binding package called gumbo_query_ex.
However Modest is currently the most active and most promising.

This project is under development!
Stay tuned for more features like ModestEx.remove, ModestEx.prepend, ModestEx.append

Tell me what you think :relaxed:

Best, F34nk

First Post!

OvermindDL1

OvermindDL1

Ah it looks like a C-based variant of Meeseeks except it can also create HTML too, quite nice! :slight_smile:

Most Liked

f34nk

f34nk

Release v1.0.0

This release is stable.

def deps do
  [
    {:modest_ex, "~> 1.0.0"}
  ]
end

Total 16 features implemented. See complete feature list.

Total 38 selector patterns implemented (including custom selector :contains(text)).
See complete list of supported CSS selectors.

The package includes all binding code under the folder target/modest_worker.
All Modest related features are implemented in a single C library called modest_html.

This way, all features are tested in a C environment using CMake/CTest with memory tracking enabled using a library called dmt.

Please feel invited to check it out :relaxed:

Best, F34nk

f34nk

f34nk

Thanks guys!

I have a use case where a request reads html from a database and before rendering I need to do some changes on the html string. In my case the html is quite large and the changes are quite extensive.

The idea for ModestEx is to implement a set of features that just do transformations on a html string. Each transformation feature will be done in C.

Something like:

result ModestEx.find("<p><a>Hello</a> World</p>", "p a")
|> ModestEx.attribute("href", "https://elixir-lang.org")

will return:

{:ok,  "<a href=\"https://elixir-lang.org\">Hello</a>"}

… ready to render in a template.

Or you could also serialize it:

ModestEx.serialize(result)

and return:

{:ok,  "<html><head></head><body><a href=\"https://elixir-lang.org\">Hello</a></body></html>"}

Which is already a (more or less) valid page!

Of course, if you need further decoding htmlex, floki or Meeseeks are great!
I see ModestEx as a useful addition to the landscape of html tools in Elixir.

f34nk

f34nk

Hey @mischov @OvermindDL1

I just published ModestEx v0.0.2-dev.

Thanks again for your input. It’s a lot clearer now what the main strength of the library actually is!

I added a new feature ModestEx.get_attribute and ModestEx.set_attribute.

And you can actually pipe them together.

iex> ModestEx.find("<p><a>Hello</a><a>World</a></p>", "p a") |> 
...> ModestEx.set_attribute("href", ["https://elixir-lang.org", "https://google.de"])
["<html><head></head><body><a href=\"https://elixir-lang.org\">Hello</a></body></html>", "<html><head></head><body><a href=\"https://google.de\">World</a></body></html>"]

Last Post!

f34nk

f34nk

New version ModestEx v2.0.0 is published to hex.pm :tada:

Where Next?

Popular in Announcing Top

mischov
import Meeseeks.CSS html = HTTPoison.get!("https://news.ycombinator.com/").body for story &lt;- Meeseeks.all(html, css("tr.athing")) do...
New
tmbb
I’ve published the first version of my Makeup library. It’s a syntax highlighter for Elixir in the spirit of Pygments, Currently it highl...
New
michalmuskala
Hello everybody. I have just released Jason - a new JSON library. You might be wondering, why do we need a new library? The primary foc...
New
bryanjos
Hi, I wanted share a small library we at Revelry Labs made for rendering react components from the server side. There are instructions fo...
New
mspanc
I am pleased to announce an initial release of the Membrane Framework - an Elixir-based framework with special focus on processing multim...
New
nikokozak
Hello all, I’ve been working on Svonix - a library for quickly integrating Svelte components into Phoenix views. It’s a much-needed succ...
New
scohen
Lexical Lexical is a next-generation language server for the Elixir programming language. Features Context aware code completion As-you...
New

Other popular topics Top

baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
siddhant3030
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
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

We're in Beta

About us Mission Statement