Skip to content

Instantly share code, notes, and snippets.

@BDQ
Created May 20, 2011 01:30
Show Gist options
  • Save BDQ/982174 to your computer and use it in GitHub Desktop.
Save BDQ/982174 to your computer and use it in GitHub Desktop.
Deface Parser Tester
require 'rubygems'
require 'diffy'
require 'nokogiri'
require 'cgi'
module Deface
class Parser
# converts erb to markup
#
def self.erb_markup!(source)
source.scan(/<\w+[^<>]+(?:<%.*?%>[^<>]*)+/m).each do |line|
erb_attrs_regexs = [/([\w-]+)(\s?=\s?)(")([^"]*<%.*?%>[^"]*)/m,
/([\w-]+)(\s?=\s?)(')([^']*<%.*?%>[^']*)'/m,
/([\w-]+)(\s?=\s?)()(<%.*?%>)(?:\s|>|\z)/m]
replace_line = erb_attrs_regexs.inject(line.clone) do |scan_line, regex|
replace_line = scan_line.scan(regex).inject(scan_line) do |replace_line, match|
replace_line.sub("#{match[0]}#{match[1]}#{match[2]}#{match[3]}#{match[2]}") { |m| m = " data-erb-#{match[0]}=\"#{CGI.escapeHTML(match[3])}\"" }
end
end
source.sub!(line) { |m| m = replace_line }
end
source.scan(/<\w+[^<>]+(?:<%.*?%>[^<>]*)+/m).each do |line|
i = -1
replace_line = line.scan(/(<%.*?%>)/m).inject(line.clone) do |replace_line, match|
replace_line.sub!(match[0]) { |m| m = " data-erb-#{i += 1}=\"#{CGI.escapeHTML(match[0])}\"" }
end
source.sub!(line) { |m| m = replace_line } if replace_line != line
end
replacements = [ {"<%=" => "<code erb-loud>"},
{"<%" => "<code erb-silent>"},
{"%>" => "</code>"} ]
replacements.each{ |h| h.each { |replace, with| source.gsub! replace, with } }
source.scan(/(<code.*?>)((?:(?!<\/code>)[\s\S])*)(<\/code>)/).each do |match|
source.sub!("#{match[0]}#{match[1]}#{match[2]}") { |m| m = "#{match[0]}#{CGI.escapeHTML(match[1])}#{match[2]}" }
end
source
end
# undoes ERB markup generated by Deface::Parser::ERB
#
def self.undo_erb_markup!(source)
replacements = [ {"<code erb-silent>" => '<%'},
{"<code erb-loud>" => '<%='},
{"</code>" => '%>'}]
replacements.each{ |h| h.each { |replace, with| source.gsub! replace, with } }
source.scan(/data-erb-(\d+)+=(['"])(.*?)\2/m).each do |match|
source.gsub!("data-erb-#{match[0]}=#{match[1]}#{match[2]}#{match[1]}") { |m| m = CGI.unescapeHTML(match[2]) }
end
source.scan(/data-erb-([\w-]+)+=(["'])(.*?)\2/m).each do |match|
source.gsub!("data-erb-#{match[0]}=#{match[1]}#{match[2]}#{match[1]}") { |m| "#{match[0]}=#{match[1]}#{CGI.unescapeHTML(match[2])}#{match[1]}" }
end
#un-escape changes from Nokogiri and erb-markup!
source.scan(/(<%.*?)((?:(?!%>)[\s\S])*)(%>)/).each do |match|
source.gsub!("#{match[0]}#{match[1]}#{match[2]}") { |m| m = "#{match[0]}#{ CGI.unescapeHTML match[1] }#{match[2]}" }
end
source
end
def self.convert(source)
erb_markup!(source)
if source =~ /(<html.*?)((?:(?!>)[\s\S])*)(>)/
Nokogiri::HTML::Document.parse(source)
else
Nokogiri::HTML::DocumentFragment.parse(source)
end
end
end
end
pass = 0
warn = 0
beginning = Time.now
Dir.glob("./**/*.html.erb") do |template|
file = File.open(template, "rb")
original = file.read
converted = Deface::Parser.convert(original.clone).to_s
result = Deface::Parser.undo_erb_markup!(converted.clone)
#check for tail tale signs of Deface fuckups!
if ["erb-", "&lt;%", "%&gt;"].any? {|trace| result.include? trace }
warn += 1
puts Diffy::Diff.new(original, result).to_s(:color)
puts template
else
pass += 1
end
#if original.gsub(/&nbsp;|\s|'|"/, '') != result.gsub(/&nbsp;|\s|'|"/, '')
# puts template
# puts Diffy::Diff.new(original, result).to_s(:color)
#end
end
puts "Pass: #{pass} Warn: #{warn}"
puts "Time elapsed #{Time.now - beginning} seconds"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment