lxl 0.4.2 → 0.4.3
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/CHANGES +4 -0
- data/VERSION +1 -1
- data/lib/lxl.rb +11 -5
- data/test/lxl_spreadsheet_test.rb +2 -0
- data/test/lxl_test.rb +4 -4
- data/test/lxl_win32ole_test.rb +68 -0
- metadata +10 -9
data/CHANGES
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.3
|
data/lib/lxl.rb
CHANGED
@@ -241,8 +241,9 @@ class LXL::Parser
|
|
241
241
|
|
242
242
|
# Initialize namespace and lexer.
|
243
243
|
#
|
244
|
-
def initialize(
|
245
|
-
@namespace = namespace
|
244
|
+
def initialize(options=Hash.new)
|
245
|
+
@namespace = options[:namespace] if options.key?(:namespace)
|
246
|
+
@namespace ||= self.class.namespace_class.new
|
246
247
|
ops = EXCEL_OPERATORS.collect { |v| Regexp.quote(v) }.join('|')
|
247
248
|
xlr = LXL::Range::EXCEL_RANGE
|
248
249
|
@lexer = self.class.lexer_class.new([
|
@@ -306,6 +307,8 @@ class LXL::Parser
|
|
306
307
|
formulas = [[]]
|
307
308
|
separators = [?=, ?;]
|
308
309
|
ops = Hash[*EXCEL_OPERATORS.zip(RUBY_OPERATORS).flatten]
|
310
|
+
ns_const_missing = begin [@namespace.const_get(:ConstMissing),true].last rescue false end
|
311
|
+
ns_method_missing = @namespace.respond_to?(:method_missing)
|
309
312
|
|
310
313
|
# Translate formula prefixes to `= to avoid clashing with the = operator
|
311
314
|
# For lines that start with = (optional leading whitespace)
|
@@ -357,15 +360,14 @@ class LXL::Parser
|
|
357
360
|
upper = token.to_s.upcase
|
358
361
|
lower = token.to_s.downcase
|
359
362
|
raise NoMethodError, "protected method `#{token}` called for #{self}" if @namespace.const_get(:METHODS).include?(lower)
|
360
|
-
custom_const_missing = begin [@namespace.const_get(:ConstMissing),true].last rescue false end
|
361
363
|
# Constants
|
362
364
|
if tokens.first != '('
|
363
|
-
if @namespace.const_defined?(upper) or
|
365
|
+
if @namespace.const_defined?(upper) or ns_const_missing
|
364
366
|
formulas.last << store(?C, "@namespace.const_get(:#{upper})")
|
365
367
|
else formulas.last << t end
|
366
368
|
# Functions
|
367
369
|
else
|
368
|
-
if @namespace.respond_to?(lower) or
|
370
|
+
if @namespace.respond_to?(lower) or ns_method_missing
|
369
371
|
formulas.last << store(?F, "@namespace.#{lower}")
|
370
372
|
else formulas.last << t end
|
371
373
|
end
|
@@ -475,6 +477,10 @@ class LXL::Range < Range
|
|
475
477
|
end
|
476
478
|
end
|
477
479
|
|
480
|
+
def to_s
|
481
|
+
"#{first}:#{last}"
|
482
|
+
end
|
483
|
+
|
478
484
|
end
|
479
485
|
|
480
486
|
# Snapshots the symbol/arguments of a function call for later use.
|
@@ -58,10 +58,12 @@ end
|
|
58
58
|
#++
|
59
59
|
|
60
60
|
class SpreadsheetTest < Test::Unit::TestCase
|
61
|
+
|
61
62
|
def test_range
|
62
63
|
assert_equal(5, MyLXL.eval('=A2'))
|
63
64
|
assert_equal($sheet1[1,2].value, MyLXL.eval('=Sheet1!A2'))
|
64
65
|
assert_equal(8, MyLXL.eval('=Sheet2!C4'))
|
65
66
|
assert_equal($sheet2[3,4].value, MyLXL.eval('=Sheet2!C4'))
|
66
67
|
end
|
68
|
+
|
67
69
|
end
|
data/test/lxl_test.rb
CHANGED
@@ -43,13 +43,13 @@ class LXLTest < Test::Unit::TestCase
|
|
43
43
|
expected += [true, false, :A, :B, false, 6, true, true, [1, 'two', 3.0], true, false, true, 'yes', 'this and that']
|
44
44
|
expected += [8, 0.502, true, true, 'embedded percentages 25% and semi-colons ; are working properly']
|
45
45
|
MyNamespace.register_symbols(:A, :B)
|
46
|
-
lxl = LXL::Parser.new(MyNamespace.new)
|
46
|
+
lxl = LXL::Parser.new(:namespace=>MyNamespace.new)
|
47
47
|
results = lxl.eval(formulas)
|
48
48
|
expected.each_index { |i| assert_equal(expected[i], results[i]) }
|
49
49
|
end
|
50
50
|
|
51
51
|
def test_range
|
52
|
-
lxl = LXL::Parser.new(MyNamespace.new)
|
52
|
+
lxl = LXL::Parser.new(:namespace=>MyNamespace.new)
|
53
53
|
res = lxl.eval('=LIST(d5:b3, "x")')
|
54
54
|
range = res.first
|
55
55
|
assert_equal(LXL::Range, range.class)
|
@@ -70,7 +70,7 @@ class LXLTest < Test::Unit::TestCase
|
|
70
70
|
|
71
71
|
def test_deferred
|
72
72
|
MyNamespace.register_deferred(:TESTING)
|
73
|
-
lxl = LXL::Parser.new(MyNamespace.new)
|
73
|
+
lxl = LXL::Parser.new(:namespace=>MyNamespace.new)
|
74
74
|
res = lxl.eval('=TESTING(1,2,3)')
|
75
75
|
assert_equal(LXL::Deferred, res.class)
|
76
76
|
assert_equal(:testing, res.symbol)
|
@@ -78,7 +78,7 @@ class LXLTest < Test::Unit::TestCase
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def test_range_naming
|
81
|
-
lxl = LXL::Parser.new(MyNamespace.new)
|
81
|
+
lxl = LXL::Parser.new(:namespace=>MyNamespace.new)
|
82
82
|
range = lxl.eval('=B1:D2')
|
83
83
|
assert_equal('B', range.first_column)
|
84
84
|
range = lxl.eval('=Sheet1!B3:D5')
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#--
|
2
|
+
# =LXL Win32OLE Interface
|
3
|
+
#
|
4
|
+
# An LXL interface to an Excel xls file via Win32OLE.
|
5
|
+
#
|
6
|
+
#++
|
7
|
+
|
8
|
+
$LOAD_PATH.unshift('../lib')
|
9
|
+
require 'test/unit'
|
10
|
+
require 'lxl'
|
11
|
+
require 'win32ole'
|
12
|
+
|
13
|
+
#--
|
14
|
+
# Excel workbook
|
15
|
+
#++
|
16
|
+
|
17
|
+
$xl = WIN32OLE.new('Excel.Application')
|
18
|
+
$xl.Visible = false
|
19
|
+
$xl.DisplayAlerts = false
|
20
|
+
$xl.ScreenUpdating = false
|
21
|
+
$xl.Interactive = false
|
22
|
+
$xl.AskToUpdateLinks = false
|
23
|
+
|
24
|
+
workbook = $xl.Workbooks.Add
|
25
|
+
w1 = $xl.Worksheets(1)
|
26
|
+
w2 = $xl.Worksheets(2)
|
27
|
+
w1.Range("A2").Value = 5
|
28
|
+
w2.Range("C4").Value = 8
|
29
|
+
|
30
|
+
#workbook.SaveAs(Dir.getwd+'/workbook.xls')
|
31
|
+
|
32
|
+
#--
|
33
|
+
# LXL Interface
|
34
|
+
#++
|
35
|
+
|
36
|
+
class XLRange < LXL::Range
|
37
|
+
|
38
|
+
def self.new(first, last)
|
39
|
+
range = super
|
40
|
+
sheet = range.sheet || 'Sheet1'
|
41
|
+
$xl.Range("#{sheet}!#{range}").Value
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
class MyLXL < LXL::Parser
|
47
|
+
def self.range_class() XLRange end
|
48
|
+
end
|
49
|
+
|
50
|
+
#--
|
51
|
+
# Test
|
52
|
+
#++
|
53
|
+
|
54
|
+
class XLTest < Test::Unit::TestCase
|
55
|
+
|
56
|
+
def test_range
|
57
|
+
assert_equal(5, MyLXL.eval('=A2'))
|
58
|
+
assert_equal($xl.Range('A2').Value, MyLXL.eval('=Sheet1!A2'))
|
59
|
+
assert_equal(8, MyLXL.eval('=Sheet2!C4'))
|
60
|
+
assert_equal($xl.Range('Sheet2!C4').Value, MyLXL.eval('=Sheet2!C4'))
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_z # finalizer
|
64
|
+
$xl.ActiveWorkbook.Close(0)
|
65
|
+
$xl.Quit
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.
|
2
|
+
rubygems_version: 0.8.6
|
3
3
|
specification_version: 1
|
4
4
|
name: lxl
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.4.
|
7
|
-
date: 2005-
|
6
|
+
version: 0.4.3
|
7
|
+
date: 2005-03-07
|
8
8
|
summary: LXL (Like Excel) is a mini-language that mimics Microsoft Excel formulas. Easily extended with new constants and functions.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -27,17 +27,18 @@ platform: ruby
|
|
27
27
|
authors:
|
28
28
|
- Kevin Howe
|
29
29
|
files:
|
30
|
-
- lib
|
31
|
-
- VERSION
|
32
30
|
- test
|
33
|
-
-
|
31
|
+
- lib
|
34
32
|
- lxl.gemspec
|
35
33
|
- setup.rb
|
34
|
+
- VERSION
|
35
|
+
- CHANGES
|
36
36
|
- README.en
|
37
|
-
- lib/lxl.rb
|
38
|
-
- test/spreadsheet.rb
|
39
|
-
- test/lxl_spreadsheet_test.rb
|
40
37
|
- test/lxl_test.rb
|
38
|
+
- test/lxl_spreadsheet_test.rb
|
39
|
+
- test/spreadsheet.rb
|
40
|
+
- test/lxl_win32ole_test.rb
|
41
|
+
- lib/lxl.rb
|
41
42
|
test_files:
|
42
43
|
- test/lxl_test.rb
|
43
44
|
rdoc_options:
|