Can we scrape html elements and add css to them using hpricot gem?

99 views Asked by At

Initially, I have a string of html and text content.

I want to add css stylings to certain html elements from the above string. How can I achieve this using hpricot gem? I am able to scrap out the html elements by using each loop. But how do I take it further?

For eg, I have the following string:

"<pre>//code snippet 1</pre><p>Table:</p><table><tbody><tr><td>1</td><td>2</td><td>3</td></tr><tr><td>4</td><td>5</td><td>6</td></tr></tbody></table>"

Then, I can access all the td elements by using:

string.search("//td").each do |ele|
  //some code needed to add css to ele
end
2

There are 2 answers

0
Jesper On

Hpricot has been abandoned, so you'd be better off using for example Nokogiri.

I made this example using Nokogiri. You can use the []= method to add arbitrary attributes to a node. We use this to add a style attribute.

require 'nokogiri'

my_string_fragment = 
  "<pre>//code snippet 1</pre><p>Table:</p>
  <table>
    <tbody>
      <tr>
        <td>1</td><td>2</td><td>3</td></tr><tr><td>4</td><td>5</td><td>6</td>
      </tr>
    </tbody>
  </table>"

html_fragment = Nokogiri::HTML::DocumentFragment.parse(my_string_fragment)

html_fragment.css("td").each do |cell|
  cell["style"] = "color: red"
end

puts html_fragment

# Prints this:
#
# <pre>//code snippet 1</pre><p>Table:</p>
# <table>
#   <tbody>
#     <tr>
#       <td style="color: red">1</td>
#       <td style="color: red">2</td>
#       <td style="color: red">3</td>
#     </tr>
#     <tr>
#       <td style="color: red">4</td>
#       <td style="color: red">5</td>
#       <td style="color: red">6</td>
#     </tr>
#   </tbody>
# </table>

I used DocumentFragment, because otherwise Nokogiri will make sure that our fragment becomes a full HTML document by adding the html tag.

Keep in mind that adding inline CSS styles like this is considered bad practice.

0
Radhika On

Instead of using hpricot or nokogiri I found a better/cleaner way to achieve what I wanted. I used premailer-rails gem. It requires nokogiri or hpricot gem to work with. But all we need to do is add this gem and it automatically converts external css to inline css.

Reference to the gem: premailer-rails