11

必要な 2 時間かけてこれをグーグルで調べましたが、良い答えが見つからないので、人間がグーグルのコンピュータに勝てるか見てみましょう。

これらのスタイルをドキュメント内の要素に適用できるように (スタイルをインライン化するために)、Ruby でスタイルシートを解析したいと考えています。だから、私は次のようなものを取りたい

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

そして、それをある種のノコギリオブジェクトに抽出することができます.

Nokogiri クラス「CSS::Parser」( http://nokogiri.rubyforge.org/nokogiri/Nokogiri/CSS/Parser.html ) には確かに有望な名前がありますが、それが何であるか、またはどのようにそれは機能するので、私がここで求めていることができるかどうかはわかりません。

私の最終目標は、次のようなコードを記述できるようにすることです。

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

スタイルシートからスタイルを抽出し、それらをすべてインライン スタイルとしてドキュメントに追加します。

4

2 に答える 2

15

Nokogiri は CSS スタイルシートを解析できません。

遭遇したCSS::Parserは、CSSを解析します。これは、XPath ではなく CSS セレクターによって HTML ツリーをトラバースするときに使用されます (これはNokogiri の優れた機能です)。

ただし、Ruby CSS パーサーはあります。のこぎりと合わせて使用​​することで、目的を達成できます。

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|
  html.css(selector).each do |element|
    style = element.attributes["style"]&.value || ""
    element.set_attribute('style', [style, declarations].compact.join(" "))
  end
end
于 2010-05-30T21:56:16.213 に答える
3

@molf は確かに素晴らしいスタートを切りましたが、本番環境で機能させるには、いくつかの問題をデバッグする必要がありました。これは、これの現在のテスト済みバージョンです。

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 
于 2010-06-07T01:29:26.330 に答える