lib/copy_paste_pdf/table.rb
module CopyPastePDF
class Table < Array
# Removes all empty rows from the table.
def remove_empty_rows!
reject! do |row|
row.all?(&:nil?)
end
end
# Copies the values of the given cells from a line to any following lines
# whose corresponding cells are empty.
#
# @param [Array] indices the cell indices to copy
# @yieldparam [Array] row a row in the table
# @yieldreturn [Boolean] whether to skip the row from the table
# @raise [CopyPastePDF::MissingSourceError] if a destination has no source
# @raise [CopyPastePDF::CopyToNonEmptyCellError] if a destination cell
# already has a value
# @raise [CopyPastePDF::InvalidRowError] if a row is neither a source nor a
# destination
def copy_into_cell_below(*indices)
source = nil
each do |row|
if !block_given? || !yield(row)
values = row.values_at(*indices)
case values.count(&:nil?)
when 0
source = values
when indices.size
if source
indices.each_with_index do |index,i|
if row[index]
raise CopyToNonEmptyCellError, "destination cell #{index} already has a value #{row[index]}"
else
row[index] = source[i]
end
end
else
raise MissingSourceError, "#{row} is a destination, but it has no source"
end
else
raise InvalidRowError, "#{row} is neither a source nor a destination"
end
end
end
end
# Merges the values of the given cells from a line, whose other cells are
# empty, into the corresponding cells of the prececeding line.
#
# @param [Array] indices the cell indices to merge
# @raise [CopyPastePDF::MergeWithEmptyCellError] if a destination cell is empty
def merge_into_cell_above(*indices)
each_with_index.reverse_each do |row,i|
if row.each_with_index.all?{|value,j| value.nil? || indices.include?(j)}
indices.each do |index|
if self[i - 1][index]
self[i - 1][index] = "#{self[i - 1][index]}\n#{row[index]}"
else
raise MergeWithEmptyCellError, "cell #{index} is empty and can't be merged"
end
end
delete_at(i)
end
end
end
end
end