Class: NWN::TwoDA::Table

Inherits:
Object
  • Object
show all
Defined in:
lib/nwn/twoda.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeTable

Create a new, empty 2da table.



14
15
16
17
# File 'lib/nwn/twoda.rb', line 14

def initialize
  @columns = []
  @rows = []
end

Instance Attribute Details

#columnsObject

An array of all column names present in this 2da table.



8
9
10
# File 'lib/nwn/twoda.rb', line 8

def columns
  @columns
end

#rowsObject

An array of row arrays, without headers.



11
12
13
# File 'lib/nwn/twoda.rb', line 11

def rows
  @rows
end

Class Method Details

.parse(bytes) ⇒ Object

Parse a existing string containing a full 2da table. Returns a TwoDA::Table.



33
34
35
36
37
# File 'lib/nwn/twoda.rb', line 33

def self.parse bytes
  obj = self.new
  obj.parse bytes
  obj
end

.read_from(io) ⇒ Object

Creates a new Table object from a given IO source.

file

A IO object pointing to a 2da file.



22
23
24
# File 'lib/nwn/twoda.rb', line 22

def self.read_from io
  self.parse io.read()
end

Instance Method Details

#by_col(column, row = nil) ⇒ Object

Retrieve data by column.

column

The column to retrieve (name or id).

row

The row to retrieve (starts at 0), or nil for all rows.

Raises:

  • (ArgumentError)


97
98
99
100
101
# File 'lib/nwn/twoda.rb', line 97

def by_col column, row = nil
  column = column_name_to_id column
  raise ArgumentError, "column must not be nil." if column.nil?
  row.nil? ? @rows.map {|v| v[column] } : @rows[row.to_i][column]
end

#by_row(row, column = nil) ⇒ Object

Retrieve data by row.

row

The row to retrieve (starts at 0)

column

The column to retrieve (name or id), or nil for all columns.



87
88
89
90
# File 'lib/nwn/twoda.rb', line 87

def by_row row, column = nil
  column = column_name_to_id column
  column.nil? ? @rows[row.to_i] : @rows[row.to_i][column]
end

#column_name_to_id(column) ⇒ Object

Translate a column name to its array offset; will validate and raise an ArgumentError if the given argument is invalid or the column cannot be resolved.



107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/nwn/twoda.rb', line 107

def column_name_to_id column
   case column
    when String
      @columns.index(column) or raise ArgumentError, "Not a valid column name: #{column}"
    when Fixnum
      column
    when NilClass
      nil
    else
      raise ArgumentError, "Invalid column type: #{column} as #{column.class}"
  end
end

#parse(bytes) ⇒ Object

Parses a string that represents a valid 2da definition. Replaces any content this table may already have.

Raises:

  • (ArgumentError)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/nwn/twoda.rb', line 41

def parse bytes
  magic, empty, header, *data = *bytes.split(/\r?\n/).map {|v| v.strip }

  raise ArgumentError, "Not valid 2da: No valid header found" if
    magic != "2DA V2.0"


  if empty != ""
    $stderr.puts "Warning: second line of 2da not empty, continuing anyways."
    data = [header].concat(data)
    header = empty
  end

  header = Shellwords.shellwords(header.strip)
  data.map! {|line|
    Shellwords.shellwords(line.strip)
  }

  data.reject! {|line|
    line.size == 0
  }

  offset = 0
  data.each_with_index {|row, idx|
    if (idx + offset) != row[0].to_i
      $stderr.puts "Warning: row #{idx} has a non-matching ID #{row[0]} (while parsing #{row[0,3].join(' ')})."
      offset += (row[0].to_i - idx)
    end

    # [1..-1]: Strip off the ID
    data[row[0].to_i] = row = row[1..-1]

    raise ArgumentError,
      "Row #{idx} does not have the appropriate amount of cells (has: #{row.size}, want: #{header.size}) (while parsing #{row[0,3].join(' ')})." if
        row.size != header.size
  }

  @columns = header
  @rows = data
end

#to_2daObject

Returns this table as a valid 2da to be written to a file.



121
122
123
124
125
126
127
128
129
130
# File 'lib/nwn/twoda.rb', line 121

def to_2da
  ret = []
  ret << "2DA V2.0"
  ret << ""
  ret << @columns.join("\t")
  @rows.each_with_index {|row, idx|
    ret << [idx].concat(row).join("\t")
  }
  ret.join("\r\n")
end

#write_to(io) ⇒ Object

Dump this table to a IO object.



27
28
29
# File 'lib/nwn/twoda.rb', line 27

def write_to io
  io.write(self.to_2da)
end