csv_plus_plus 0.0.3 → 0.0.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +1 -1
- data/bin/csv++ +13 -54
- data/lib/csv_plus_plus/cli_flag.rb +83 -0
- data/lib/csv_plus_plus/color.rb +45 -11
- data/lib/csv_plus_plus/error.rb +7 -0
- data/lib/csv_plus_plus/graph.rb +0 -5
- data/lib/csv_plus_plus/language/compiler.rb +0 -1
- data/lib/csv_plus_plus/language/scope.rb +0 -2
- data/lib/csv_plus_plus/language/syntax_error.rb +1 -1
- data/lib/csv_plus_plus/modifier.rb +4 -15
- data/lib/csv_plus_plus/modifier.tab.rb +367 -381
- data/lib/csv_plus_plus/options.rb +1 -0
- data/lib/csv_plus_plus/version.rb +1 -1
- data/lib/csv_plus_plus/writer/excel.rb +15 -2
- data/lib/csv_plus_plus/writer/google_sheet_builder.rb +12 -31
- data/lib/csv_plus_plus/writer/google_sheet_modifier.rb +56 -0
- data/lib/csv_plus_plus/writer/google_sheets.rb +4 -4
- data/lib/csv_plus_plus/writer/rubyxl_builder.rb +112 -0
- data/lib/csv_plus_plus/writer/rubyxl_modifier.rb +52 -0
- data/lib/csv_plus_plus/writer.rb +2 -3
- data/lib/csv_plus_plus.rb +1 -0
- metadata +26 -15
@@ -1,12 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative './rubyxl_builder'
|
4
|
+
|
3
5
|
module CSVPlusPlus
|
4
6
|
module Writer
|
5
7
|
# A class that can output a +Template+ to an Excel file
|
6
8
|
class Excel < ::CSVPlusPlus::Writer::BaseWriter
|
7
|
-
# write
|
9
|
+
# write the +template+ to an Excel file
|
8
10
|
def write(template)
|
9
|
-
|
11
|
+
::CSVPlusPlus::Writer::RubyXLBuilder.new(
|
12
|
+
output_filename: @options.output_filename,
|
13
|
+
rows: template.rows,
|
14
|
+
sheet_name: @options.sheet_name
|
15
|
+
).write
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def load_requires
|
21
|
+
require('rubyXL')
|
22
|
+
require('rubyXL/convenience_methods')
|
10
23
|
end
|
11
24
|
end
|
12
25
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative './google_sheet_modifier'
|
4
|
+
|
3
5
|
module CSVPlusPlus
|
4
6
|
module Writer
|
5
|
-
##
|
6
7
|
# Given +rows+ from a +Template+, build requests compatible with Google Sheets Ruby API
|
7
8
|
# rubocop:disable Metrics/ClassLength
|
8
9
|
class GoogleSheetBuilder
|
@@ -26,9 +27,7 @@ module CSVPlusPlus
|
|
26
27
|
::Google::Apis::SheetsV4
|
27
28
|
end
|
28
29
|
|
29
|
-
def sheets_color(color)
|
30
|
-
sheets_ns::Color.new(red: color.red, green: color.green, blue: color.blue)
|
31
|
-
end
|
30
|
+
def sheets_color(color); end
|
32
31
|
|
33
32
|
def set_extended_value_type!(extended_value, value)
|
34
33
|
v = value || ''
|
@@ -43,38 +42,20 @@ module CSVPlusPlus
|
|
43
42
|
end
|
44
43
|
end
|
45
44
|
|
46
|
-
|
47
|
-
sheets_ns::TextFormat.new(
|
48
|
-
bold: mod.formatted?('bold') || nil,
|
49
|
-
italic: mod.formatted?('italic') || nil,
|
50
|
-
strikethrough: mod.formatted?('strikethrough') || nil,
|
51
|
-
underline: mod.formatted?('underline') || nil,
|
52
|
-
|
53
|
-
font_family: mod.fontfamily,
|
54
|
-
font_size: mod.fontsize,
|
55
|
-
|
56
|
-
foreground_color: mod.fontcolor ? sheets_color(mod.fontcolor) : nil
|
57
|
-
)
|
58
|
-
end
|
59
|
-
|
60
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
45
|
+
# rubocop:disable Metrics/AbcSize
|
61
46
|
def build_cell_format(mod)
|
62
47
|
sheets_ns::CellFormat.new.tap do |cf|
|
63
|
-
cf.text_format =
|
48
|
+
cf.text_format = mod.text_format
|
64
49
|
|
65
|
-
|
66
|
-
cf.
|
67
|
-
cf.horizontal_alignment = 'RIGHT' if mod.aligned?('right')
|
68
|
-
cf.horizontal_alignment = 'CENTER' if mod.aligned?('center')
|
69
|
-
cf.vertical_alignment = 'TOP' if mod.aligned?('top')
|
70
|
-
cf.vertical_alignment = 'BOTTOM' if mod.aligned?('bottom')
|
50
|
+
cf.horizontal_alignment = mod.halign if mod.halign
|
51
|
+
cf.vertical_alignment = mod.valign if mod.valign
|
71
52
|
|
72
|
-
cf.background_color =
|
53
|
+
cf.background_color = mod.color if mod.color
|
73
54
|
|
74
|
-
cf.number_format =
|
55
|
+
cf.number_format = mod.numberformat if mod.numberformat
|
75
56
|
end
|
76
57
|
end
|
77
|
-
# rubocop:enable Metrics/AbcSize
|
58
|
+
# rubocop:enable Metrics/AbcSize
|
78
59
|
|
79
60
|
def grid_range_for_cell(cell)
|
80
61
|
sheets_ns::GridRange.new(
|
@@ -106,10 +87,10 @@ module CSVPlusPlus
|
|
106
87
|
end
|
107
88
|
|
108
89
|
def build_cell_data(cell)
|
109
|
-
mod = cell.modifier
|
90
|
+
mod = ::CSVPlusPlus::Writer::GoogleSheetModifier.new(cell.modifier)
|
110
91
|
|
111
92
|
sheets_ns::CellData.new.tap do |cd|
|
112
|
-
cd.user_entered_format = build_cell_format(
|
93
|
+
cd.user_entered_format = build_cell_format(mod)
|
113
94
|
cd.note = mod.note if mod.note
|
114
95
|
|
115
96
|
# XXX apply data validation
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CSVPlusPlus
|
4
|
+
module Writer
|
5
|
+
# Decorate a Modifier so it can be written to the Google Sheets API
|
6
|
+
class GoogleSheetModifier < ::SimpleDelegator
|
7
|
+
# Format the halign for Google Sheets
|
8
|
+
def halign
|
9
|
+
super&.upcase
|
10
|
+
end
|
11
|
+
|
12
|
+
# Format the valign for Google Sheets
|
13
|
+
def valign
|
14
|
+
super&.upcase
|
15
|
+
end
|
16
|
+
|
17
|
+
# Format the color for Google Sheets
|
18
|
+
def color
|
19
|
+
google_sheets_color(super) if super
|
20
|
+
end
|
21
|
+
|
22
|
+
# Format the fontcolor for Google Sheets
|
23
|
+
def fontcolor
|
24
|
+
google_sheets_color(super) if super
|
25
|
+
end
|
26
|
+
|
27
|
+
# Format the numberformat for Google Sheets
|
28
|
+
def numberformat
|
29
|
+
::Google::Apis::SheetsV4::NumberFormat.new(type: super) if super
|
30
|
+
end
|
31
|
+
|
32
|
+
# Builds a SheetsV4::TextFormat with the underlying Modifier
|
33
|
+
def text_format
|
34
|
+
::Google::Apis::SheetsV4::TextFormat.new(
|
35
|
+
bold: formatted?('bold') || nil,
|
36
|
+
italic: formatted?('italic') || nil,
|
37
|
+
strikethrough: formatted?('strikethrough') || nil,
|
38
|
+
underline: formatted?('underline') || nil,
|
39
|
+
font_family: fontfamily,
|
40
|
+
font_size: fontsize,
|
41
|
+
foreground_color: fontcolor
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def google_sheets_color(color)
|
48
|
+
::Google::Apis::SheetsV4::Color.new(
|
49
|
+
red: color.red_percent,
|
50
|
+
green: color.green_percent,
|
51
|
+
blue: color.blue_percent
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -26,8 +26,8 @@ module CSVPlusPlus
|
|
26
26
|
def write(template)
|
27
27
|
auth!
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
fetch_spreadsheet!
|
30
|
+
fetch_spreadsheet_values!
|
31
31
|
|
32
32
|
create_sheet! if @options.create_if_not_exists
|
33
33
|
|
@@ -58,7 +58,7 @@ module CSVPlusPlus
|
|
58
58
|
@gs.authorization = ::Google::Auth.get_application_default(::AUTH_SCOPES)
|
59
59
|
end
|
60
60
|
|
61
|
-
def
|
61
|
+
def fetch_spreadsheet_values!
|
62
62
|
formatted_values = get_all_spreadsheet_values('FORMATTED_VALUE')
|
63
63
|
formula_values = get_all_spreadsheet_values('FORMULA')
|
64
64
|
|
@@ -94,7 +94,7 @@ module CSVPlusPlus
|
|
94
94
|
@spreadsheet.sheets.find { |s| s.properties.title.strip == @sheet_name.strip }
|
95
95
|
end
|
96
96
|
|
97
|
-
def
|
97
|
+
def fetch_spreadsheet!
|
98
98
|
@spreadsheet = @gs.get_spreadsheet(@sheet_id)
|
99
99
|
|
100
100
|
return unless @sheet_name.nil?
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './rubyxl_modifier'
|
4
|
+
|
5
|
+
module CSVPlusPlus
|
6
|
+
module Writer
|
7
|
+
# Build a RubyXL workbook formatted according to the given +rows+
|
8
|
+
class RubyXLBuilder
|
9
|
+
attr_reader :output_filename, :rows
|
10
|
+
|
11
|
+
# initialize
|
12
|
+
def initialize(output_filename:, rows:, sheet_name:)
|
13
|
+
@rows = rows
|
14
|
+
@output_filename = output_filename
|
15
|
+
@workbook = open_workbook(sheet_name)
|
16
|
+
@worksheet = @workbook[sheet_name]
|
17
|
+
end
|
18
|
+
|
19
|
+
# write the given @rows in +sheet_name+ to +@output_filename+
|
20
|
+
def write
|
21
|
+
build_workbook!
|
22
|
+
@workbook.write(@output_filename)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def build_workbook!
|
28
|
+
@rows.each_with_index do |row, x|
|
29
|
+
row.cells.each_with_index do |cell, y|
|
30
|
+
modifier = ::CSVPlusPlus::Writer::RubyXLModifier.new(cell.modifier)
|
31
|
+
|
32
|
+
@worksheet.add_cell(x, y, cell.to_csv)
|
33
|
+
format_cell!(x, y, modifier)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def do_alignments!(cell, modifier)
|
39
|
+
cell.change_horizontal_alignment(modifier.halign) if modifier.halign
|
40
|
+
cell.change_vertical_alignment(modifier.valign) if modifier.valign
|
41
|
+
end
|
42
|
+
|
43
|
+
# rubocop:disable Metrics/MethodLength
|
44
|
+
def do_borders!(cell, modifier)
|
45
|
+
return unless modifier.any_border?
|
46
|
+
|
47
|
+
color = modifier.bordercolor
|
48
|
+
weight = modifier.border_weight
|
49
|
+
|
50
|
+
if modifier.border_all?
|
51
|
+
%i[top bottom left right].each do |direction|
|
52
|
+
# TODO: I can't support a weight and a color?
|
53
|
+
cell.change_border(direction, color || weight)
|
54
|
+
end
|
55
|
+
else
|
56
|
+
modifier.borders.each do |direction|
|
57
|
+
cell.change_border(direction, color || weight)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
# rubocop:enable Metrics/MethodLength
|
62
|
+
|
63
|
+
def do_fill!(cell, modifier)
|
64
|
+
cell.change_fill(modifier.color.to_hex) if modifier.color
|
65
|
+
end
|
66
|
+
|
67
|
+
def do_formats!(cell, modifier)
|
68
|
+
cell.change_font_bold(true) if modifier.formatted?('bold')
|
69
|
+
cell.change_font_italics(true) if modifier.formatted?('italic')
|
70
|
+
cell.change_font_underline(true) if modifier.formatted?('underline')
|
71
|
+
cell.change_font_strikethrough(true) if modifier.formatted?('strikethrough')
|
72
|
+
end
|
73
|
+
|
74
|
+
def do_fonts!(cell, modifier)
|
75
|
+
cell.change_font_color(modifier.fontcolor.to_hex) if modifier.fontcolor
|
76
|
+
cell.change_font_name(modifier.fontfamily) if modifier.fontfamily
|
77
|
+
cell.change_font_size(modifier.fontsize) if modifier.fontsize
|
78
|
+
end
|
79
|
+
|
80
|
+
def do_number_formats!(cell, modifier)
|
81
|
+
return unless modifier.numberformat
|
82
|
+
|
83
|
+
cell.set_number_format(modifier.number_format_code)
|
84
|
+
# TODO: this is annoying... we have to set the contents with the correct type of object
|
85
|
+
cell.change_contents(cell.value)
|
86
|
+
end
|
87
|
+
|
88
|
+
def format_cell!(row_index, cell_index, modifier)
|
89
|
+
@worksheet.sheet_data[row_index][cell_index].tap do |cell|
|
90
|
+
do_alignments!(cell, modifier)
|
91
|
+
do_borders!(cell, modifier)
|
92
|
+
do_fill!(cell, modifier)
|
93
|
+
do_fonts!(cell, modifier)
|
94
|
+
do_formats!(cell, modifier)
|
95
|
+
do_number_formats!(cell, modifier)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def open_workbook(sheet_name)
|
100
|
+
if ::File.exist?(@output_filename)
|
101
|
+
::RubyXL::Parser.parse(@output_filename).tap do |workbook|
|
102
|
+
workbook.add_worksheet(sheet_name) unless workbook[sheet_name]
|
103
|
+
end
|
104
|
+
else
|
105
|
+
::RubyXL::Workbook.new.tap do |workbook|
|
106
|
+
workbook.worksheets[0].sheet_name = sheet_name
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CSVPlusPlus
|
4
|
+
# Writer
|
5
|
+
module Writer
|
6
|
+
# Build a RubyXL-decorated Modifier class adds some support for Excel
|
7
|
+
class RubyXLModifier < ::SimpleDelegator
|
8
|
+
# https://www.rubydoc.info/gems/rubyXL/RubyXL/NumberFormats
|
9
|
+
# https://support.microsoft.com/en-us/office/number-format-codes-5026bbd6-04bc-48cd-bf33-80f18b4eae68
|
10
|
+
NUM_FMT_IDS = {
|
11
|
+
currency: 5,
|
12
|
+
date: 14,
|
13
|
+
date_time: 22,
|
14
|
+
number: 1,
|
15
|
+
percent: 9,
|
16
|
+
text: 49,
|
17
|
+
time: 21,
|
18
|
+
scientific: 48
|
19
|
+
}.freeze
|
20
|
+
private_constant :NUM_FMT_IDS
|
21
|
+
|
22
|
+
# https://www.rubydoc.info/gems/rubyXL/2.3.0/RubyXL
|
23
|
+
# ST_BorderStyle = %w{ none thin medium dashed dotted thick double hair mediumDashed dashDot mediumDashDot
|
24
|
+
# dashDotDot slantDashDot }
|
25
|
+
BORDER_STYLES = {
|
26
|
+
dashed: 'dashed',
|
27
|
+
dotted: 'dotted',
|
28
|
+
double: 'double',
|
29
|
+
solid: 'thin',
|
30
|
+
solid_medium: 'medium',
|
31
|
+
solid_thick: 'thick'
|
32
|
+
}.freeze
|
33
|
+
private_constant :BORDER_STYLES
|
34
|
+
|
35
|
+
# The excel-specific number format code
|
36
|
+
def number_format_code
|
37
|
+
::RubyXL::NumberFormats::DEFAULT_NUMBER_FORMATS.find_by_format_id(
|
38
|
+
# rubocop:disable Lint/ConstantResolution
|
39
|
+
NUM_FMT_IDS[numberformat.to_sym]
|
40
|
+
# rubocop:enable Lint/ConstantResolution
|
41
|
+
).format_code
|
42
|
+
end
|
43
|
+
|
44
|
+
# The excel-specific border weight
|
45
|
+
def border_weight
|
46
|
+
# rubocop:disable Lint/ConstantResolution
|
47
|
+
BORDER_STYLES[borderstyle.to_sym]
|
48
|
+
# rubocop:enable Lint/ConstantResolution
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/csv_plus_plus/writer.rb
CHANGED
@@ -7,7 +7,6 @@ require_relative './writer/google_sheets'
|
|
7
7
|
require_relative './writer/open_document'
|
8
8
|
|
9
9
|
module CSVPlusPlus
|
10
|
-
##
|
11
10
|
# Various strategies for writing to various formats (excel, google sheets, CSV, OpenDocument)
|
12
11
|
module Writer
|
13
12
|
# Return an instance of a writer depending on the given +options+
|
@@ -17,8 +16,8 @@ module CSVPlusPlus
|
|
17
16
|
case options.output_filename
|
18
17
|
when /\.csv$/ then ::CSVPlusPlus::Writer::CSV.new(options)
|
19
18
|
when /\.ods$/ then ::CSVPlusPlus::Writer::OpenDocument.new(options)
|
20
|
-
when /\.
|
21
|
-
else raise(::
|
19
|
+
when /\.xl(sx|sm|tx|tm)$/ then ::CSVPlusPlus::Writer::Excel.new(options)
|
20
|
+
else raise(::CSVPlusPlus::Error, "Unsupported file extension: #{options.output_filename}")
|
22
21
|
end
|
23
22
|
end
|
24
23
|
end
|
data/lib/csv_plus_plus.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csv_plus_plus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Patrick Carroll
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-02-
|
11
|
+
date: 2023-02-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-apis-sheets_v4
|
@@ -39,61 +39,61 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.3'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rubyXL
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
48
|
-
type: :
|
47
|
+
version: '3.4'
|
48
|
+
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '3.4'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '2'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '2'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '13'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '13'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rubocop
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '1.4'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '1.4'
|
97
97
|
description: "A programming language built on top of CSV. You can define functions
|
98
98
|
and variables to use in your spreadsheet, \nthen compile it to Excel, CSV, Google
|
99
99
|
Sheets, etc.\n"
|
@@ -108,8 +108,10 @@ files:
|
|
108
108
|
- bin/csv++
|
109
109
|
- lib/csv_plus_plus.rb
|
110
110
|
- lib/csv_plus_plus/cell.rb
|
111
|
+
- lib/csv_plus_plus/cli_flag.rb
|
111
112
|
- lib/csv_plus_plus/code_section.rb
|
112
113
|
- lib/csv_plus_plus/color.rb
|
114
|
+
- lib/csv_plus_plus/error.rb
|
113
115
|
- lib/csv_plus_plus/expand.rb
|
114
116
|
- lib/csv_plus_plus/google_options.rb
|
115
117
|
- lib/csv_plus_plus/graph.rb
|
@@ -144,13 +146,22 @@ files:
|
|
144
146
|
- lib/csv_plus_plus/writer/csv.rb
|
145
147
|
- lib/csv_plus_plus/writer/excel.rb
|
146
148
|
- lib/csv_plus_plus/writer/google_sheet_builder.rb
|
149
|
+
- lib/csv_plus_plus/writer/google_sheet_modifier.rb
|
147
150
|
- lib/csv_plus_plus/writer/google_sheets.rb
|
148
151
|
- lib/csv_plus_plus/writer/open_document.rb
|
152
|
+
- lib/csv_plus_plus/writer/rubyxl_builder.rb
|
153
|
+
- lib/csv_plus_plus/writer/rubyxl_modifier.rb
|
149
154
|
homepage: https://github.com/patrickomatic/csv-plus-plus
|
150
155
|
licenses:
|
151
156
|
- MIT
|
152
157
|
metadata:
|
153
158
|
rubygems_mfa_required: 'true'
|
159
|
+
bug_tracker_uri: https://github.com/patrickomatic/csv-plus-plus/issues
|
160
|
+
documentation_uri: https://www.rubydoc.info/gems/csv_plus_plus/
|
161
|
+
github_repo: git://github.com/patrickomatic/csv_plus_plus
|
162
|
+
homepage_uri: https://github.com/patrickomatic/csv_plus_plus
|
163
|
+
source_code_uri: https://github.com/patrickomatic/csv_plus_plus
|
164
|
+
changelog_uri: https://github.com/patrickomatic/csv_plus_plus/blob/main/CHANGELOG.md
|
154
165
|
post_install_message:
|
155
166
|
rdoc_options: []
|
156
167
|
require_paths:
|