Class: CSVPlusPlus::Template

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/csv_plus_plus/template.rb

Overview

Contains the data from a parsed csvpp template.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rows:, runtime:) ⇒ Template

Returns a new instance of Template.

Parameters:

  • rows (Array<Row>)

    The Rows that comprise this Template

  • runtime (Runtime)

    The Runtime containing all function and variable references



21
22
23
24
# File 'lib/csv_plus_plus/template.rb', line 21

def initialize(rows:, runtime:)
  @rows = rows
  @runtime = runtime
end

Instance Attribute Details

#rowsArray<Row> (readonly)

The Rows that comprise this Template

Returns:

  • (Array<Row>)

    the current value of rows



9
10
11
# File 'lib/csv_plus_plus/template.rb', line 9

def rows
  @rows
end

#runtimeRuntime (readonly)

The Runtime containing all function and variable references

Returns:

  • (Runtime)

    the current value of runtime



9
10
11
# File 'lib/csv_plus_plus/template.rb', line 9

def runtime
  @runtime
end

Instance Method Details

#bind_all_vars!(runtime) ⇒ Object

Only run after expanding all rows, now we can bind all [[var=]] modifiers to a variable. There are two distinct types of variable bindings here:

  • Binding to a cell: for this we just make an A1Reference to the cell itself (A1, B4, etc)

  • Binding to a cell within an expand: the variable can only be resolved within that expand and needs to be relative to it’s row (it can’t be an absolute cell reference like above)

rubocop:disable Metrics/MethodLength

Parameters:

  • runtime (Runtime)

    The current runtime



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/csv_plus_plus/template.rb', line 36

def bind_all_vars!(runtime)
  runtime.position.map_rows(@rows) do |row|
    # rubocop:disable Style/MissingElse
    if row.unexpanded?
      # rubocop:enable Style/MissingElse
      raise(
        ::CSVPlusPlus::Error::CompilerError,
        'Template#expand_rows! must be called before Template#bind_all_vars!'
      )
    end

    runtime.position.map_row(row.cells) do |cell|
      bind_vars(cell, row.modifier.expand)
    end
  end
end

#expand_rows!Array<Row>

Apply expand= (adding rows to the results) modifiers to the parsed template. This happens in towards the end of compilation because expanding rows will change the relative rownums as rows are added, and variables can’t be bound until the rows have been assigned their final rownums.

Returns:



60
61
62
63
64
65
66
67
68
69
70
# File 'lib/csv_plus_plus/template.rb', line 60

def expand_rows!
  # TODO: make it so that an infinite expand will not overwrite the rows below it, but instead merge with them
  @rows =
    rows.reduce([]) do |expanded_rows, row|
      if row.modifier.expand
        row.expand_rows(starts_at: expanded_rows.length, into: expanded_rows)
      else
        expanded_rows << row.tap { |r| r.index = expanded_rows.length }
      end
    end
end

#validate_infinite_expandsObject

Make sure that the template has a valid amount of infinite expand modifiers



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/csv_plus_plus/template.rb', line 74

def validate_infinite_expands
  infinite_expand_rows = @rows.filter { |r| r.modifier.expand&.infinite? }
  return unless infinite_expand_rows.length > 1

  raise(
    ::CSVPlusPlus::Error::ModifierSyntaxError.new(
      'You can only have one infinite expand= (on all others you must specify an amount)',
      bad_input: infinite_expand_rows[1].to_s
    )
  )
end

#verbose_summary::String

Provide a summary of the state of the template (and it’s @runtime)

Returns:

  • (::String)


90
91
92
93
94
95
96
97
# File 'lib/csv_plus_plus/template.rb', line 90

def verbose_summary
  # TODO: we can probably include way more stats in here
  <<~SUMMARY
    #{@runtime.scope.verbose_summary}

    > #{@rows.length} rows to be written
  SUMMARY
end