fat_table 0.6.4 → 0.6.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 41e7e31d83ee64d7aea1c9b19969c80ab8d1d58b7058b0962534a389a222330e
4
- data.tar.gz: b0745fd3fa09032d7981cae20520bfa349f546f885b042907fff64401c49f25f
3
+ metadata.gz: b9661335d0ae8ec4d87b9e16c3055552af05a354c5222b9838d51f8109ddd749
4
+ data.tar.gz: fe23c745a61b2fff7d3380221ee133b5e38c3bdd9d4ff429bdce2094cbe47755
5
5
  SHA512:
6
- metadata.gz: 371b2369809d837afc7f40b81092bc03c917276653ae60806a6bc2931d6bfff9a8ab7e866d8141babf5fd77dfb07e7ad8538c74f49391bc4009d888893397005
7
- data.tar.gz: e352a6445fce148e2545280d6d44970f55fc74e1e91fb89768a1f65da5d077aeed29c90ace57ea93e4586228251c42d565754fdce28b4637aedca56571f410ab
6
+ metadata.gz: 201d3df5ba9820b96e22b1a035013c128c2f8cf2efd054cd16b9b6f372c13381334db9cc11b268daa0537d25e2d0475c35cd73f1749d08d8a008a2498010ead1
7
+ data.tar.gz: e067fc5bedae6541e0ce88e41025fffbff64a16a3545fccd89a6b171f2b6d648fd8e1716227ceafd770db509417361781c3c6d4cc718824ec8b9098a266eafab
data/.solargraph.yml ADDED
@@ -0,0 +1,22 @@
1
+ ---
2
+ include:
3
+ - "**/*.rb"
4
+ exclude:
5
+ - spec/**/*
6
+ - test/**/*
7
+ - vendor/**/*
8
+ - ".bundle/**/*"
9
+ require: []
10
+ domains: []
11
+ reporters:
12
+ - rubocop
13
+ - require_not_found
14
+ formatter:
15
+ rubocop:
16
+ cops: safe
17
+ except: []
18
+ only: []
19
+ extra_args: []
20
+ require_paths: []
21
+ plugins: []
22
+ max_files: 5000
data/README.org CHANGED
@@ -140,7 +140,7 @@ org-mode buffer as an org-table, ready for processing by other code blocks.
140
140
  - [[#to-aoa-array-of-arrays][To AoA (Array of Arrays)]]
141
141
  - [[#to-aoh-array-of-hashes][To AoH (Array of Hashes)]]
142
142
  - [[#formatting-directives][Formatting Directives]]
143
- - [[#string][String]]
143
+ - [[#all-types-as-strings][All Types as Strings]]
144
144
  - [[#numeric][Numeric]]
145
145
  - [[#datetime][DateTime]]
146
146
  - [[#boolean][Boolean]]
@@ -2389,7 +2389,7 @@ formats can be defined by adding additional classes.
2389
2389
  **** Examples
2390
2390
  ***** To Text
2391
2391
 
2392
- This formatter uses nothing by ASCII characters to draw the table. Notice
2392
+ This formatter uses nothing but ASCII characters to draw the table. Notice
2393
2393
  that, unlike to ~to_org~ formatter shown below, the intersections of lines are
2394
2394
  represented by a ~+~ character. Embelishments such as color, bold, and so
2395
2395
  forth are ignored.
@@ -2421,7 +2421,7 @@ characters to draw the table, but, the intersections of lines are represented
2421
2421
  by a ~|~ character. Embelishments such as color, bold, and so forth are
2422
2422
  ignored. When working in Org Mode, note that Emacs will convert an Array of
2423
2423
  Arrays into an Org Mode table, so when constructing tables programmatically,
2424
- it may be better to use that formatter as shown below.
2424
+ it may be better to use the =to_aoa= formatter shown below.
2425
2425
 
2426
2426
  #+begin_SRC ruby :wrap EXAMPLE
2427
2427
  tab_a.to_org
@@ -2528,28 +2528,28 @@ order, so '$R,' and ',$R' are equivalent.
2528
2528
 
2529
2529
  Here is a list of all the formatting directives that apply to each cell type:
2530
2530
 
2531
- **** String
2531
+ **** All Types as Strings
2532
2532
 
2533
- For a string element, the following instructions are valid. Note that these can
2534
- also be applied to all the other cell types as well since they are all converted
2535
- to a string in forming the output.
2533
+ For a string element, or any an element of any type (since these are applied
2534
+ after the element has been converted to a String), the following instructions
2535
+ are valid.
2536
2536
 
2537
- - u :: convert the element to all lowercase,
2538
- - U :: convert the element to all uppercase,
2537
+ - u :: convert the element to all lowercase [default false],
2538
+ - U :: convert the element to all uppercase [default false],
2539
2539
  - t :: title case the element, that is, upcase the initial letter in
2540
- each word and lower case the other letters
2541
- - B ~B :: make the element bold, or turn off bold
2542
- - I ~I :: make the element italic, or turn off italic
2543
- - R :: align the element on the right of the column
2544
- - L :: align the element on the left of the column
2545
- - C :: align the element in the center of the column
2540
+ each word and lower case the other letters [default false],
2541
+ - B ~B :: make the element bold, or turn off bold [default ~B]
2542
+ - I ~I :: make the element italic, or turn off italic [default ~I]
2543
+ - R :: align the element on the right of the column [default off]
2544
+ - L :: align the element on the left of the column [default on]
2545
+ - C :: align the element in the center of the column [default off]
2546
2546
  - c[<color_spec>] :: render the element in the given color; the <color_spec>
2547
2547
  can have the form fgcolor, fgcolor.bgcolor, or .bgcolor, to set the
2548
2548
  foreground or background colors respectively, and each of those can be an
2549
2549
  ANSI or X11 color name in addition to the special color, 'none', which keeps
2550
- the output's default color.
2551
- - _ ~_ :: underline the element, or turn off underline
2552
- - * ~* :: cause the element to blink, or turn off blink
2550
+ the output's default color [default none].
2551
+ - _ ~_ :: underline the element, or turn off underline [default off]
2552
+ - * ~* :: cause the element to blink, or turn off blink [default off]
2553
2553
 
2554
2554
  For example, the directive 'tCc[red.yellow]' would title-case the element,
2555
2555
  center it, and color it red on a yellow background. The directives that are
@@ -2562,16 +2562,21 @@ particular columns.
2562
2562
  For a numeric element, all the instructions valid for string are available, in
2563
2563
  addition to the following:
2564
2564
 
2565
- - , ~, :: insert grouping commas, or do not insert grouping commas,
2566
- - $ ~$ :: format the number as currency according to the locale, or not,
2567
- - m.n :: include at least m digits before the decimal point, padding on
2568
- the left with zeroes as needed, and round the number to the n
2569
- decimal places and include n digits after the decimal point,
2570
- padding on the right with zeroes as needed,
2565
+ - , ~, :: insert grouping commas, or do not insert grouping commas [default
2566
+ ~,],
2567
+ - $ ~$ :: format the number as currency according to the locale, or not
2568
+ [default ~$],
2569
+ - m.n :: include at least m digits before the decimal point, padding on the
2570
+ left with zeroes as needed, and round the number to the n decimal places and
2571
+ include n digits after the decimal point, padding on the right with zeroes
2572
+ as needed. If n is negative, the value will be rounded to the left of the
2573
+ decimal point: e.g., if n is -2, the number will be rounded to the nearest
2574
+ hundred, if -3, to the nearest thousand, etc. [default 0.0]
2571
2575
  - H :: convert the number (assumed to be in units of seconds) to ~HH:MM:SS.ss~
2572
- form. So a column that is the result of subtracting two :datetime forms
2573
- will result in a :numeric expressed as seconds and can be displayed in
2574
- hours, minutes, and seconds with this formatting instruction.
2576
+ form. So a column that is the result of subtracting two :datetime forms will
2577
+ result in a :numeric expressed as seconds and can be displayed in hours,
2578
+ minutes, and seconds with this formatting instruction. If this directive is
2579
+ included, all other numeric directives will be ignored. [default off]
2575
2580
 
2576
2581
  For example, the directive 'R5.0c[blue]' would right-align the numeric
2577
2582
  element, pad it on the left with zeros, and color it blue.
@@ -2598,7 +2603,7 @@ For a boolean cell, all the instructions valid for string are available, in
2598
2603
  addition to the following:
2599
2604
 
2600
2605
  - Y :: print true as ~Y~ and false as ~N~,
2601
- - T :: print true as ~T~ and false as ~F~,
2606
+ - T :: print true as ~T~ and false as ~F~ [this is the default],
2602
2607
  - X :: print true as ~X~ and false as an empty string '',
2603
2608
  - b[xxx,yyy] :: print true as the string given as ~xxx~ and false as the string
2604
2609
  given as ~yyy~,
@@ -2616,7 +2621,7 @@ By default, ~nil~ elements are rendered as blank cells, but you can make them
2616
2621
  visible with the following, and in that case, all the formatting instructions
2617
2622
  valid for strings are also available:
2618
2623
 
2619
- - n[niltext] :: render a ~nil~ item with the given niltext.
2624
+ - n[niltext] :: render a ~nil~ item with the given niltext [default ''].
2620
2625
 
2621
2626
  For example, you might want to use 'n[-]Cc[purple]' to make nils visible as a
2622
2627
  centered purple hyphen.
data/TODO.org CHANGED
@@ -1,4 +1,21 @@
1
1
 
2
+ * TODO Explicitly typed columns
3
+ Having FatTable infer column types from the content of a table is nice, but as
4
+ I learned from the need to have force_string!, sometimes we want to restrict
5
+ the type of the column and throw an error if the content does not conform.
6
+ So, perhaps when the table columns are specified, we can allow them to be
7
+ terminated with a "sigil" that restricts its type:
8
+
9
+ - @ :: at Date or DateTime column,
10
+ - # :: a Numeric column
11
+ - ? :: a Boolean column
12
+ - ~ :: a String Column,
13
+ - * :: a tolerant Column, i.e., it infers the type from the content, but
14
+ allows strings to be added as items in an otherwise typed column but treat
15
+ them a nil for calculation purposes.
16
+ - @*, #*, ?* :: a Date, Numeric, or Boolean column that is also tolerant.
17
+ `~*` could be treated the same as `~`.
18
+
2
19
  * TODO Specify Column Widths
3
20
  Allow a formatter to specify column widths. This could be a number of
4
21
  characters, which would be interpreted as a number of "ems" for LaTeX.
@@ -23,6 +40,13 @@ Possible enhancements:
23
40
  This is a [[https://github.com/westonganger/spreadsheet_architect][gem]] that I can include into the Table model to convert a table into
24
41
  a spread-sheet, or even a sheet in a multi-sheet spreadsheet file.
25
42
 
43
+ * TODO Conversion to HTML
44
+ Perhaps an obvious formatter would be HTML tables, but CSS controls the
45
+ styling, so have to think on that one.
46
+
47
+ * TODO Conversion to JSON, YAML
48
+ These would need no color formatting and might prove useful.
49
+
26
50
  * TODO Add Quandl or EODDATA Queries
27
51
  Possible replacements for YQL.
28
52
 
data/fat_table.gemspec CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
6
6
  spec.name = 'fat_table'
7
7
  spec.version = FatTable::VERSION
8
8
  spec.authors = ['Daniel E. Doherty']
9
- spec.email = ['ded-law@ddoherty.net']
9
+ spec.email = ['ded@ddoherty.net']
10
10
 
11
11
  spec.summary = 'Provides tools for working with tables as a data type.'
12
12
  spec.description = <<-DESC
@@ -70,7 +70,7 @@ module FatTable
70
70
  # except in the case of String columns, which retain them a blank
71
71
  # strings.
72
72
  #
73
- # Examples:
73
+ # @example
74
74
  #
75
75
  # require 'fat_table'
76
76
  # col = FatTable::Column.new(header: 'date')
@@ -83,6 +83,8 @@ module FatTable
83
83
  # col.type #=> 'Numeric'
84
84
  # col.header #=> :prices
85
85
  # col.sum #=> 18376.75
86
+ #
87
+ # @param
86
88
  def initialize(header:, items: [], type: 'NilClass', tolerant: false)
87
89
  @raw_header = header
88
90
  @header =
@@ -153,8 +155,6 @@ module FatTable
153
155
  # Force the column to have String type and then convert all items to
154
156
  # strings.
155
157
  def force_string!
156
- # msg = "Can only force an empty column to String type"
157
- # raise UserError, msg unless empty?
158
158
  @type = 'String'
159
159
  unless empty?
160
160
  @items = items.map(&:to_s)
@@ -102,23 +102,25 @@ module FatTable
102
102
  end
103
103
  end
104
104
 
105
- ISO_DATE_RE = %r{(?<yr>\d\d\d\d)[-\/]
105
+ ISO_DATE_RE = %r{\A(?<yr>\d\d\d\d)[-\/]
106
106
  (?<mo>\d\d?)[-\/]
107
107
  (?<dy>\d\d?)\s*
108
- (T?\s*\d\d:\d\d(:\d\d)?
109
- ([-+](\d\d?)(:\d\d?))?)?}x
108
+ (T?\s*\d\d:\d\d(:\d\d)?\s*
109
+ ([-+](\d\d?)(:\d\d?))?)?\s*
110
+ ((mon|tue|wed|thu|fri|sat|sun)[a-zA-z]*)?\s*
111
+ \z}xi
110
112
 
111
- AMR_DATE_RE = %r{(?<dy>\d\d?)[-/](?<mo>\d\d?)[-/](?<yr>\d\d\d\d)\s*
112
- (?<tm>T\d\d:\d\d:\d\d(\+\d\d:\d\d)?)?}x
113
+ AMR_DATE_RE = %r{\A(?<dy>\d\d?)[-/](?<mo>\d\d?)[-/](?<yr>\d\d\d\d)\s*
114
+ (?<tm>T\d\d:\d\d:\d\d(\+\d\d:\d\d)?)?\z}xi
113
115
 
114
116
  # A Date like 'Tue, 01 Nov 2016' or 'Tue 01 Nov 2016' or '01 Nov 2016'.
115
117
  # These are emitted by Postgresql, so it makes from_sql constructor
116
118
  # possible without special formatting of the dates.
117
- INV_DATE_RE = %r{((mon|tue|wed|thu|fri|sat|sun)[a-zA-z]*,?)?\s+ # looks like dow
119
+ INV_DATE_RE = %r{\A((mon|tue|wed|thu|fri|sat|sun)[a-zA-z]*,?)?\s+ # looks like dow
118
120
  (?<dy>\d\d?)\s+ # one or two-digit day
119
121
  (?<mo_name>[jfmasondJFMASOND][A-Za-z]{2,})\s+ # looks like a month name
120
122
  (?<yr>\d\d\d\d) # and a 4-digit year
121
- }xi
123
+ \z}xi
122
124
 
123
125
  # Convert the val to a DateTime if it is either a DateTime, a Date, a Time, or a
124
126
  # String that can be parsed as a DateTime, otherwise return nil. It only
@@ -132,7 +134,7 @@ module FatTable
132
134
  return val.to_datetime if val.is_a?(Time)
133
135
 
134
136
  begin
135
- str = val.to_s.clean
137
+ str = val.to_s.clean.sub(/\A[\[\(\{\<]\s*/, '').sub(/[\]\)\}\>]\s*\z/, '')
136
138
  return nil if str.blank?
137
139
 
138
140
  if str.match(ISO_DATE_RE)
@@ -64,7 +64,7 @@ module FatTable
64
64
  bgcolor: 'none',
65
65
  hms: false,
66
66
  pre_digits: 0,
67
- post_digits: -1,
67
+ post_digits: 0,
68
68
  commas: false,
69
69
  currency: false,
70
70
  datetime_fmt: '%F %H:%M:%S',
@@ -1026,46 +1026,59 @@ module FatTable
1026
1026
  # specializing this method.
1027
1027
  def format_numeric(val, istruct)
1028
1028
  return istruct.nil_text if val.nil?
1029
+ return val.secs_to_hms if istruct.hms
1029
1030
 
1030
- val = val.round(istruct.post_digits) if istruct.post_digits >= 0
1031
- if istruct.hms
1032
- result = val.secs_to_hms
1033
- istruct.commas = false
1034
- elsif istruct.currency
1035
- delim = istruct.commas ? ',' : ''
1036
- result =
1037
- if istruct.post_digits < 0
1038
- val.to_s(:currency, delimiter: delim,
1039
- unit: FatTable.currency_symbol)
1040
- else
1041
- val.to_s(:currency, precision: istruct.post_digits, delimiter: delim,
1042
- unit: FatTable.currency_symbol)
1043
- end
1044
- # istruct.commas = false
1045
- elsif istruct.pre_digits.positive?
1046
- if val.whole?
1047
- # No fractional part, ignore post_digits
1048
- result = sprintf("%0#{istruct.pre_digits}d", val)
1049
- elsif istruct.post_digits >= 0
1050
- # There's a fractional part and pre_digits. sprintf width includes
1051
- # space for fractional part and decimal point, so add pre, post, and 1
1052
- # to get the proper sprintf width.
1053
- wid = istruct.pre_digits + 1 + istruct.post_digits
1054
- result = sprintf("%0#{wid}.#{istruct.post_digits}f", val)
1055
- else
1056
- val = val.round(0)
1057
- result = sprintf("%0#{istruct.pre_digits}d", val)
1031
+ if istruct.commas
1032
+ # Commify the whole number part if not done already.
1033
+ result = val.commas(istruct.post_digits)
1034
+ else
1035
+ result = val.round(istruct.post_digits).to_s
1036
+ match = result.match(/\.(\d+)\z/)
1037
+ if match && match[1]&.size < istruct.post_digits
1038
+ # Add trailing zeros to pad out post_digits
1039
+ n_zeros = [istruct.post_digits - match[1].size, 0].max
1040
+ zeros = '0' * n_zeros
1041
+ result = result + zeros
1058
1042
  end
1059
- elsif istruct.post_digits >= 0
1060
- # Round to post_digits but no padding of whole number, pad fraction with
1061
- # trailing zeroes.
1062
- result = sprintf("%.#{istruct.post_digits}f", val)
1043
+ result
1044
+ end
1045
+
1046
+ if istruct.pre_digits.positive?
1047
+ match = result.match(/\A([\d,]+)(\.\d+)?\z/)
1048
+ whole_part = match[1]
1049
+ frac_part = match[2]
1050
+ n_zeros = [istruct.pre_digits - whole_part.gsub(',', '').size, 0].max
1051
+ result =
1052
+ if n_zeros.positive?
1053
+ if istruct.commas
1054
+ # Insert leading zeros with commas
1055
+ pre_comma_match = whole_part.match(/\A(\d+),/)
1056
+ if pre_comma_match
1057
+ n_partial_zeros = 3 - pre_comma_match[1].size
1058
+ whole_part = "0" * n_partial_zeros + whole_part
1059
+ n_zeros -= n_partial_zeros
1060
+ end
1061
+ zeros = ''
1062
+ if n_zeros.positive?
1063
+ zeros = "0" * n_zeros
1064
+ if n_zeros > 3 && istruct.commas
1065
+ zeros = zeros.reverse.gsub!(/([0-9]{3})/, "\\1,").reverse
1066
+ end
1067
+ end
1068
+ "#{zeros},#{whole_part}#{frac_part}"
1069
+ else
1070
+ # Insert leading zeros without commas
1071
+ zeros = "0" * n_zeros
1072
+ "#{zeros}#{whole_part}#{frac_part}"
1073
+ end
1074
+ else
1075
+ "#{whole_part}#{frac_part}"
1076
+ end
1063
1077
  else
1064
- result = val.to_s
1078
+ result
1065
1079
  end
1066
- if istruct.commas
1067
- # Commify the whole number part if not done already.
1068
- result = result.commas
1080
+ if istruct.currency
1081
+ result = "#{FatTable.currency_symbol}#{result}"
1069
1082
  end
1070
1083
  result
1071
1084
  end
@@ -1199,8 +1212,10 @@ module FatTable
1199
1212
  result += post_header(widths)
1200
1213
  end
1201
1214
  new_rows.each do |loc_row|
1202
- result += hline(widths) if loc_row.nil?
1203
- next if loc_row.nil?
1215
+ if loc_row.nil?
1216
+ result += hline(widths)
1217
+ next
1218
+ end
1204
1219
 
1205
1220
  _loc, row = *loc_row
1206
1221
  result += pre_row
@@ -379,11 +379,10 @@ module FatTable
379
379
 
380
380
  # :category: Attributes
381
381
 
382
- # Set the column type for Column with the given +key+ as a String type,
383
- # but only if empty. Otherwise, we would have to worry about converting
384
- # existing items in the column to String. Perhaps that's a TODO.
382
+ # Set the column type for Column with the given +key+ as a String type.
385
383
  def force_string!(*keys)
386
384
  keys.each do |h|
385
+ raise UserError, "force_string!: #{h} not a column in table" unless column(h)
387
386
  column(h).force_string!
388
387
  end
389
388
  self
@@ -2,5 +2,5 @@
2
2
 
3
3
  module FatTable
4
4
  # The current version of FatTable
5
- VERSION = '0.6.4'
5
+ VERSION = '0.6.6'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fat_table
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: 0.6.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel E. Doherty
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-07 00:00:00.000000000 Z
11
+ date: 2023-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -264,7 +264,7 @@ description: |2
264
264
  array of arrays with its .to_aoa output function and will be rendered in an
265
265
  org-mode buffer as an org-table, ready for processing by other code blocks.
266
266
  email:
267
- - ded-law@ddoherty.net
267
+ - ded@ddoherty.net
268
268
  executables:
269
269
  - ft_console
270
270
  extensions: []
@@ -274,6 +274,7 @@ files:
274
274
  - ".rspec"
275
275
  - ".rubocop.yml"
276
276
  - ".simplecov"
277
+ - ".solargraph.yml"
277
278
  - ".travis.yml"
278
279
  - ".yardopts"
279
280
  - Gemfile
@@ -319,7 +320,7 @@ licenses: []
319
320
  metadata:
320
321
  allowed_push_host: https://rubygems.org
321
322
  yard.run: yri
322
- post_install_message:
323
+ post_install_message:
323
324
  rdoc_options: []
324
325
  require_paths:
325
326
  - lib
@@ -334,8 +335,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
334
335
  - !ruby/object:Gem::Version
335
336
  version: '0'
336
337
  requirements: []
337
- rubygems_version: 3.3.3
338
- signing_key:
338
+ rubygems_version: 3.4.1
339
+ signing_key:
339
340
  specification_version: 4
340
341
  summary: Provides tools for working with tables as a data type.
341
342
  test_files: []