11: def each
12: state = :pre_head
13: meta_found = @encoding.nil?
14: pending = []
15:
16: __getobj__.each do |token|
17: case token[:type]
18: when :StartTag
19: state = :in_head if token[:name].downcase == "head"
20:
21: when :EmptyTag
22: if token[:name].downcase == "meta"
23:
24: token[:data].each_with_index do |(name, value), index|
25: if name == 'charset'
26: token[:data][index][1] = @encoding
27: meta_found = true
28: end
29: end
30:
31:
32: has_http_equiv_content_type = false
33: content_index = -1
34: token[:data].each_with_index do |(name, value), i|
35: if name.downcase == 'charset'
36: token[:data][i] = ['charset', @encoding]
37: meta_found = true
38: break
39: elsif name == 'http-equiv' and value.downcase == 'content-type'
40: has_http_equiv_content_type = true
41: elsif name == 'content'
42: content_index = i
43: end
44: end
45:
46: if !meta_found
47: if has_http_equiv_content_type && content_index >= 0
48: token[:data][content_index][1] = 'text/html; charset=%s' % @encoding
49: meta_found = true
50: end
51: end
52:
53: elsif token[:name].downcase == "head" && !meta_found
54:
55: yield :type => :StartTag, :name => "head", :data => token[:data]
56: yield :type => :EmptyTag, :name => "meta", :data => [["charset", @encoding]]
57: yield :type => :EndTag, :name => "head"
58: meta_found = true
59: next
60: end
61:
62: when :EndTag
63: if token[:name].downcase == "head" && pending.any?
64:
65: yield pending.shift
66: yield :type => :EmptyTag, :name => "meta", :data => [["charset", @encoding]] if !meta_found
67: yield pending.shift while pending.any?
68: meta_found = true
69: state = :post_head
70: end
71: end
72:
73: if state == :in_head
74: pending << token
75: else
76: yield token
77: end
78: end
79: end