csv_plus_plus 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -1
- data/README.md +18 -62
- data/lib/csv_plus_plus/benchmarked_compiler.rb +62 -0
- data/lib/csv_plus_plus/can_define_references.rb +88 -0
- data/lib/csv_plus_plus/can_resolve_references.rb +8 -0
- data/lib/csv_plus_plus/cell.rb +3 -3
- data/lib/csv_plus_plus/cli.rb +24 -7
- data/lib/csv_plus_plus/color.rb +12 -6
- data/lib/csv_plus_plus/compiler.rb +156 -0
- data/lib/csv_plus_plus/data_validation.rb +138 -0
- data/lib/csv_plus_plus/{language → entities}/ast_builder.rb +5 -7
- data/lib/csv_plus_plus/entities/boolean.rb +31 -0
- data/lib/csv_plus_plus/{language → entities}/builtins.rb +2 -4
- data/lib/csv_plus_plus/entities/cell_reference.rb +60 -0
- data/lib/csv_plus_plus/entities/date.rb +30 -0
- data/lib/csv_plus_plus/entities/entity.rb +84 -0
- data/lib/csv_plus_plus/entities/function.rb +33 -0
- data/lib/csv_plus_plus/entities/function_call.rb +35 -0
- data/lib/csv_plus_plus/entities/number.rb +34 -0
- data/lib/csv_plus_plus/entities/runtime_value.rb +26 -0
- data/lib/csv_plus_plus/entities/string.rb +29 -0
- data/lib/csv_plus_plus/entities/variable.rb +25 -0
- data/lib/csv_plus_plus/entities.rb +33 -0
- data/lib/csv_plus_plus/error/error.rb +10 -0
- data/lib/csv_plus_plus/error/formula_syntax_error.rb +36 -0
- data/lib/csv_plus_plus/error/modifier_syntax_error.rb +27 -0
- data/lib/csv_plus_plus/error/modifier_validation_error.rb +49 -0
- data/lib/csv_plus_plus/{language → error}/syntax_error.rb +6 -14
- data/lib/csv_plus_plus/error/writer_error.rb +9 -0
- data/lib/csv_plus_plus/error.rb +9 -2
- data/lib/csv_plus_plus/expand.rb +3 -1
- data/lib/csv_plus_plus/google_api_client.rb +4 -0
- data/lib/csv_plus_plus/lexer/lexer.rb +19 -11
- data/lib/csv_plus_plus/modifier/conditional_formatting.rb +17 -0
- data/lib/csv_plus_plus/modifier.rb +73 -70
- data/lib/csv_plus_plus/options.rb +3 -0
- data/lib/csv_plus_plus/parser/cell_value.tab.rb +305 -0
- data/lib/csv_plus_plus/parser/code_section.tab.rb +410 -0
- data/lib/csv_plus_plus/parser/modifier.tab.rb +484 -0
- data/lib/csv_plus_plus/references.rb +68 -0
- data/lib/csv_plus_plus/row.rb +0 -3
- data/lib/csv_plus_plus/runtime.rb +199 -0
- data/lib/csv_plus_plus/scope.rb +196 -0
- data/lib/csv_plus_plus/template.rb +21 -5
- data/lib/csv_plus_plus/validated_modifier.rb +164 -0
- data/lib/csv_plus_plus/version.rb +1 -1
- data/lib/csv_plus_plus/writer/file_backer_upper.rb +6 -4
- data/lib/csv_plus_plus/writer/google_sheet_builder.rb +24 -29
- data/lib/csv_plus_plus/writer/google_sheet_modifier.rb +33 -12
- data/lib/csv_plus_plus/writer/rubyxl_builder.rb +3 -6
- data/lib/csv_plus_plus.rb +41 -16
- metadata +34 -24
- data/lib/csv_plus_plus/code_section.rb +0 -68
- data/lib/csv_plus_plus/language/benchmarked_compiler.rb +0 -65
- data/lib/csv_plus_plus/language/cell_value.tab.rb +0 -332
- data/lib/csv_plus_plus/language/code_section.tab.rb +0 -442
- data/lib/csv_plus_plus/language/compiler.rb +0 -157
- data/lib/csv_plus_plus/language/entities/boolean.rb +0 -33
- data/lib/csv_plus_plus/language/entities/cell_reference.rb +0 -33
- data/lib/csv_plus_plus/language/entities/entity.rb +0 -86
- data/lib/csv_plus_plus/language/entities/function.rb +0 -35
- data/lib/csv_plus_plus/language/entities/function_call.rb +0 -26
- data/lib/csv_plus_plus/language/entities/number.rb +0 -36
- data/lib/csv_plus_plus/language/entities/runtime_value.rb +0 -28
- data/lib/csv_plus_plus/language/entities/string.rb +0 -31
- data/lib/csv_plus_plus/language/entities/variable.rb +0 -25
- data/lib/csv_plus_plus/language/entities.rb +0 -28
- data/lib/csv_plus_plus/language/references.rb +0 -70
- data/lib/csv_plus_plus/language/runtime.rb +0 -205
- data/lib/csv_plus_plus/language/scope.rb +0 -188
- data/lib/csv_plus_plus/modifier.tab.rb +0 -907
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './syntax_error'
|
4
|
+
|
5
|
+
module CSVPlusPlus
|
6
|
+
module Error
|
7
|
+
# An Error that wraps a +ModifierValidationError+ with a +Runtime+.
|
8
|
+
class ModifierSyntaxError < ::CSVPlusPlus::Error::SyntaxError
|
9
|
+
# You must supply either a +choices+ or +message+
|
10
|
+
#
|
11
|
+
# @param runtime [Runtime] The current runtime
|
12
|
+
# @param wrapped_error [ModifierValidationError] The validtion error that this is wrapping
|
13
|
+
def initialize(runtime, wrapped_error:)
|
14
|
+
@wrapped_error = wrapped_error
|
15
|
+
|
16
|
+
super(runtime, wrapped_error:)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Calls +wrapped_error.error_message+.
|
20
|
+
#
|
21
|
+
# @return [::String]
|
22
|
+
def error_message
|
23
|
+
@wrapped_error.error_message
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './syntax_error'
|
4
|
+
|
5
|
+
module CSVPlusPlus
|
6
|
+
module Error
|
7
|
+
# An error that can be thrown when a modifier doesn't pass our validation.
|
8
|
+
#
|
9
|
+
# @attr_reader modifier [Symbol] The modifier being parsed when the bad input was encountered
|
10
|
+
# @attr_reader bad_input [String] The offending input that caused the error to be thrown
|
11
|
+
# @attr_reader choices [Array<Symbol>, nil] The choices that +value+ must be one of (but violated)
|
12
|
+
# @attr_reader message [String, nil] A relevant message to show
|
13
|
+
class ModifierValidationError < ::CSVPlusPlus::Error::Error
|
14
|
+
attr_reader :bad_input, :choices, :message, :modifier
|
15
|
+
|
16
|
+
# You must supply either a +choices+ or +message+
|
17
|
+
#
|
18
|
+
# @param modifier [Symbol] The modifier being parsed when the bad input was encountered
|
19
|
+
# @param bad_input [String] The offending input that caused the error to be thrown
|
20
|
+
# @param choices [Array<Symbol>, nil] The choices that +value+ must be one of (but violated)
|
21
|
+
# @param message [String, nil] A relevant message to show
|
22
|
+
def initialize(modifier, bad_input, choices: nil, message: nil)
|
23
|
+
@bad_input = bad_input
|
24
|
+
@choices = choices
|
25
|
+
@modifier = modifier
|
26
|
+
|
27
|
+
@message =
|
28
|
+
if @choices
|
29
|
+
"must be one of (#{@choices.map(&:to_s).join(', ')})"
|
30
|
+
else
|
31
|
+
message
|
32
|
+
end
|
33
|
+
|
34
|
+
super(@message)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Create a relevant error message given +@choices+ or +@message+ (one of them must be supplied).
|
38
|
+
#
|
39
|
+
# @return [::String]
|
40
|
+
def error_message
|
41
|
+
<<~ERROR_MESSAGE
|
42
|
+
Error parsing modifier: [[#{@modifier}=...]]
|
43
|
+
Bad input: #{@bad_input}
|
44
|
+
Reason: #{@message}
|
45
|
+
ERROR_MESSAGE
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,21 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module CSVPlusPlus
|
4
|
-
module
|
4
|
+
module Error
|
5
5
|
# An error that can be thrown for various syntax errors
|
6
|
-
class SyntaxError < ::CSVPlusPlus::Error
|
7
|
-
# @param message [String] The primary message to be shown to the user
|
8
|
-
# @param bad_input [String] The offending input that caused the error to be thrown
|
6
|
+
class SyntaxError < ::CSVPlusPlus::Error::Error
|
9
7
|
# @param runtime [Runtime] The current runtime
|
10
8
|
# @param wrapped_error [StandardError] The underlying error that caused the syntax error. For example a
|
11
9
|
# Racc::ParseError that was thrown
|
12
|
-
def initialize(
|
13
|
-
@bad_input = bad_input.to_s
|
10
|
+
def initialize(runtime, wrapped_error: nil)
|
14
11
|
@runtime = runtime
|
15
12
|
@wrapped_error = wrapped_error
|
16
|
-
@message = message
|
17
13
|
|
18
|
-
super(
|
14
|
+
super()
|
19
15
|
end
|
20
16
|
|
21
17
|
# @return [String]
|
@@ -34,7 +30,7 @@ module CSVPlusPlus
|
|
34
30
|
#
|
35
31
|
# @return [String]
|
36
32
|
def to_trace
|
37
|
-
"#{message_prefix}#{cell_index} #{
|
33
|
+
"#{message_prefix}#{cell_index} #{error_message}"
|
38
34
|
end
|
39
35
|
|
40
36
|
private
|
@@ -55,11 +51,7 @@ module CSVPlusPlus
|
|
55
51
|
filename = @runtime.filename
|
56
52
|
|
57
53
|
line_str = line_number ? ":#{line_number}" : ''
|
58
|
-
"
|
59
|
-
end
|
60
|
-
|
61
|
-
def message_postfix
|
62
|
-
"#{@message}: \"#{@bad_input}\""
|
54
|
+
"#{filename}#{line_str}"
|
63
55
|
end
|
64
56
|
end
|
65
57
|
end
|
data/lib/csv_plus_plus/error.rb
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative './error/error'
|
4
|
+
require_relative './error/formula_syntax_error'
|
5
|
+
require_relative './error/modifier_syntax_error'
|
6
|
+
require_relative './error/modifier_validation_error'
|
7
|
+
require_relative './error/syntax_error'
|
8
|
+
require_relative './error/writer_error'
|
9
|
+
|
3
10
|
module CSVPlusPlus
|
4
|
-
#
|
5
|
-
|
11
|
+
# A module containing errors to be raised
|
12
|
+
module Error
|
6
13
|
end
|
7
14
|
end
|
data/lib/csv_plus_plus/expand.rb
CHANGED
@@ -4,11 +4,13 @@ module CSVPlusPlus
|
|
4
4
|
Expand =
|
5
5
|
::Struct.new(:repetitions) do
|
6
6
|
# Does this infinitely expand?
|
7
|
+
#
|
8
|
+
# @return [boolean]
|
7
9
|
def infinite?
|
8
10
|
repetitions.nil?
|
9
11
|
end
|
10
12
|
|
11
|
-
#
|
13
|
+
# @return [::String]
|
12
14
|
def to_s
|
13
15
|
"Expand #{repetitions || 'infinity'}"
|
14
16
|
end
|
@@ -4,6 +4,8 @@ module CSVPlusPlus
|
|
4
4
|
# A convenience wrapper around Google's REST API client
|
5
5
|
module GoogleApiClient
|
6
6
|
# Get a +::Google::Apis::SheetsV4::SheetsService+ instance connected to the sheets API
|
7
|
+
#
|
8
|
+
# @return [Google::Apis::SheetsV4::SheetsService]
|
7
9
|
def self.sheets_client
|
8
10
|
::Google::Apis::SheetsV4::SheetsService.new.tap do |s|
|
9
11
|
s.authorization = ::Google::Auth.get_application_default(['https://www.googleapis.com/auth/spreadsheets'].freeze)
|
@@ -11,6 +13,8 @@ module CSVPlusPlus
|
|
11
13
|
end
|
12
14
|
|
13
15
|
# Get a +::Google::Apis::DriveV3::DriveService+ instance connected to the drive API
|
16
|
+
#
|
17
|
+
# @return [Google::Apis::DriveV3::DriveService]
|
14
18
|
def self.drive_client
|
15
19
|
::Google::Apis::DriveV3::DriveService.new.tap do |d|
|
16
20
|
d.authorization = ::Google::Auth.get_application_default(['https://www.googleapis.com/auth/drive.file'].freeze)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../color'
|
4
|
+
|
3
5
|
module CSVPlusPlus
|
4
6
|
# Common methods to be mixed into the Racc parsers
|
5
7
|
#
|
@@ -32,18 +34,23 @@ module CSVPlusPlus
|
|
32
34
|
do_parse
|
33
35
|
return_value
|
34
36
|
rescue ::Racc::ParseError => e
|
35
|
-
runtime.
|
37
|
+
runtime.raise_formula_syntax_error("Error parsing #{parse_subject}", e.message, wrapped_error: e)
|
38
|
+
rescue ::CSVPlusPlus::Error::ModifierValidationError => e
|
39
|
+
raise(::CSVPlusPlus::Error::ModifierSyntaxError.new(runtime, wrapped_error: e))
|
36
40
|
end
|
37
41
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
42
|
+
TOKEN_LIBRARY = {
|
43
|
+
A1_NOTATION: [::CSVPlusPlus::Entities::CellReference::A1_NOTATION_REGEXP, :A1_NOTATION],
|
44
|
+
FALSE: [/false/i, :FALSE],
|
45
|
+
HEX_COLOR: [::CSVPlusPlus::Color::HEX_STRING_REGEXP, :HEX_COLOR],
|
46
|
+
ID: [/[$!\w:]+/, :ID],
|
47
|
+
INFIX_OP: [%r{\^|\+|-|\*|/|&|<|>|<=|>=|<>}, :INFIX_OP],
|
48
|
+
NUMBER: [/-?[\d.]+/, :NUMBER],
|
49
|
+
STRING: [%r{"(?:[^"\\]|\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4}))*"}, :STRING],
|
50
|
+
TRUE: [/true/i, :TRUE],
|
51
|
+
VAR_REF: [/\$\$/, :VAR_REF]
|
52
|
+
}.freeze
|
53
|
+
public_constant :TOKEN_LIBRARY
|
47
54
|
|
48
55
|
private
|
49
56
|
|
@@ -70,7 +77,8 @@ module CSVPlusPlus
|
|
70
77
|
elsif tokenizer.scan_catchall
|
71
78
|
@tokens << [tokenizer.last_match, tokenizer.last_match]
|
72
79
|
else
|
73
|
-
|
80
|
+
# TODO: this should raise a modifier_syntax_error if we're on the modifier parser
|
81
|
+
runtime.raise_formula_syntax_error("Unable to parse #{parse_subject} starting at", tokenizer.peek)
|
74
82
|
end
|
75
83
|
end
|
76
84
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CSVPlusPlus
|
4
|
+
module Modifier
|
5
|
+
# A class that handles the rules for modifiers to support conditional formatting.
|
6
|
+
class ConditionalFormatting
|
7
|
+
attr_reader :arguments, :condition, :invalid_reason
|
8
|
+
|
9
|
+
# @param value [::String] The unparsed conditional formatting rule
|
10
|
+
def initialize(value)
|
11
|
+
condition, args = value.split(/\si:\s*/)
|
12
|
+
@condition = condition.to_sym
|
13
|
+
@arguments = args.split(/\s+/)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,37 +1,56 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'set'
|
4
|
-
require_relative './color'
|
5
|
-
require_relative './expand'
|
6
|
-
require_relative './language/syntax_error'
|
7
|
-
|
8
3
|
module CSVPlusPlus
|
9
4
|
# A container representing the operations that can be applied to a cell or row
|
10
5
|
#
|
11
|
-
# @attr
|
6
|
+
# @attr bordercolor [Color]
|
7
|
+
# @attr borders [Array<Symbol>] The borders that will be set
|
8
|
+
# @attr color [Color] The background color of the cell
|
12
9
|
# @attr expand [Expand] Whether this row expands into multiple rows
|
13
|
-
# @attr
|
14
|
-
# @attr
|
15
|
-
# @attr
|
16
|
-
# @attr
|
17
|
-
# @attr
|
18
|
-
# @attr
|
10
|
+
# @attr fontcolor [Color] The font color of the cell
|
11
|
+
# @attr fontfamily [::String] The font family
|
12
|
+
# @attr fontsize [Integer] The font size
|
13
|
+
# @attr halign [:left, :center, :right] Horizontal alignment
|
14
|
+
# @attr note [::String] A note/comment on the cell
|
15
|
+
# @attr numberformat [Symbol] A number format to apply to the value in the cell
|
16
|
+
# @attr row_level [boolean] Is this a row modifier? If so it's values will apply to all cells in the row
|
19
17
|
# (unless overridden by the cell modifier)
|
20
18
|
# @attr validation [Object]
|
21
|
-
# @attr valign [
|
19
|
+
# @attr valign [:top, :center, :bottom] Vertical alignment
|
20
|
+
# @attr var [Symbol] The variable bound to this cell
|
22
21
|
#
|
23
|
-
# @attr_writer borderstyle [
|
22
|
+
# @attr_writer borderstyle [:hashed, :dotted, :double, :solid, :solid_medium, :solid_thick]
|
24
23
|
# The style of border on the cell
|
25
24
|
#
|
26
|
-
# @attr_reader
|
27
|
-
# @attr_reader
|
28
|
-
# @attr_reader color [Color] The background color of the cell
|
29
|
-
# @attr_reader fontcolor [Color] The font color of the cell
|
30
|
-
# @attr_reader formats [Array<String>] Bold/italics/underline/strikethrough formatting
|
25
|
+
# @attr_reader borders [Array<Symbol>]
|
26
|
+
# @attr_reader formats [Array<Symbol>] Bold/italics/underline/strikethrough formatting
|
31
27
|
class Modifier
|
32
|
-
|
28
|
+
attr_accessor :bordercolor,
|
29
|
+
:color,
|
30
|
+
:expand,
|
31
|
+
:fontcolor,
|
32
|
+
:fontfamily,
|
33
|
+
:fontsize,
|
34
|
+
:halign,
|
35
|
+
:valign,
|
36
|
+
:note,
|
37
|
+
:numberformat,
|
38
|
+
:row_level,
|
39
|
+
:validation,
|
40
|
+
:var
|
41
|
+
attr_reader :borders, :formats
|
33
42
|
attr_writer :borderstyle
|
34
|
-
|
43
|
+
|
44
|
+
# When instantiating a new object, extend it with our validation functionality.
|
45
|
+
#
|
46
|
+
# I'm not sure why I need to do it this way tbh, using +include ValidatedModifier+ at the
|
47
|
+
# class level didn't seem to have access to the parent methods
|
48
|
+
# def self.new(*args, **kwargs, &)
|
49
|
+
# allocate.tap do |i|
|
50
|
+
# i.__send__(:initialize, *args, **kwargs, &)
|
51
|
+
# i.extend(::CSVPlusPlus::ValidatedModifier)
|
52
|
+
# end
|
53
|
+
# end
|
35
54
|
|
36
55
|
# @param row_level [Boolean] Whether or not this modifier applies to the entire row
|
37
56
|
def initialize(row_level: false)
|
@@ -41,70 +60,68 @@ module CSVPlusPlus
|
|
41
60
|
@formats = ::Set.new
|
42
61
|
end
|
43
62
|
|
44
|
-
#
|
63
|
+
# Are there any borders set?
|
64
|
+
#
|
65
|
+
# @return [Boolean]
|
66
|
+
def any_border?
|
67
|
+
!@borders.empty?
|
68
|
+
end
|
69
|
+
|
70
|
+
# Style of border
|
45
71
|
#
|
46
|
-
# @
|
72
|
+
# @return [Symbol]
|
73
|
+
def borderstyle
|
74
|
+
@borderstyle || :solid
|
75
|
+
end
|
76
|
+
|
77
|
+
# Is this a cell-level modifier?
|
47
78
|
#
|
48
|
-
# @return [
|
49
|
-
def
|
50
|
-
|
79
|
+
# @return [Boolean]
|
80
|
+
def cell_level?
|
81
|
+
!@row_level
|
51
82
|
end
|
52
83
|
|
53
84
|
# Assign a border
|
54
85
|
#
|
55
|
-
# @param side [
|
86
|
+
# @param side [:top, :left, :bottom, :right, :all]
|
56
87
|
def border=(side)
|
57
88
|
@borders << side
|
58
89
|
end
|
59
90
|
|
60
91
|
# Does this have a border along +side+?
|
61
92
|
#
|
62
|
-
# @param side [
|
93
|
+
# @param side [:top, :left, :bottom, :right, :all]
|
63
94
|
#
|
64
|
-
# @return [
|
95
|
+
# @return [boolean]
|
65
96
|
def border_along?(side)
|
66
|
-
@borders.include?(
|
97
|
+
@borders.include?(:all) || @borders.include?(side)
|
67
98
|
end
|
68
99
|
|
69
100
|
# Does this have a border along all sides?
|
70
101
|
#
|
71
|
-
# @return [
|
102
|
+
# @return [boolean]
|
72
103
|
def border_all?
|
73
|
-
@borders.include?(
|
74
|
-
|| (border_along?(
|
75
|
-
end
|
76
|
-
|
77
|
-
# Set the bordercolor
|
78
|
-
#
|
79
|
-
# @param hex_value [String] formatted as '#000000', '#000' or '000000'
|
80
|
-
def bordercolor=(hex_value)
|
81
|
-
@bordercolor = ::CSVPlusPlus::Color.new(hex_value)
|
104
|
+
@borders.include?(:all) \
|
105
|
+
|| (border_along?(:top) && border_along?(:bottom) && border_along?(:left) && border_along?(:right))
|
82
106
|
end
|
83
107
|
|
84
|
-
#
|
108
|
+
# Set this modifier to expand infinitely
|
85
109
|
#
|
86
|
-
# @return [
|
87
|
-
def
|
88
|
-
|
89
|
-
end
|
90
|
-
|
91
|
-
# Set the fontcolor
|
92
|
-
#
|
93
|
-
# @param hex_value [String] formatted as '#000000', '#000' or '000000'
|
94
|
-
def fontcolor=(hex_value)
|
95
|
-
@fontcolor = ::CSVPlusPlus::Color.new(hex_value)
|
110
|
+
# @return [::Expand]
|
111
|
+
def expand!
|
112
|
+
@expand = ::CSVPlusPlus::Expand.new if row_level?
|
96
113
|
end
|
97
114
|
|
98
115
|
# Set a text format (bolid, italic, underline or strikethrough)
|
99
116
|
#
|
100
|
-
# @param value [
|
117
|
+
# @param value [:bold, :italic, :underline, :strikethrough]
|
101
118
|
def format=(value)
|
102
119
|
@formats << value
|
103
120
|
end
|
104
121
|
|
105
122
|
# Is the given format set?
|
106
123
|
#
|
107
|
-
# @param type [
|
124
|
+
# @param type [:bold, :italic, :underline, :strikethrough]
|
108
125
|
#
|
109
126
|
# @return [Boolean]
|
110
127
|
def formatted?(type)
|
@@ -120,7 +137,7 @@ module CSVPlusPlus
|
|
120
137
|
|
121
138
|
# Is the row frozen?
|
122
139
|
#
|
123
|
-
# @return [
|
140
|
+
# @return [boolean]
|
124
141
|
def frozen?
|
125
142
|
@frozen
|
126
143
|
end
|
@@ -134,26 +151,12 @@ module CSVPlusPlus
|
|
134
151
|
|
135
152
|
# Is this a row-level modifier?
|
136
153
|
#
|
137
|
-
# @return [
|
154
|
+
# @return [boolean]
|
138
155
|
def row_level?
|
139
156
|
@row_level
|
140
157
|
end
|
141
158
|
|
142
|
-
#
|
143
|
-
#
|
144
|
-
# @return [Boolean]
|
145
|
-
def cell_level?
|
146
|
-
!@row_level
|
147
|
-
end
|
148
|
-
|
149
|
-
# Style of border
|
150
|
-
#
|
151
|
-
# @return [String]
|
152
|
-
def borderstyle
|
153
|
-
@borderstyle || 'solid'
|
154
|
-
end
|
155
|
-
|
156
|
-
# @return [String]
|
159
|
+
# @return [::String]
|
157
160
|
def to_s
|
158
161
|
# TODO... I dunno, not sure how to manage this
|
159
162
|
"Modifier(row_level: #{@row_level} halign: #{@halign} valign: #{@valign} format: #{@formats} " \
|
@@ -31,12 +31,14 @@ module CSVPlusPlus
|
|
31
31
|
#
|
32
32
|
# @param sheet_id [String] The identifier used by Google's API to reference the sheet. You can find it in the URL
|
33
33
|
# for the sheet
|
34
|
+
#
|
34
35
|
# @return [String]
|
35
36
|
def google_sheet_id=(sheet_id)
|
36
37
|
@google = ::CSVPlusPlus::GoogleOptions.new(sheet_id)
|
37
38
|
end
|
38
39
|
|
39
40
|
# Returns an error string or nil if there are no validation problems
|
41
|
+
#
|
40
42
|
# @return [String, nil]
|
41
43
|
def validate
|
42
44
|
return if @google || @output_filename
|
@@ -45,6 +47,7 @@ module CSVPlusPlus
|
|
45
47
|
end
|
46
48
|
|
47
49
|
# Return a string with a verbose description of what we're doing with the options
|
50
|
+
#
|
48
51
|
# @return [String]
|
49
52
|
def verbose_summary
|
50
53
|
<<~SUMMARY
|