Class: Docp::Table

Inherits:
Object
  • Object
show all
Extended by:
TableRemoveMethods, Forwardable
Includes:
TableRemoveMethods, Enumerable
Defined in:
lib/docp/table.rb

Defined Under Namespace

Classes: HeaderCountNotMatchError, RequiredAttributesUndefined

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from TableRemoveMethods

colspan_join, doc_remove_attributes, rowspan_flatten, rowspan_join

Constructor Details

#initialize(doc, header_parser, table, header_tr, header_index) ⇒ Table

Returns a new instance of Table.



52
53
54
55
56
57
58
59
# File 'lib/docp/table.rb', line 52

def initialize doc, header_parser, table, header_tr, header_index
  @doc = doc
  @this_table = Nokogiri::XML::Element.new("table", @doc)
  @header_parser = header_parser.child || header_parser
  if @header_parser.columns.any?
    parse_table table, header_tr, header_index
  end
end

Instance Attribute Details

#docObject (readonly)

Returns the value of attribute doc.



50
51
52
# File 'lib/docp/table.rb', line 50

def doc
  @doc
end

#header_required_undefinedsObject (readonly)

Returns the value of attribute header_required_undefineds.



51
52
53
# File 'lib/docp/table.rb', line 51

def header_required_undefineds
  @header_required_undefineds
end

Class Method Details

.find(src_doc, header_parser) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/docp/table.rb', line 21

def find src_doc, header_parser
  header_parser = header_parser.is_a?(Hash) ? TableHeader.new(nil, header_parser) : header_parser
  src_doc = Nokogiri::HTML(src_doc) if src_doc.is_a?(String)
  parse_doc = src_doc.respond_to?(:to_html) ?  Nokogiri::HTML(src_doc.to_html) : Nokogiri::HTML(src_doc.parser.to_html)
  parse_doc.search('//table').each {|table, i|
    next if table.at('table') || table.at('tr table')
    table.search('tr').map.with_index do|tr, header_index|
      break if header_parser.exclude_ptn?(tr)
      next unless header_parser.include_ptn?(tr)
      next unless header_parser.required_all?(tr)
      yield table, tr, header_index
      break
    end
  }
end

.header_required_all?(header_tr, header_parser) ⇒ Boolean

Returns:

  • (Boolean)


37
38
39
# File 'lib/docp/table.rb', line 37

def header_required_all? header_tr, header_parser

end

.parse(parse_doc, header_parser, &block) ⇒ Object



17
18
19
# File 'lib/docp/table.rb', line 17

def parse parse_doc, header_parser, &block
  TableDoc.new.parse(parse_doc, header_parser, &block)
end

Instance Method Details

#each(args = {}) ⇒ Object Also known as: rows_each



123
124
125
126
127
128
129
130
131
132
133
# File 'lib/docp/table.rb', line 123

def each args = {}
  @this_table.search('tr').each {|tr|
    header = tr.at('.table-header')
    next if args[:header].nil? && tr[:class] == "table-header" 
    next if tr.row_elements.select {|td| td[:class]}.empty?
    yield extend_row(header) if args[:header]
    if row_required_all?(tr.row_elements)
      yield extend_row(tr)
    end
  }
end

#errorsObject



118
119
120
121
# File 'lib/docp/table.rb', line 118

def errors
  mes = @this_table.search('tr').map {|tr| tr[:error]}.compact
  mes
end

#extend_row(tr) ⇒ Object



114
115
116
# File 'lib/docp/table.rb', line 114

def extend_row tr
  TableRow.new(tr, @header_parser)
end

#get_row_class_names(tr_elements) ⇒ Object



102
103
104
105
106
107
# File 'lib/docp/table.rb', line 102

def get_row_class_names tr_elements
  tr_elements.map {|td| 
    next unless td[:class]
    td[:class].split(",").map(&:to_sym)
  }.compact.flatten
end

#headerObject



135
136
137
138
# File 'lib/docp/table.rb', line 135

def header
  #@this_table.at('.table-header')
  extend_row @this_table.at('.table-header')
end

#parse_table(table, header_tr, header_index) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/docp/table.rb', line 61

def parse_table table, header_tr, header_index
  @header_parser.before_parse.call(table) if @header_parser.before_parse
  doc_remove_attributes(table)
  if @header_parser.vertical
    header_tr = @this_table.add_child Nokogiri::XML::Element.new("tr", @doc)
    row_tr = @this_table.add_child Nokogiri::XML::Element.new("tr", @doc)
    header_tr[:class] = "table-header"
    table.row_elements.each do|td|
      @header_parser.columns.select {|c| c.include_ptn?(td)}.each do|col|
        if td[:class]
          td[:class] = "#{td[:class]},#{col.name}"
          header_tr.row_elements.last[:class] = td[:class]
        else
          td[:class] = col.name
          header_tr.add_child td.clone
        end
        
        if ntd = td.next_element
          ntd[:class] = col.name
          row_tr.add_child ntd.clone
        else
          #raise "NextElementNotfound #{ntd.class} #{ntd}\n"
        end
      end
    end
    #set_vertical_row_attributes(header_tr)
    @doc.add_child(@this_table)
  else
    #if header_required_all?(header_tr)
      if row_elements = table.search('tr')[header_index..-1]
        header_tr[:class] = "table-header"
        @this_table.add_child row_elements
        set_header_attributes(header_tr)
        set_row_attributes(header_tr, @this_table.search('tr')[1..-1])
        @doc.add_child(@this_table)
      end
    #end
  end
  self
end

#row_required_all?(tr_elements) ⇒ Boolean

Returns:

  • (Boolean)


109
110
111
112
# File 'lib/docp/table.rb', line 109

def row_required_all? tr_elements
  ret = get_row_class_names(tr_elements).select {|name| @header_parser.required_keys.include?(name)}
  ret.count >= @header_parser.required_keys.count
end

#rows(args = {}) ⇒ Object



140
141
142
143
144
145
# File 'lib/docp/table.rb', line 140

def rows args = {}
  [].tap {|ret|
    each(args) {|row| 
      ret << row.tap {|r| yield r if block_given?} }
  }
end

#set_header_attributes(tr) ⇒ Object

def set_vertical_row_attributes tr

  tr.row_elements.each {|td|
    @header_parser.columns.each do|col|
      if col.include_ptn?(td)
        if ntd = td.next_element
          ntd[:class] = ntd[:class] ? "#{ntd[:class]},#{col.name}" : col.name
        end
      end
    end
  }
end


163
164
165
166
167
168
169
170
171
# File 'lib/docp/table.rb', line 163

def set_header_attributes tr
  tr.row_elements.each {|td|
    @header_parser.columns.each do|col|
      if col.include_ptn?(td)
        td[:class] = td[:class] ? "#{td[:class]},#{col.name}" : col.name
      end
    end
  }
end

#set_row_attributes(header_tr, tr_rows) ⇒ Object



173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/docp/table.rb', line 173

def set_row_attributes header_tr, tr_rows
  tr_rows.each_with_index {|tr, i|
    if header_tr.row_elements.count != tr.row_elements.count
      tr[:error] = "#{HeaderCountNotMatchError}"
    end
    header_tr.row_elements.each_with_index do|h, x|
      next if h[:class].nil? || tr.row_elements[x].nil?
      tr.row_elements[x][:class] = h[:class] if h[:class]
    end
    unless row_required_all?(tr.row_elements)
      tr[:error] = "#{RequiredAttributesUndefined}" 
    end
  }
end