Class: CFML::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/cfml/parser.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(content, opts = {}) ⇒ Parser

Returns a new instance of Parser.



5
6
7
8
9
10
11
12
# File 'lib/cfml/parser.rb', line 5

def initialize(content, opts = {})
  @opts = opts
  @doc = Parser.parse(content)
  @cftags = @doc.xpath("//cf:*[not(ancestor::cf:*)]")
  @tags = @cftags.map do |t|
    tag_class(t.name).new(t, @opts)
  end
end

Instance Attribute Details

#cftagsObject (readonly)

Returns the value of attribute cftags.



3
4
5
# File 'lib/cfml/parser.rb', line 3

def cftags
  @cftags
end

#docObject (readonly)

Returns the value of attribute doc.



3
4
5
# File 'lib/cfml/parser.rb', line 3

def doc
  @doc
end

#errorsObject (readonly)

Returns the value of attribute errors.



3
4
5
# File 'lib/cfml/parser.rb', line 3

def errors
  @errors
end

#tagsObject (readonly)

Returns the value of attribute tags.



3
4
5
# File 'lib/cfml/parser.rb', line 3

def tags
  @tags
end

Class Method Details

.escape(string) ⇒ Object



87
88
89
90
91
92
# File 'lib/cfml/parser.rb', line 87

def self.escape( string )
  string.to_s.gsub( /&/, "&" ).
         gsub( /</, "&lt;" ).
         gsub( />/, "&gt;" ).
         gsub( /"/, "&quot;" )
end

.parse(content) ⇒ Object



14
15
16
# File 'lib/cfml/parser.rb', line 14

def self.parse(content)
  Nokogiri::XML("<root xmlns:cf='http://crowdflower.com'>#{content}</root>")
end

Instance Method Details

#convertObject



18
19
20
21
22
23
# File 'lib/cfml/parser.rb', line 18

def convert
  @cftags.each_with_index do |t,i|
    t.replace(@tags[i].convert)
  end
  @doc
end

#fieldsObject



25
26
27
28
29
30
31
32
# File 'lib/cfml/parser.rb', line 25

def fields
  @fields = {}
  @tags.each do |g|
    agg = g.attrs["aggregation"]
    @fields[g.name] = agg.to_s if agg
  end
  @fields
end

#goldsObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/cfml/parser.rb', line 34

def golds
  return @golds if @golds
  @golds = {}
  @tags.each do |g|
    gold = g.gold?
    next unless gold
    val = (gold.attributes["gold"] || gold.attributes["src"]).to_s
    val = "#{g.name}_gold" if val =~ /^(true|\s*)$/
    @golds[g.name] = val
    ["strict","regex"].each do |attrs|
      if a = gold.attributes[attrs]
        @golds["_#{val}_#{attrs}"] = attrs == "regex" ? [a.to_s, gold.attributes["flags"].to_s] : a.to_s
      end
    end
  end
  @golds
end

#to_htmlObject



82
83
84
85
# File 'lib/cfml/parser.rb', line 82

def to_html
  convert
  wrap(@doc.at("root").inner_html)
end

#valid?Boolean

Returns:

  • (Boolean)


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/cfml/parser.rb', line 52

def valid?
  @errors = []
  @doc.errors.each do |e|
    @errors << "Malformed HTML.  #{e.message.chomp} on line #{e.line} column #{e.column}."
  end
  @tags.select {|t| t.validate? && t.name =~ /^\s*$/ }.each do |t|
    @errors << ["#{t.to_s.split("\n")[0]} does not have a label or name specified."]
  end
  dupes = @tags.select do |tag|
    tag.validate? && @tags.select {|t| t.name == tag.name}.length > 1
  end
  (dupes[1..-1] || []).each do |t|
    @errors << ["#{t.to_s.split("\n")[0]} has a duplicated name, please specify a unique name attribute."]
  end
  @tags.each do |t|
    next unless t.children
    dupes = t.children.select do |child|
      t.children.select {|c| c.value == child.value}.length > 1
    end
    (dupes[1..-1] || []).each do |c|
      @errors << ["#{c} a child of #{t.to_s.split("\n")[0]} has a duplicated value, please specify a unique value attribute."]
    end
  end
  @errors.length == 0
end

#wrap(content) ⇒ Object



78
79
80
# File 'lib/cfml/parser.rb', line 78

def wrap(content)
  @opts[:no_wrap] ? content : "<div class=\"cfml #{@opts[:prefix]}\">#{content}</div>"
end