2010-05-30 6 views
8

J'ai passé mes deux heures nécessaires Googling ceci, et je ne peux pas trouver de bonnes réponses, alors voyons si les humains peuvent battre les ordinateurs Google. Je veux analyser une feuille de style dans Ruby afin que je puisse appliquer ces styles aux éléments de mon document (pour rendre les styles inline). Donc, je veux prendre quelque chose commeEst-il possible d'analyser une feuille de style avec Nokogiri?

<style> 
.mystyle { 
    color:white; 
} 
</style> 

et être capable de l'extraire dans un objet Nokogiri de quelque sorte. La classe Nokogiri "CSS :: Parser" (http://nokogiri.rubyforge.org/nokogiri/Nokogiri/CSS/Parser.html) a certainement un nom prometteur, mais je ne trouve aucune documentation sur ce que c'est ou comment cela fonctionne, donc je ne sais pas si elle peut faire ce que je suis après ici.

Mon objectif final est de pouvoir écrire du code quelque chose comme:

a_web_page = Nokogiri::HTML(html_page_as_string) 
parsed_styles = Nokogiri::CSS.parse(html_page_as_string) 
parsed_styles.each do |style| 
    existing_inlined_style = a_web_page.css(style.declaration) || '' 
    a_web_page.css(style.declaration)['css'] = existing_inlined_style + style.definition 
end 

qui va extraire les styles d'une feuille de style et les ajouter que les styles inline à mon document.

Répondre

4

@molf avait certainement un bon départ là-bas, mais il reste nécessaire de débogage une poignée de problèmes pour le faire fonctionner dans la production. Voici le courant, la version testée de ceci:

html = Nokogiri::HTML(html_string) 
css = CssParser::Parser.new 
css.add_block!(html_string) # Warning: This line modifies the string passed into it. In potentially bad ways. Make sure the string has been duped and stored elsewhere before passing this. 

css.each_selector do |selector, declarations, specificity| 
    next unless selector =~ /^[\d\w\s\#\.\-]*$/ # Some of the selectors given by css_parser aren't actually selectors. 
    begin 
    elements = html.css(selector) 
    elements.each do |match| 
     match["style"] = [match["style"], declarations].compact.join(" ") 
    end 
    rescue 
    logger.info("Couldn't parse selector '#{selector}'") 
    end 
end 

html_with_inline_styles = html.to_s 
15

Nokogiri ne peut pas analyser les feuilles de style CSS.

Le CSS::Parser que vous avez rencontré analyse CSS expressions. Il est utilisé chaque fois que vous traversez un arbre HTML par des sélecteurs CSS plutôt que XPath (ceci est un cool feature de Nokogiri). Il existe cependant un Ruby CSS parser. Vous pouvez l'utiliser avec Nokogiri pour réaliser ce que vous voulez.

require "nokogiri" 
require "css_parser" 

html = Nokogiri::HTML(html_string) 

css = CssParser::Parser.new 
css.add_block!(css_string) 

css.each_selector do |selector, declarations, specificity| 
    element = html.css(selector) 
    element["style"] = [element["style"], declarations].compact.join(" ") 
end 
+1

html.css (sélecteur) retourne un tableau d'éléments. Donc ça devrait être elements.each do | element | – Alagu

Questions connexes