require 'erb'
require 'ostruct'
class Generator
attr_reader :tags, :attributes
BASEDIR = File.dirname(__FILE__)
OUT_FILE = File.join(BASEDIR, '../src/dom/html/meta.rs')
def run(out_file = OUT_FILE)
parse_tags
parse_attributes
map_basic_attributes
generate(out_file)
end
FLAGS = {
'E' => 'empty',
'D' => 'deprecated',
'I' => 'inline',
'M' => 'meta',
'B' => 'banned',
'U' => 'undefined'
}
def parse_tags
@tags = []
open(File.join(BASEDIR, 'tags'), 'r') do |fin|
fin.each do |line|
case line
when /^\s*#/, /^\s*$/
when /^\s*[^\s,]+\s*,[^,]*,[^,]*$/
r = line.split(',').map { |c| c.strip }
r = r.compact.reject { |c| c.empty? }
flags = r[1].split(' ').map { |f| FLAGS[f] }.compact
@tags << OpenStruct.new(
:name => r[0],
:flags => flags,
:desc => r[2]
)
else
raise "Parse ERROR: line [#{line}]"
end
end
end
@tags.sort_by! { |o| o.name }
@tags.uniq! { |o| o.name }
@tag_max_len = @tags.map { |t| t.name.length }.max
end
def parse_attributes
@attributes = []
tagsets = {}
open(File.join(BASEDIR, 'attributes'), 'r') do |fin|
fin.each do |line|
case line
when /^\s*#/, /^\s*$/
when /^\s*([A-Z]+)\s*::\s*ALL\s+except:(.*)$/
sname = $1
except = $2.split(' ').compact.reject { |t| t.empty? }
tset = @tags.reject { |t| except.include?(t.name) }
tset.map! { |t| t.name }
tagsets[sname] = tset
when /^\s*[^\s,]+\s*,/
r = line.split(',').map { |c| c.strip }
r = r.compact.reject { |c| c.empty? }
if r[3]
flags = r[3].split(' ').map { |f| FLAGS[f] }.compact
else
flags = []
end
btags = r[1].split(' ').compact.reject { |t| t.empty? || t =~ /^\*/ }
btags = btags.map { |t| tagsets[ t ] || t }.flatten
@attributes << OpenStruct.new(
:name => r[0],
:basic_tags => btags,
:flags => flags,
:desc => r[2]
)
else
raise "Parse ERROR: line [#{line}]"
end
end
end
@attributes.sort_by! { |o| o.name }
@attributes.uniq! { |o| o.name }
@attr_max_len = @attributes.map { |t| t.name.length }.max
end
def map_basic_attributes
@tags.each do |tag|
tag.basic_atts =
@attributes.select { |attr| attr.basic_tags.include?(tag.name) }
end
end
def twidth(val, extra = 0)
val + (' ' * (@tag_max_len - val.length + extra))
end
def awidth(val, extra = 0)
val + (' ' * (@attr_max_len - val.length + extra))
end
def const(val)
val.gsub(/\-/, '_')
end
def clone_if(o, val)
if o.flags.include?('undefined')
"#{val}.clone()"
else
val
end
end
def tags_with(flag)
@tags
.select {|t| t.flags.include?(flag) }
.map { |t| t.name }
.join(' ')
end
def map_flags(tag)
tag.flags
.reject { |f| f == "undefined" }
.map { |f| "is_#{f}: true" }
end
def generate(out_file)
erb_file = File.join(BASEDIR, 'meta.rs.erb')
template = ERB.new(IO.read(erb_file), nil, '%')
open(out_file, 'w') do |fout|
fout << template.result(binding)
end
end
end
if $0 == __FILE__
Generator.new.run(*ARGV)
end