fat_table 0.9.9 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rspec/core/rake_task'
3
5
  require 'rdoc/task'
@@ -13,4 +15,7 @@ end
13
15
 
14
16
  RSpec::Core::RakeTask.new(:spec)
15
17
 
18
+ require "gem_docs"
19
+ GemDocs.install
20
+
16
21
  task :default => [:spec, :rubocop]
data/bin/ft_console CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'bundler/setup'
4
5
  require 'fat_table'
data/fat_table.gemspec CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  lib = File.expand_path('../lib', __FILE__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
  require 'fat_table/version'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Array
2
4
  # Map booleans true to 1 and false to 0 so they can be compared in a sort
3
5
  # with the <=> operator.
@@ -0,0 +1,196 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'debug'
4
+
5
+ # This refinement contains methods that extend the String class to massage
6
+ # strings that represent numbers, such as adding commas, pre- and
7
+ # post-padding, etc.
8
+ module NumericString
9
+ # You can control how NumericString behaves by supplying a new
10
+ # NumericString::Config to the config: parameter of these methods. Calling
11
+ # `NumericString::Config.build` gives you the deafult configuration with
12
+ # whatever overrides you give it. You can also modify an existing config
13
+ # with some overrides. For example:
14
+ #
15
+ # #+begin_src ruby
16
+ # cfg = NumericString::Config.build(group_size: 4)
17
+ # cfg2 = cfg.with(group_char: '_')
18
+ #
19
+ # "1234567.89".add_grouping(config: cfg)
20
+ # => "123,4567.89"
21
+ # "1234567.89".add_grouping(config: cfg2)
22
+ # => '123_4567.89'
23
+ # #+end_src
24
+ Config = Struct.new(
25
+ :group_char,
26
+ :group_size,
27
+ :decimal_char,
28
+ :currency_symbol,
29
+ :pre_pad_char,
30
+ :post_pad_char,
31
+ keyword_init: true,
32
+ ) do
33
+ DEFAULTS = {
34
+ group_char: ',',
35
+ group_size: 3,
36
+ decimal_char: '.',
37
+ currency_symbol: '$',
38
+ pre_pad_char: '0',
39
+ post_pad_char: '0',
40
+ }.freeze
41
+
42
+ def self.default
43
+ @default ||= new(**DEFAULTS).freeze
44
+ end
45
+
46
+ # Build from defaults, overriding selectively
47
+ def self.build(**overrides)
48
+ new(**DEFAULTS.merge(overrides)).freeze
49
+ end
50
+
51
+ # Clone-with-changes (very Ruby, very nice)
52
+ def with(**overrides)
53
+ self.class.build(
54
+ group_char: overrides.fetch(:group_char, group_char),
55
+ group_size: overrides.fetch(:group_size, group_size),
56
+ decimal_char: overrides.fetch(:decimal_char, decimal_char),
57
+ currency_symbol: overrides.fetch(:currency_symbol, currency_symbol),
58
+ pre_pad_char: overrides.fetch(:pre_pad_char, pre_pad_char),
59
+ post_pad_char: overrides.fetch(:post_pad_char, post_pad_char),
60
+ )
61
+ end
62
+ end
63
+
64
+ refine String do
65
+ # If self is a valid decimal number, add grouping commas to the whole
66
+ # part, retaining any fractional part and currency symbol undisturbed.
67
+ # The optional cond: parameter can contain a test to determine if the
68
+ # grouping ought to be performed. If (1) self is not a valid decimal
69
+ # number string, (2) the whole part already contains grouping characters,
70
+ # or (3) cond: is falsey, return self.
71
+ def add_grouping(cond: true, config: Config.default)
72
+ return self unless cond
73
+ return self unless valid_num?(config:)
74
+
75
+ cur, whole, frac = cur_whole_frac(config:)
76
+ return self if whole.include?(config.group_char)
77
+
78
+ whole = whole.split('').reverse
79
+ .each_slice(config.group_size).to_a
80
+ .map { |a| a.reverse.join }
81
+ .reverse
82
+ .join(config.group_char)
83
+ cur + whole + frac
84
+ end
85
+
86
+ alias_method :add_commas, :add_grouping
87
+
88
+ # If self is a valid decimal number, add the currency symbol (per
89
+ # NumericString::Config.currency_symbol) to the front of the number
90
+ # string, retaining any grouping characters undisturbed. The optional
91
+ # cond: parameter can contain a test to determine if the currency symbol
92
+ # ought to be pre-pended. If (1) self is not a valid decimal number
93
+ # string, (2) the currency symbol is already present, or (3) cond: is
94
+ # falsey, return self.
95
+ def add_currency(cond: true, config: Config.default)
96
+ return self unless cond
97
+ return self unless valid_num?(config:)
98
+
99
+ md = match(num_re(config:))
100
+ return self unless md[:cur].blank?
101
+
102
+ config.currency_symbol + self
103
+ end
104
+
105
+ def add_pre_digits(n, cond: true, config: Config.default)
106
+ return self unless cond
107
+ return self if n <= 0
108
+ return self unless valid_num?(config:)
109
+
110
+ cur, whole, frac = cur_whole_frac(config:)
111
+ n_pads = [n - whole.delete(config.group_char).size, 0].max
112
+ padding = config.pre_pad_char * n_pads
113
+ "#{cur}#{padding}#{whole}#{frac}"
114
+ end
115
+
116
+ def add_post_digits(n, cond: true, config: Config.default)
117
+ return self unless cond
118
+ return self unless valid_num?(config:)
119
+
120
+ cur, whole, frac = cur_whole_frac(config:)
121
+ frac_digs = frac.size - 1 # frac includes the decimal character
122
+ if n >= frac_digs
123
+ n_pads = [n - frac_digs, 0].max
124
+ padding = config.post_pad_char * n_pads
125
+ "#{cur}#{whole}#{frac}#{padding}"
126
+ elsif n.zero?
127
+ # Round up last digit of whole if first digit of frac >= 5
128
+ if frac[1].to_i >= 5
129
+ whole = whole[0..-2] + (whole[-1].to_i + 1).to_s
130
+ end
131
+ # No fractional part
132
+ "#{cur}#{whole}"
133
+ elsif n.negative?
134
+ # This calls for rounding the whole part to nearest 10^n.abs and
135
+ # dropping the frac part.
136
+ ndigs_in_whole = whole.delete(config.group_char).size
137
+ nplaces = [ndigs_in_whole - 1, n.abs].min
138
+ # Replace the right-most nplaces digs with the pre-pad character.
139
+ replace_count = 0
140
+ new_whole = +''
141
+ round_char = whole.delete(config.group_char)[-1]
142
+ rounded = false
143
+ whole.split('').reverse_each do |c|
144
+ if c == config.group_char
145
+ new_whole << c
146
+ elsif replace_count < nplaces
147
+ new_whole << config.pre_pad_char
148
+ round_char = c
149
+ replace_count += 1
150
+ elsif !rounded
151
+ new_whole <<
152
+ if round_char.to_i >= 5
153
+ (c.to_i + 1).to_s
154
+ else
155
+ c
156
+ end
157
+ rounded = true
158
+ else
159
+ new_whole << c
160
+ end
161
+ end
162
+ "#{cur}#{new_whole.reverse}"
163
+ else
164
+ # We have to shorten the fractional part, which required rounding.
165
+ last_frac_dig = frac[n]
166
+ following_frac_dig = frac[n + 1]
167
+ if following_frac_dig.to_i >= 5
168
+ last_frac_dig = (last_frac_dig.to_i + 1).to_s
169
+ end
170
+ frac = frac[0..(n - 1)] + last_frac_dig
171
+ padding = ''
172
+ "#{cur}#{whole}#{frac}#{padding}"
173
+ end
174
+ end
175
+
176
+ private
177
+
178
+ def num_re(config: Config.default)
179
+ cur_sym = Regexp.quote(config.currency_symbol)
180
+ grp_char = Regexp.quote(config.group_char)
181
+ dec_char = Regexp.quote(config.decimal_char)
182
+ /\A(?<cur>#{cur_sym})?(?<whole>[0-9#{grp_char}]+)(?<frac>#{dec_char}[0-9]*)?\z/
183
+ end
184
+
185
+ # Return the currency, whole and fractional parts of a string with a possible
186
+ # decimal point attached to the frac part if present.
187
+ def cur_whole_frac(config: Config.default)
188
+ match = match(num_re(config:))
189
+ [match[:cur].to_s, match[:whole].to_s, match[:frac].to_s]
190
+ end
191
+
192
+ def valid_num?(config: Config.default)
193
+ match?(num_re(config:))
194
+ end
195
+ end
196
+ end
data/lib/core_ext.rb ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'core_ext/array'
4
+ require_relative 'core_ext/numeric_string'
@@ -86,7 +86,11 @@ module FatTable
86
86
  # col.header #=> :prices
87
87
  # col.sum #=> 18376.75
88
88
  #
89
- # @param
89
+ # @param header [String, Symbol] the name of the column header
90
+ # @param items [Array<String>, Array<DateTime>, Array<Numeric>, Array<Boolean>] the initial data items in column
91
+ # @param type [String] the column type: 'String', 'Numeric', 'DateTime', 'Boolean', or 'NilClass'
92
+ # @param tolerant [Boolean] whether the column accepts unconvertable items not of its type as Strings
93
+ # @return [Column] the new Column
90
94
  def initialize(header:, items: [], type: 'NilClass', tolerant: false)
91
95
  @raw_header = header
92
96
  @header =
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FatTable
2
4
  module Convert
3
5
  # Convert val to the type of key, a ruby class constant, such as Date,
@@ -213,7 +213,7 @@ module FatTable
213
213
  end
214
214
 
215
215
  # Insert a possibly calculated value for the label in the appropriate
216
- # @values column.
216
+ # `@values` column.
217
217
  def insert_labels_in_label_col
218
218
  if group
219
219
  @values[@label_col] = []
@@ -67,7 +67,7 @@ module FatTable
67
67
  bgcolor: 'none',
68
68
  hms: false,
69
69
  pre_digits: 0,
70
- post_digits: 0,
70
+ post_digits: 4,
71
71
  commas: false,
72
72
  currency: false,
73
73
  datetime_fmt: '%F %H:%M:%S',
@@ -1026,63 +1026,37 @@ module FatTable
1026
1026
  # above. Only device-independent formatting is done here. Device dependent
1027
1027
  # formatting (e.g., color) can be done in a subclass of Formatter by
1028
1028
  # specializing this method.
1029
+
1030
+ using NumericString
1031
+
1029
1032
  def format_numeric(val, istruct)
1030
1033
  return istruct[:nil_text] if val.nil?
1031
1034
  return val.secs_to_hms if istruct[:hms]
1032
1035
 
1033
- if istruct[:commas]
1034
- # Commify the whole number part if not done already.
1035
- result = val.commas(istruct[:post_digits])
1036
- else
1037
- result = val.round(istruct[:post_digits]).to_s
1038
- match = result.match(/\.(\d+)\z/)
1039
- if match && (match[1]&.size&.< istruct[:post_digits])
1040
- # Add trailing zeros to pad out post_digits
1041
- n_zeros = [istruct[:post_digits] - match[1].size, 0].max
1042
- zeros = '0' * n_zeros
1043
- result += zeros
1044
- end
1045
- result
1046
- end
1047
-
1048
- if istruct[:pre_digits].positive?
1049
- match = result.match(/\A([\d,]+)(\.\d+)?\z/)
1050
- whole_part = match[1]
1051
- frac_part = match[2]
1052
- n_zeros = [istruct[:pre_digits] - whole_part.delete(',').size, 0].max
1053
- result =
1054
- if n_zeros.positive?
1055
- if istruct[:commas]
1056
- # Insert leading zeros with commas
1057
- pre_comma_match = whole_part.match(/\A(\d+),/)
1058
- if pre_comma_match
1059
- n_partial_zeros = 3 - pre_comma_match[1].size
1060
- whole_part = "0" * n_partial_zeros + whole_part
1061
- n_zeros -= n_partial_zeros
1062
- end
1063
- zeros = ''
1064
- if n_zeros.positive?
1065
- zeros = "0" * n_zeros
1066
- if n_zeros > 3 && istruct[:commas]
1067
- zeros = zeros.reverse.gsub!(/([0-9]{3})/, "\\1,").reverse
1068
- end
1069
- end
1070
- "#{zeros},#{whole_part}#{frac_part}"
1071
- else
1072
- # Insert leading zeros without commas
1073
- zeros = "0" * n_zeros
1074
- "#{zeros}#{whole_part}#{frac_part}"
1075
- end
1076
- else
1077
- "#{whole_part}#{frac_part}"
1078
- end
1036
+ case val
1037
+ when Integer
1038
+ val.to_s
1039
+ .add_pre_digits(istruct[:pre_digits], cond: istruct[:pre_digits].positive?)
1040
+ .add_commas(cond: istruct[:commas])
1041
+ .add_currency(cond: istruct[:currency])
1042
+ when Rational
1043
+ num = val.numerator.to_s
1044
+ .add_pre_digits(istruct[:pre_digits], cond: istruct[:pre_digits].positive?)
1045
+ .add_commas(cond: istruct[:commas])
1046
+ .add_currency(cond: istruct[:currency])
1047
+ den = val.denominator.to_s
1048
+ .add_pre_digits(istruct[:pre_digits], cond: istruct[:pre_digits].positive?)
1049
+ .add_commas(cond: istruct[:commas])
1050
+ "#{num}/#{den}"
1051
+ when Float, BigDecimal
1052
+ val.to_s
1053
+ .add_pre_digits(istruct[:pre_digits], cond: istruct[:pre_digits].positive?)
1054
+ .add_post_digits(istruct[:post_digits])
1055
+ .add_commas(cond: istruct[:commas])
1056
+ .add_currency(cond: istruct[:currency])
1079
1057
  else
1080
- result
1081
- end
1082
- if istruct[:currency]
1083
- result = "#{FatTable.currency_symbol}#{result}"
1058
+ raise ArgumentError, "cannot apply format_numeric to #{val} of class #{val.class}"
1084
1059
  end
1085
- result
1086
1060
  end
1087
1061
 
1088
1062
  # Apply non-device-dependent string formatting instructions.
@@ -26,8 +26,8 @@ module FatTable
26
26
  end
27
27
 
28
28
  # Taken from the Rainbow gem's list of valid colors.
29
-
30
- self.valid_colors = File.readlines(File.join(__dir__, 'xcolors.txt'), chomp: true)
29
+ color_path = File.expand_path("../../../data/xcolors.txt", __dir__)
30
+ self.valid_colors = File.readlines(color_path, chomp: true)
31
31
 
32
32
  # LaTeX commands to load the needed packages based on the :environement
33
33
  # option. For now, just handles the default 'longtable' :environment. The
@@ -721,7 +721,7 @@ module FatTable
721
721
  # row in the table as a group boundary. An attempt to add a boundary to
722
722
  # an empty table has no effect. We adopt the convention that the last row
723
723
  # of the table always marks an implicit boundary even if it is not in the
724
- # @explicit_boundaries array. When we "mark" a boundary, we intend it to
724
+ # `@explicit_boundaries` array. When we "mark" a boundary, we intend it to
725
725
  # be an explicit boundary, even if it marks the last row of the table.
726
726
  def mark_boundary(row_num = nil)
727
727
  return self if empty?
@@ -774,7 +774,7 @@ module FatTable
774
774
  # user's point of view are indexed starting at 0.
775
775
  def row_index_to_group_index(row_num)
776
776
  boundaries.each_with_index do |b_last, g_num|
777
- return (g_num + 1) if row_num <= b_last
777
+ return g_num + 1 if row_num <= b_last
778
778
  end
779
779
  0
780
780
  end
@@ -918,8 +918,8 @@ module FatTable
918
918
  # access the instance variable @row, as the row number of the row being
919
919
  # evaluated, and @group, as the group number of the row being evaluated.
920
920
  #
921
- # 4. a hash in +new_cols+ with one of the special keys, +ivars: {literal
922
- # hash}+, +before_hook: 'ruby-code'+, or +after_hook: 'ruby-code'+ for
921
+ # 4. a hash in +new_cols+ with one of the special keys, `+ivars: {literal
922
+ # hash}+`, +before_hook: 'ruby-code'+, or +after_hook: 'ruby-code'+ for
923
923
  # defining custom instance variables to be used during evaluation of
924
924
  # parameters described in point 3 and hooks of ruby code snippets to be
925
925
  # evaluated before and after processing each row.
@@ -1150,7 +1150,7 @@ module FatTable
1150
1150
  # exception will be thrown. Duplicates are eliminated from the result. Any
1151
1151
  # groups present in either Table are eliminated in the output Table.
1152
1152
  def intersect(other)
1153
- set_operation(other, :intersect, distinct: true)
1153
+ set_operation(other, :&, distinct: true)
1154
1154
  end
1155
1155
 
1156
1156
  # :category: Operators
@@ -1163,7 +1163,7 @@ module FatTable
1163
1163
  # will be thrown. Duplicates are not eliminated from the result. Resets
1164
1164
  # groups.
1165
1165
  def intersect_all(other)
1166
- set_operation(other, :intersect, distinct: false)
1166
+ set_operation(other, :&, distinct: false)
1167
1167
  end
1168
1168
 
1169
1169
  # :category: Operators
@@ -1176,7 +1176,7 @@ module FatTable
1176
1176
  # are eliminated from the result. Any groups present in either Table are
1177
1177
  # eliminated in the output Table.
1178
1178
  def except(other)
1179
- set_operation(other, :difference, distinct: true)
1179
+ set_operation(other, :-, distinct: true)
1180
1180
  end
1181
1181
 
1182
1182
  # :category: Operators
@@ -1189,7 +1189,7 @@ module FatTable
1189
1189
  # are /not/ eliminated from the result. Any groups present in either Table
1190
1190
  # are eliminated in the output Table.
1191
1191
  def except_all(other)
1192
- set_operation(other, :difference, distinct: false)
1192
+ set_operation(other, :-, distinct: false)
1193
1193
  end
1194
1194
 
1195
1195
  # An Array of symbols for the valid join types.
@@ -2,5 +2,5 @@
2
2
 
3
3
  module FatTable
4
4
  # The current version of FatTable
5
- VERSION = '0.9.9'
5
+ VERSION = '1.0.0'
6
6
  end
data/lib/fat_table.rb CHANGED
@@ -1,11 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This module provides objects for treating tables as a data type on which you
4
- # can (1) perform operations, such as select, where, join, and others and (2)
5
- # output the tables in several formats, including text, ANSI terminal, LaTeX,
6
- # and others. It also provides several constructors for building tables from a
7
- # variety of input sources. See, e.g., .from_csv_file,
8
- # FatTable.from_org_file, and FatTable.from_sql, for more details.
3
+ # Gem Overview (extracted from README.org by gem_docs)
4
+ #
5
+ # * Introduction
6
+ # ~FatTable~ is a gem that treats tables as a data type. It provides methods for
7
+ # constructing tables from a variety of sources, building them row-by-row,
8
+ # extracting rows, columns, and cells, and performing aggregate operations on
9
+ # columns. It also provides a set of SQL-esque methods for manipulating table
10
+ # objects: ~select~ for filtering by columns or for creating new columns, ~where~
11
+ # for filtering by rows, ~order_by~ for sorting rows, ~distinct~ for eliminating
12
+ # duplicate rows, ~group_by~ for aggregating multiple rows into single rows and
13
+ # applying column aggregate methods to ungrouped columns, a collection of ~join~
14
+ # methods for combining tables, and more.
15
+ #
16
+ # Furthermore, ~FatTable~ provides methods for formatting tables and producing
17
+ # output that targets various output media: text, ANSI terminals, ruby data
18
+ # structures, LaTeX tables, Emacs org-mode tables, and more. The formatting
19
+ # methods can specify cell formatting in a way that is uniform across all the
20
+ # output methods and can also decorate the output with any number of footers,
21
+ # including group footers. ~FatTable~ applies formatting directives to the extent
22
+ # they makes sense for the output medium and treats other formatting directives as
23
+ # no-ops.
24
+ #
25
+ # ~FatTable~ can be used to perform operations on data that are naturally best
26
+ # conceived of as tables, which in my experience is quite often. It can also
27
+ # serve as a foundation for providing reporting functions where flexibility
28
+ # about the output medium can be useful. Finally ~FatTable~ can be used within
29
+ # Emacs ~org-mode~ files in code blocks targeting the Ruby language. Org mode
30
+ # tables are presented to a ruby code block as an array of arrays, so ~FatTable~
31
+ # can read them in with its ~.from_aoa~ constructor. A ~FatTable~ table output as an
32
+ # array of arrays with its ~.to_aoa~ output function will be rendered in an
33
+ # org-mode buffer as an org-table, ready for processing by other code blocks.
9
34
  module FatTable
10
35
  require 'fat_core/symbol'
11
36
  require 'fat_core/array'
@@ -18,9 +43,9 @@ module FatTable
18
43
  require 'active_support/core_ext'
19
44
  require 'active_support/number_helper'
20
45
 
46
+ require 'core_ext'
21
47
  require 'fat_table/version'
22
48
  require 'fat_table/patches'
23
- require 'ext/array'
24
49
  require 'fat_table/evaluator'
25
50
  require 'fat_table/convert'
26
51
  require 'fat_table/column'
@@ -145,11 +170,11 @@ module FatTable
145
170
  # methods can be called. If no block is given, the default format for the type
146
171
  # will be used. The +options+ are passed along to the FatTable::Formatter
147
172
  # created to process the output.
148
- def self.to_format(table, options = {}) # :yields: formatter
173
+ def self.to_format(table, **options) # :yields: formatter
149
174
  if block_given?
150
- to_any(format, table, options, &Proc.new)
175
+ to_any(format, table, **options, &Proc.new)
151
176
  else
152
- to_any(format, table, options)
177
+ to_any(format, table, **options)
153
178
  end
154
179
  end
155
180
 
@@ -159,15 +184,15 @@ module FatTable
159
184
  # +FatTable::Formatter+ of the appropriate type on which formatting and footer
160
185
  # methods can be called. If no block is given, the default format for the
161
186
  # +fmt+ type will be used.
162
- def self.to_any(fmt, table, options = {})
187
+ def self.to_any(fmt, table, **options)
163
188
  fmt = fmt.as_sym
164
189
  raise UserError, "unknown format '#{fmt}'" unless FORMATS.include?(fmt)
165
190
 
166
191
  method = "to_#{fmt}"
167
192
  if block_given?
168
- send(method, table, options, &Proc.new)
193
+ send(method, table, **options, &Proc.new)
169
194
  else
170
- send(method, table, options)
195
+ send(method, table, **options)
171
196
  end
172
197
  end
173
198
 
@@ -176,7 +201,7 @@ module FatTable
176
201
  # default formatting is applied to the +table+'s cells. If a block is given,
177
202
  # it yields the +FatTable::Formatter+ to the block on which formatting
178
203
  # and footer methods can be called.
179
- def self.to_psv(table, options = {})
204
+ def self.to_psv(table, **options)
180
205
  fmt = Formatter.new(table, options)
181
206
  yield fmt if block_given?
182
207
  fmt.output
@@ -186,8 +211,8 @@ module FatTable
186
211
  # default formatting is applies to the table's cells. If a block is given, it
187
212
  # yields an AoaFormatter to the block to which formatting instructions and
188
213
  # footers can be added by calling methods on it.
189
- def self.to_aoa(table, options = {})
190
- fmt = AoaFormatter.new(table, options)
214
+ def self.to_aoa(table, **options)
215
+ fmt = AoaFormatter.new(table, **options)
191
216
  yield fmt if block_given?
192
217
  fmt.output
193
218
  end
@@ -197,8 +222,8 @@ module FatTable
197
222
  # table. If no block is given, default formatting is applies to the table's
198
223
  # cells. If a block is given, it yields an AohFormatter to the block to which
199
224
  # formatting instructions and footers can be added by calling methods on it.
200
- def self.to_aoh(table, options = {})
201
- fmt = AohFormatter.new(table, options)
225
+ def self.to_aoh(table, **options)
226
+ fmt = AohFormatter.new(table, **options)
202
227
  yield fmt if block_given?
203
228
  fmt.output
204
229
  end
@@ -207,8 +232,8 @@ module FatTable
207
232
  # default formatting applies to the table's cells. If a block is given, it
208
233
  # yields a LaTeXFormatter to the block to which formatting instructions and
209
234
  # footers can be added by calling methods on it.
210
- def self.to_latex(table, options = {})
211
- fmt = LaTeXFormatter.new(table, options)
235
+ def self.to_latex(table, **options)
236
+ fmt = LaTeXFormatter.new(table, **options)
212
237
  yield fmt if block_given?
213
238
  fmt.output
214
239
  end
@@ -217,8 +242,8 @@ module FatTable
217
242
  # is given, default formatting applies to the table's cells. If a block is
218
243
  # given, it yields a OrgFormatter to the block to which formatting
219
244
  # instructions and footers can be added by calling methods on it.
220
- def self.to_org(table, options = {})
221
- fmt = OrgFormatter.new(table, options)
245
+ def self.to_org(table, **options)
246
+ fmt = OrgFormatter.new(table, **options)
222
247
  yield fmt if block_given?
223
248
  fmt.output
224
249
  end
@@ -227,8 +252,8 @@ module FatTable
227
252
  # table. If no block is given, default formatting applies to the table's
228
253
  # cells. If a block is given, it yields a TermFormatter to the block to which
229
254
  # formatting instructions and footers can be added by calling methods on it.
230
- def self.to_term(table, options = {})
231
- fmt = TermFormatter.new(table, options)
255
+ def self.to_term(table, **options)
256
+ fmt = TermFormatter.new(table, **options)
232
257
  yield fmt if block_given?
233
258
  fmt.output
234
259
  end
@@ -237,8 +262,8 @@ module FatTable
237
262
  # no block is given, default formatting applies to the table's cells. If a
238
263
  # block is given, it yields a TextFormatter to the block to which formatting
239
264
  # instructions and footers can be added by calling methods on it.
240
- def self.to_text(table, options = {})
241
- fmt = TextFormatter.new(table, options)
265
+ def self.to_text(table, **options)
266
+ fmt = TextFormatter.new(table, **options)
242
267
  yield fmt if block_given?
243
268
  fmt.output
244
269
  end