require "nokogiri"

module Rack
  class Pygments

    def initialize(app, opts={})
      @app = app
      @tag = opts[:html_tag].nil? ? 'highlight' : opts[:html_tag] 
      @attr = opts[:html_attr].nil? ? 'lang' : opts[:html_attr]
      if system("which pygmentize > /dev/null")
        @bin = `which pygmentize`.chomp
      else
        raise Exception, "Pygmentize is missing"
      end
    end
    
    def call(env)
      if env["PATH_INFO"] !~ /.*\.css$/
      status, headers, response = @app.call(env)
      content = response.instance_variable_get("@body").to_s
        document = Nokogiri::HTML(content)
        nodes = document.css(@tag)
        nodes.each do |node|
          lang = node.attribute(@attr).nil? ? 'bash' : node.attribute(@attr).value
          pygmentize = `echo '#{node.content}' | #{@bin} -l #{lang} -f html`
          node.replace(Nokogiri::HTML(pygmentize).css("div.highlight").first)
        end
        response = document.to_s
        headers["Content-Length"] = response.length.to_s
        [status,headers,[response]]
      else
        @app.call(env)
      end
    end
  end
end

require "nokogiri"

module Rack
  class Pygments

    def initialize(app, opts={})
      @app = app
      @tag = opts[:html_tag].nil? ? 'highlight' : opts[:html_tag] 
      @attr = opts[:html_attr].nil? ? 'lang' : opts[:html_attr]
      if system("which pygmentize > /dev/null")
        @bin = `which pygmentize`.chomp
      else
        raise Exception, "Pygmentize is missing"
      end
    end

    def call(env)
      if env["PATH_INFO"] !~ /.*\.css$/
      status, headers, response = @app.call(env)
      content = response.each.map.join
        document = Nokogiri::HTML(content)
        nodes = document.css(@tag)
        nodes.each do |node|
          lang = node.attribute(@attr).nil? ? 'bash' : node.attribute(@attr).value
          pygmentize = `echo '#{node.content}' | #{@bin} -l #{lang} -f html`
          node.replace(Nokogiri::HTML(pygmentize).css("div.highlight").first)
        end
        response = document.to_s
        headers["Content-Length"] = response.length.to_s
        [status,headers,[response]]
      else
        @app.call(env)
      end
    end
  end
end

Update to work with current Rack
Update to work with current Rack

There isn't a @body instance variable in the part
of the Rack response representing the body. Using
[]#each to yield Strings as per the Rack spec.
