def row(options = {}, &block)
      raise StandardError.new('row called within row block') if @in_row

      @in_row = true
      @col_offset = @col_start
      options = change_row(options || {})

      @row_cell_options = @base_cell_options.merge(options)

      fill_cells(@row_offset, @col_offset)

      # skip placeholders when starting a new row.
      if @data[@row_offset]
        while @data[@row_offset][@col_offset] == :span_placeholder
          @col_offset += 1
        end
      end

      yield if block_given?

      @in_row = false
      @row_offset += 1
      @row_cell_options = nil
    end
def row(options = {}, &block)
      raise StandardError.new('row called within row block') if @in_row

      @in_row = true
      @col_offset = @col_start
      options = change_row(options || {})

      @row_cell_options = @base_cell_options.merge(options)

      fill_cells(@row_offset, @col_offset)

      # skip placeholders when starting a new row.
      if @data[@row_offset]
        while @data[@row_offset][@col_offset] == :span_placeholder
          @col_offset += 1
        end
      end

      yield if block_given?

      @in_row = false
      @row_offset += 1
      @row_cell_options = nil
    end
Builds a row in the table.

 Valid options:

 row::
   Defines the row you want to start on.  If not set, then it uses #current_row.

 Additional options are merged with the base cell options for this row.

 When it completes, the #current_row is set to 1 more than the row we started on.