Class: Katalyst::Content::TableHelper::TableNormalizer

Inherits:
Object
  • Object
show all
Defined in:
app/helpers/katalyst/content/table_helper.rb

Overview

rubocop:disable Rails/HelperInstanceVariable

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(table, heading: true) ⇒ TableNormalizer

Returns a new instance of TableNormalizer.



47
48
49
50
51
52
53
54
55
56
57
58
# File 'app/helpers/katalyst/content/table_helper.rb', line 47

def initialize(table, heading: true)
  @table   = table
  @heading = heading

  root  = ActionText::Fragment.from_html(table.content&.body&.to_html || "").source
  @node = root.name == "table" ? root : root.at_css("table")

  return unless @node

  @heading_rows = @table.heading_rows.clamp(0..css("tr").length)
  @heading_columns = @table.heading_columns.clamp(0..)
end

Instance Attribute Details

#heading_columnsObject (readonly)

Returns the value of attribute heading_columns.



43
44
45
# File 'app/helpers/katalyst/content/table_helper.rb', line 43

def heading_columns
  @heading_columns
end

#heading_rowsObject (readonly)

Returns the value of attribute heading_rows.



43
44
45
# File 'app/helpers/katalyst/content/table_helper.rb', line 43

def heading_rows
  @heading_rows
end

#nodeObject (readonly)

Returns the value of attribute node.



43
44
45
# File 'app/helpers/katalyst/content/table_helper.rb', line 43

def node
  @node
end

Instance Method Details

#set_caption!Object



60
61
62
63
64
# File 'app/helpers/katalyst/content/table_helper.rb', line 60

def set_caption!
  return if at_css("caption")

  prepend_child("<caption>#{@table.heading}</caption>")
end

#set_cell_type!(cell, row, col) ⇒ Object



105
106
107
# File 'app/helpers/katalyst/content/table_helper.rb', line 105

def set_cell_type!(cell, row, col)
  cell.name = col < heading_columns || row < heading_rows ? "th" : "td"
end

#set_header_columns!Object

convert cells between th and td based on heading_columns



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'app/helpers/katalyst/content/table_helper.rb', line 82

def set_header_columns!
  matrix = []

  css("tr").each_with_index do |row, y|
    row.css("td, th").each_with_index do |cell, x|
      # step right until we find an empty cell
      x += 1 until matrix.dig(y, x).nil?

      # update the type of the cell based on the heading configuration
      set_cell_type!(cell, y, x)

      # record the coordinates that this cell occupies in the matrix
      # e.g. colspan=2 rowspan=3 would occupy 6 cells
      row_range(cell, y).each do |ty|
        col_range(cell, x).each do |tx|
          matrix[ty] ||= []
          matrix[ty][tx] = cell.text
        end
      end
    end
  end
end

#set_header_rows!Object

move cells between thead and tbody based on heading_rows



67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'app/helpers/katalyst/content/table_helper.rb', line 67

def set_header_rows!
  rows = node.css("tr")

  if heading_rows > thead.css("tr").count
    rows.slice(0, heading_rows).reject { |row| row.parent == thead }.each do |row|
      thead.add_child(row)
    end
  else
    rows.slice(heading_rows, rows.length).reject { |row| row.parent == tbody }.reverse_each do |row|
      tbody.prepend_child(row)
    end
  end
end

#to_htmlObject



109
110
111
112
113
114
115
116
117
# File 'app/helpers/katalyst/content/table_helper.rb', line 109

def to_html
  return "" if @node.nil?

  set_caption! if @heading && @table.heading.present? && !@table.heading_none?
  set_header_rows!
  set_header_columns!

  @node.to_html
end