csv_plus_plus 0.0.3 → 0.0.5
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 +11 -0
- data/README.md +9 -4
- data/bin/csv++ +1 -78
- data/bin/csvpp +6 -0
- data/lib/csv_plus_plus/cli.rb +84 -0
- 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/google_api_client.rb +20 -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/entities/boolean.rb +3 -3
- data/lib/csv_plus_plus/language/entities/entity.rb +10 -6
- 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 +49 -22
- data/lib/csv_plus_plus/modifier.tab.rb +367 -381
- data/lib/csv_plus_plus/options.rb +1 -1
- data/lib/csv_plus_plus/version.rb +1 -1
- data/lib/csv_plus_plus/writer/base_writer.rb +0 -1
- data/lib/csv_plus_plus/writer/csv.rb +4 -1
- data/lib/csv_plus_plus/writer/excel.rb +18 -2
- data/lib/csv_plus_plus/writer/file_backer_upper.rb +56 -0
- 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 +25 -38
- 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 +6 -1
- metadata +45 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4f5c9b5a342102fa8e1c31b319fb05f19ad55278bc633435129254b5b2511a8
|
4
|
+
data.tar.gz: 0c2656d4d7b22d0b3b3311745ed5a70b789277c622f0f2d09d2b8a144de71a8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90965e2275cc7988f4054b59e30523cd645b21c1adb89797828e86a767217b09ac174bbc17094604dd608b93defd79f4c9a74ccf7e2f20dd17995f8c1b5dadac
|
7
|
+
data.tar.gz: 291011896232e88a7bd0e252887459986812d2877c1d0383458250e1c30cf735d8b2bdaf5dd759f44fa5b8b33b08f74d780df7960622ab774e9f6d856628508f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## v0.0.5
|
2
|
+
|
3
|
+
- Support the --backup/-b option
|
4
|
+
- bin/csvpp (which does the same thing as bin/csv++ but will work better on other filesystems)
|
5
|
+
- Fix links in gemspec (which end up on rubygems.org)
|
6
|
+
- docs & tests
|
7
|
+
|
8
|
+
## v0.0.4
|
9
|
+
|
10
|
+
- Excel support
|
11
|
+
|
1
12
|
## v0.0.3
|
2
13
|
|
3
14
|
- Fix the gem package to include the bin/ file
|
data/README.md
CHANGED
@@ -9,7 +9,7 @@ A tool that allows you to programatically author spreadsheets in your favorite t
|
|
9
9
|
A `csvpp` file consists of a (optional) code section and a CSV section separated by `---`. In the code section you can define variables and functions that can be used in the CSV below it. For example:
|
10
10
|
|
11
11
|
```
|
12
|
-
fees := 0.
|
12
|
+
fees := 0.50 # my broker charges $0.50 a trade
|
13
13
|
|
14
14
|
price := cellref(C)
|
15
15
|
quantity := cellref(D)
|
@@ -21,12 +21,17 @@ def profit() (price * quantity) - fees
|
|
21
21
|
![[expand]],[[format=bold]],,,"=PROFIT()",$$fees
|
22
22
|
```
|
23
23
|
|
24
|
-
##
|
24
|
+
## Variables
|
25
25
|
|
26
|
-
|
26
|
+
Variables can be defined in the code section by giving a name (a combination of letters, numbers and underscores ) the expression `:=` and followed with a value.
|
27
27
|
|
28
|
-
|
28
|
+
### Built-in Variables
|
29
29
|
|
30
|
+
* `$$rownum` - The current row number. The first row of the spreadsheet starts at 1. Can be used anywhere and it's value will evaluate to the current row being processed.
|
31
|
+
|
32
|
+
## Functions
|
33
|
+
|
34
|
+
### Built-in Functions
|
30
35
|
* `cellref(CELL)` - Returns a reference to the `CELL` relative to the current row. If the current `$$rownum` is `2`, then `CELLREF("C")` returns a reference to cell `C2`.
|
31
36
|
|
32
37
|
## Modifiers
|
data/bin/csv++
CHANGED
@@ -1,83 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require 'optparse'
|
5
4
|
require_relative '../lib/csv_plus_plus'
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
option_parser =
|
10
|
-
# rubocop:disable Metrics/BlockLength
|
11
|
-
::OptionParser.new do |parser|
|
12
|
-
parser.on('-b', '--backup', 'Create a backup of the spreadsheet before applying changes.') do
|
13
|
-
options.backup = true
|
14
|
-
end
|
15
|
-
|
16
|
-
parser.on(
|
17
|
-
'-g SHEET_ID',
|
18
|
-
'--google-sheet-id SHEET_ID',
|
19
|
-
'The id of the sheet - you can extract this from the URL: ' \
|
20
|
-
'https://docs.google.com/spreadsheets/d/< ... SHEET_ID ... >/edit#gid=0'
|
21
|
-
) do |v|
|
22
|
-
options.google_sheet_id = v
|
23
|
-
end
|
24
|
-
|
25
|
-
parser.on('-c', '--create', "Create the sheet if it doesn't exist. It will use --sheet-name if specified") do
|
26
|
-
options.create_if_not_exists = true
|
27
|
-
end
|
28
|
-
|
29
|
-
parser.on(
|
30
|
-
'-k KEY_VALUES',
|
31
|
-
'--key-values KEY_VALUES',
|
32
|
-
'A comma-separated list of key=values which will be made available to the template'
|
33
|
-
) do |v|
|
34
|
-
options.key_values =
|
35
|
-
begin
|
36
|
-
[v.split('=')].to_h
|
37
|
-
rescue ::StandardError
|
38
|
-
{}
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
parser.on('-n SHEET_NAME', '--sheet-name SHEET_NAME', 'The name of the sheet to apply the template to') do |v|
|
43
|
-
options.sheet_name = v
|
44
|
-
end
|
45
|
-
|
46
|
-
parser.on('-o OUTPUT_FILE', '--output OUTPUT_FILE', 'The file to write to (must be .csv, .ods, .xls)') do |v|
|
47
|
-
options.output_filename = v
|
48
|
-
end
|
49
|
-
|
50
|
-
parser.on('-v', '--verbose', 'Enable verbose output') do
|
51
|
-
options.verbose = true
|
52
|
-
end
|
53
|
-
|
54
|
-
parser.on('-x OFFSET', '--offset-columns OFFSET', 'Apply the template offset by OFFSET cells') do |v|
|
55
|
-
options.offset[0] = v
|
56
|
-
end
|
57
|
-
|
58
|
-
parser.on('-y OFFSET', '--offset-rows OFFSET', 'Apply the template offset by OFFSET rows') do |v|
|
59
|
-
options.offset[1] = v
|
60
|
-
end
|
61
|
-
|
62
|
-
parser.on('-h', '--help', 'Show help information') do
|
63
|
-
puts(parser)
|
64
|
-
exit
|
65
|
-
end
|
66
|
-
end
|
67
|
-
# rubocop:enable Metrics/BlockLength
|
68
|
-
|
69
|
-
option_parser.parse!
|
70
|
-
|
71
|
-
error_message = options.validate
|
72
|
-
unless error_message.nil?
|
73
|
-
warn(error_message)
|
74
|
-
puts(option_parser)
|
75
|
-
exit(1)
|
76
|
-
end
|
77
|
-
|
78
|
-
begin
|
79
|
-
::CSVPlusPlus.apply_template_to_sheet!(::ARGF.read, ::ARGF.filename, options)
|
80
|
-
rescue ::CSVPlusPlus::Language::SyntaxError => e
|
81
|
-
warn(options.verbose ? e.to_verbose_trace : e.to_trace)
|
82
|
-
exit(1)
|
83
|
-
end
|
6
|
+
::CSVPlusPlus::CLI.launch_compiler!
|
data/bin/csvpp
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
module CSVPlusPlus
|
6
|
+
# Handle running the application with the given CLI flags
|
7
|
+
class CLI
|
8
|
+
# handle any CLI flags and launch the compiler
|
9
|
+
def self.launch_compiler!
|
10
|
+
cli = new
|
11
|
+
cli.compile!
|
12
|
+
rescue ::StandardError => e
|
13
|
+
cli.handle_error(e)
|
14
|
+
exit(1)
|
15
|
+
end
|
16
|
+
|
17
|
+
# initialize
|
18
|
+
def initialize
|
19
|
+
parse_options!
|
20
|
+
end
|
21
|
+
|
22
|
+
# compile the given template, using the given CLI flags
|
23
|
+
def compile!
|
24
|
+
::CSVPlusPlus.apply_template_to_sheet!(::ARGF.read, ::ARGF.filename, @options)
|
25
|
+
end
|
26
|
+
|
27
|
+
# (nicely) handle a given error. how it's handled depends on if it's our error and if @options.verbose
|
28
|
+
def handle_error(error)
|
29
|
+
case error
|
30
|
+
when ::CSVPlusPlus::Error
|
31
|
+
handle_internal_error(error)
|
32
|
+
when ::Google::Apis::ClientError
|
33
|
+
handle_google_error(error)
|
34
|
+
else
|
35
|
+
# TODO: more if verbose?
|
36
|
+
warn(error.message)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def handle_internal_error(error)
|
43
|
+
if error.is_a?(::CSVPlusPlus::Language::SyntaxError)
|
44
|
+
warn(@options.verbose ? error.to_verbose_trace : error.to_trace)
|
45
|
+
else
|
46
|
+
warn(error.message)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def handle_google_error(error)
|
51
|
+
warn("Error making Google Sheets API request: #{error.message}")
|
52
|
+
return unless @options.verbose
|
53
|
+
|
54
|
+
warn("#{error.status_code} Error making Google API request [#{error.message}]: #{error.body}")
|
55
|
+
end
|
56
|
+
|
57
|
+
def parse_options!
|
58
|
+
@options = ::CSVPlusPlus::Options.new
|
59
|
+
option_parser.parse!
|
60
|
+
validate_options
|
61
|
+
end
|
62
|
+
|
63
|
+
def validate_options
|
64
|
+
error_message = @options.validate
|
65
|
+
return if error_message.nil?
|
66
|
+
|
67
|
+
puts(option_parser)
|
68
|
+
raise(::CSVPlusPlus::Error, error_message)
|
69
|
+
end
|
70
|
+
|
71
|
+
def option_parser
|
72
|
+
::OptionParser.new do |parser|
|
73
|
+
parser.on('-h', '--help', 'Show help information') do
|
74
|
+
puts(parser)
|
75
|
+
exit
|
76
|
+
end
|
77
|
+
|
78
|
+
::SUPPORTED_CSVPP_FLAGS.each do |f|
|
79
|
+
parser.on(f.short_flag, f.long_flag, f.description) { |v| f.handler.call(@options, v) }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './google_options'
|
4
|
+
|
5
|
+
module CSVPlusPlus
|
6
|
+
# Individual CLI flags that a user can supply
|
7
|
+
class CliFlag
|
8
|
+
attr_reader :short_flag, :long_flag, :description, :handler
|
9
|
+
|
10
|
+
# initialize
|
11
|
+
def initialize(short_flag, long_flag, description, handler)
|
12
|
+
@short_flag = short_flag
|
13
|
+
@long_flag = long_flag
|
14
|
+
@description = description
|
15
|
+
@handler = handler
|
16
|
+
end
|
17
|
+
|
18
|
+
# to_s
|
19
|
+
def to_s
|
20
|
+
"#{@short_flag}, #{@long_flag} #{@description}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
SUPPORTED_CSVPP_FLAGS = [
|
26
|
+
::CSVPlusPlus::CliFlag.new(
|
27
|
+
'-b',
|
28
|
+
'--backup',
|
29
|
+
'Create a backup of the spreadsheet before applying changes.',
|
30
|
+
->(options, _v) { options.backup = true }
|
31
|
+
),
|
32
|
+
::CSVPlusPlus::CliFlag.new(
|
33
|
+
'-c',
|
34
|
+
'--create',
|
35
|
+
"Create the sheet if it doesn't exist. It will use --sheet-name if specified",
|
36
|
+
->(options, _v) { options.create_if_not_exists = true }
|
37
|
+
),
|
38
|
+
::CSVPlusPlus::CliFlag.new(
|
39
|
+
'-g SHEET_ID',
|
40
|
+
'--google-sheet-id SHEET_ID',
|
41
|
+
'The id of the sheet - you can extract this from the URL: ' \
|
42
|
+
'https://docs.google.com/spreadsheets/d/< ... SHEET_ID ... >/edit#gid=0',
|
43
|
+
->(options, v) { options.google_sheet_id = v }
|
44
|
+
),
|
45
|
+
::CSVPlusPlus::CliFlag.new(
|
46
|
+
'-k',
|
47
|
+
'--key-values KEY_VALUES',
|
48
|
+
'A comma-separated list of key=values which will be made available to the template',
|
49
|
+
lambda do |options, v|
|
50
|
+
options.key_values =
|
51
|
+
begin
|
52
|
+
[v.split('=')].to_h
|
53
|
+
rescue ::StandardError
|
54
|
+
{}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
),
|
58
|
+
::CSVPlusPlus::CliFlag.new(
|
59
|
+
'-n SHEET_NAME',
|
60
|
+
'--sheet-name SHEET_NAME',
|
61
|
+
'The name of the sheet to apply the template to',
|
62
|
+
->(options, v) { options.sheet_name = v }
|
63
|
+
),
|
64
|
+
::CSVPlusPlus::CliFlag.new(
|
65
|
+
'-o OUTPUT_FILE',
|
66
|
+
'--output OUTPUT_FILE',
|
67
|
+
'The file to write to (must be .csv, .ods, .xls)',
|
68
|
+
->(options, v) { options.output_filename = v }
|
69
|
+
),
|
70
|
+
::CSVPlusPlus::CliFlag.new('-v', '--verbose', 'Enable verbose output', ->(options, _v) { options.verbose = true }),
|
71
|
+
::CSVPlusPlus::CliFlag.new(
|
72
|
+
'-x OFFSET',
|
73
|
+
'--offset-columns OFFSET',
|
74
|
+
'Apply the template offset by OFFSET cells',
|
75
|
+
->(options, v) { options.offset[0] = v }
|
76
|
+
),
|
77
|
+
::CSVPlusPlus::CliFlag.new(
|
78
|
+
'-y OFFSET',
|
79
|
+
'--offset-rows OFFSET',
|
80
|
+
'Apply the template offset by OFFSET rows',
|
81
|
+
->(options, v) { options.offset[1] = v }
|
82
|
+
)
|
83
|
+
].freeze
|
data/lib/csv_plus_plus/color.rb
CHANGED
@@ -3,20 +3,54 @@
|
|
3
3
|
module CSVPlusPlus
|
4
4
|
# A color value
|
5
5
|
class Color
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :red_hex, :green_hex, :blue_hex
|
7
7
|
|
8
8
|
# create an instance from a string like "#FFF" or "#FFFFFF"
|
9
9
|
def initialize(hex_string)
|
10
|
-
@
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
10
|
+
@red_hex, @green_hex, @blue_hex = hex_string
|
11
|
+
.gsub(/^#?/, '')
|
12
|
+
.match(/([0-9a-f]{1,2})([0-9a-f]{1,2})([0-9a-f]{1,2})/i)
|
13
|
+
&.captures
|
14
|
+
&.map { |s| s.length == 1 ? s + s : s }
|
15
|
+
end
|
16
|
+
|
17
|
+
# The percent (decimal between 0-1) of red
|
18
|
+
def red_percent
|
19
|
+
hex_to_percent(@red_hex)
|
20
|
+
end
|
21
|
+
|
22
|
+
# The percent (decimal between 0-1) of green
|
23
|
+
def green_percent
|
24
|
+
hex_to_percent(@green_hex)
|
25
|
+
end
|
26
|
+
|
27
|
+
# The percent (decimal between 0-1) of blue
|
28
|
+
def blue_percent
|
29
|
+
hex_to_percent(@blue_hex)
|
30
|
+
end
|
31
|
+
|
32
|
+
# to_hex
|
33
|
+
def to_hex
|
34
|
+
[@red_hex, @green_hex, @blue_hex].join
|
35
|
+
end
|
36
|
+
|
37
|
+
# to_s
|
38
|
+
def to_s
|
39
|
+
"Color(r: #{@red_hex}, g: #{@green_hex}, b: #{@blue_hex})"
|
40
|
+
end
|
41
|
+
|
42
|
+
# ==
|
43
|
+
def ==(other)
|
44
|
+
other.is_a?(self.class) &&
|
45
|
+
other.red_hex == @red_hex &&
|
46
|
+
other.green_hex == @green_hex &&
|
47
|
+
other.blue_hex == @blue_hex
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def hex_to_percent(hex)
|
53
|
+
hex.to_i(16) / 255
|
20
54
|
end
|
21
55
|
end
|
22
56
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CSVPlusPlus
|
4
|
+
# A convenience wrapper around Google's REST API client
|
5
|
+
module GoogleApiClient
|
6
|
+
# Get a +::Google::Apis::SheetsV4::SheetsService+ instance connected to the sheets API
|
7
|
+
def self.sheets_client
|
8
|
+
::Google::Apis::SheetsV4::SheetsService.new.tap do |s|
|
9
|
+
s.authorization = ::Google::Auth.get_application_default(['https://www.googleapis.com/auth/spreadsheets'].freeze)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Get a +::Google::Apis::DriveV3::DriveService+ instance connected to the drive API
|
14
|
+
def self.drive_client
|
15
|
+
::Google::Apis::DriveV3::DriveService.new.tap do |d|
|
16
|
+
d.authorization = ::Google::Auth.get_application_default(['https://www.googleapis.com/auth/drive.file'].freeze)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/csv_plus_plus/graph.rb
CHANGED
@@ -54,11 +54,6 @@ module CSVPlusPlus
|
|
54
54
|
include ::TSort
|
55
55
|
alias tsort_each_node each_key
|
56
56
|
|
57
|
-
# create a +DependencyGraph+ from a +Hash+
|
58
|
-
def self.from_hash(hash)
|
59
|
-
self[hash.map { |k, v| [k, v] }]
|
60
|
-
end
|
61
|
-
|
62
57
|
# sort each child
|
63
58
|
def tsort_each_child(node, &)
|
64
59
|
fetch(node).each(&)
|
@@ -5,24 +5,24 @@ require_relative './entity'
|
|
5
5
|
module CSVPlusPlus
|
6
6
|
module Language
|
7
7
|
module Entities
|
8
|
-
##
|
9
8
|
# A boolean value
|
10
9
|
class Boolean < Entity
|
11
10
|
attr_reader :value
|
12
11
|
|
13
12
|
# initialize
|
13
|
+
# @param value [String, Boolean]
|
14
14
|
def initialize(value)
|
15
15
|
super(:boolean)
|
16
16
|
# TODO: probably can do a lot better in general on type validation
|
17
17
|
@value = value.is_a?(::String) ? (value.downcase == 'true') : value
|
18
18
|
end
|
19
19
|
|
20
|
-
#
|
20
|
+
# @return [String]
|
21
21
|
def to_s
|
22
22
|
@value.to_s.upcase
|
23
23
|
end
|
24
24
|
|
25
|
-
#
|
25
|
+
# @return [Boolean]
|
26
26
|
def ==(other)
|
27
27
|
super && value == other.value
|
28
28
|
end
|
@@ -9,13 +9,14 @@ module CSVPlusPlus
|
|
9
9
|
class Entity
|
10
10
|
attr_reader :id, :type
|
11
11
|
|
12
|
-
#
|
12
|
+
# @param type [String, Symbol]
|
13
|
+
# @param id [String]
|
13
14
|
def initialize(type, id: nil)
|
14
15
|
@type = type.to_sym
|
15
16
|
@id = id.downcase.to_sym if id
|
16
17
|
end
|
17
18
|
|
18
|
-
#
|
19
|
+
# @return [Boolean]
|
19
20
|
def ==(other)
|
20
21
|
self.class == other.class && @type == other.type && @id == other.id
|
21
22
|
end
|
@@ -30,7 +31,8 @@ module CSVPlusPlus
|
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
33
|
-
#
|
34
|
+
# Respond to predicates by type (entity.boolean?, entity.string?, etc)
|
35
|
+
# @return [Boolean]
|
34
36
|
def respond_to_missing?(method_name, *_arguments)
|
35
37
|
(method_name =~ /^(\w+)\?$/ && a_type?(::Regexp.last_match(1))) || super
|
36
38
|
end
|
@@ -42,17 +44,19 @@ module CSVPlusPlus
|
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
45
|
-
# An entity that can take arguments
|
47
|
+
# An entity that can take other entities as arguments
|
46
48
|
class EntityWithArguments < Entity
|
47
49
|
attr_reader :arguments
|
48
50
|
|
49
|
-
#
|
51
|
+
# @param type [String, Symbol]
|
52
|
+
# @param id [String]
|
53
|
+
# @param arguments [Array<Entity>]
|
50
54
|
def initialize(type, id: nil, arguments: [])
|
51
55
|
super(type, id:)
|
52
56
|
@arguments = arguments
|
53
57
|
end
|
54
58
|
|
55
|
-
#
|
59
|
+
# @return [Boolean]
|
56
60
|
def ==(other)
|
57
61
|
super && @arguments == other.arguments
|
58
62
|
end
|
@@ -127,8 +127,6 @@ module CSVPlusPlus
|
|
127
127
|
|
128
128
|
# this will throw a syntax error if it doesn't exist (which is what we want)
|
129
129
|
return ::BUILTIN_FUNCTIONS[id] if ::BUILTIN_FUNCTIONS.key?(id)
|
130
|
-
|
131
|
-
@runtime.raise_syntax_error('Unknown function', fn_id)
|
132
130
|
end
|
133
131
|
|
134
132
|
def apply_arguments(function, function_call)
|
@@ -4,7 +4,7 @@ module CSVPlusPlus
|
|
4
4
|
module Language
|
5
5
|
##
|
6
6
|
# An error that can be thrown for various syntax errors
|
7
|
-
class SyntaxError <
|
7
|
+
class SyntaxError < ::CSVPlusPlus::Error
|
8
8
|
# initialize
|
9
9
|
def initialize(message, bad_input, runtime, wrapped_error: nil)
|
10
10
|
@bad_input = bad_input.to_s
|