ruby-rtf 0.0.1 → 0.0.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.
- checksums.yaml +7 -0
- data/Gemfile.lock +19 -86
- data/Rakefile +2 -2
- data/bin/rtf_parse +26 -0
- data/lib/ruby-rtf/parser.rb +68 -13
- data/lib/ruby-rtf/version.rb +2 -2
- data/ruby-rtf.gemspec +1 -5
- data/spec/parser_spec.rb +137 -27
- metadata +18 -49
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6c49f3df763a3eed0f7db3da2c0f8b3b8c719d82
|
4
|
+
data.tar.gz: 44d7a2e153fd5b5c98ee33ef1e5c4c3bf601f4aa
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b5b942ab6e002d1be0dd70d1041b84f2f34bc8851c62d6f5aa391321ec55d8fcdfd38111f5ddfb43e6804c7afa76410fe45c719ab152646731568337733592e4
|
7
|
+
data.tar.gz: 1339b06aca24cf79cf5156f689e6a24d160e20a49b198c75f8d8da249c143ea5be215e93242eb898cb4a8c4cf61d8131bd65779233f3b0c61f606b9c175f42d1
|
data/Gemfile.lock
CHANGED
@@ -1,101 +1,34 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ruby-rtf (0.0.
|
4
|
+
ruby-rtf (0.0.2)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: http://rubygems.org/
|
8
8
|
specs:
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
diff-lcs (1.1.2)
|
25
|
-
erubis (2.6.6)
|
26
|
-
abstract (>= 1.0.0)
|
27
|
-
fattr (2.2.0)
|
28
|
-
flay (1.4.2)
|
29
|
-
ruby_parser (~> 2.0)
|
30
|
-
sexp_processor (~> 3.0)
|
31
|
-
flog (2.5.1)
|
32
|
-
ruby_parser (~> 2.0)
|
33
|
-
sexp_processor (~> 3.0)
|
34
|
-
haml (3.0.25)
|
35
|
-
hirb (0.3.6)
|
36
|
-
hoe (2.9.1)
|
37
|
-
rake (>= 0.8.7)
|
38
|
-
i18n (0.5.0)
|
39
|
-
infinity_test (1.0.2)
|
40
|
-
notifiers (>= 1.1.0)
|
41
|
-
watchr (>= 0.7)
|
42
|
-
json_pure (1.5.1)
|
43
|
-
main (4.4.0)
|
44
|
-
arrayfields (>= 4.7.4)
|
45
|
-
fattr (>= 2.1.0)
|
46
|
-
metric_fu (2.0.1)
|
47
|
-
Saikuro (>= 1.1.0)
|
48
|
-
activesupport (>= 2.0.0)
|
49
|
-
chronic (~> 0.2.3)
|
50
|
-
churn (>= 0.0.7)
|
51
|
-
flay (>= 1.2.1)
|
52
|
-
flog (>= 2.2.0)
|
53
|
-
rails_best_practices (>= 0.3.16)
|
54
|
-
rcov (>= 0.8.3.3)
|
55
|
-
reek (>= 1.2.6)
|
56
|
-
roodi (>= 2.1.0)
|
57
|
-
notifiers (1.1.0)
|
58
|
-
rails_best_practices (0.7.0)
|
59
|
-
activesupport
|
60
|
-
colored (~> 1.2)
|
61
|
-
erubis (~> 2.6.6)
|
62
|
-
haml (~> 3.0.18)
|
63
|
-
i18n
|
64
|
-
ruby-progressbar (~> 0.0.9)
|
65
|
-
ruby_parser (~> 2.0.4)
|
66
|
-
rake (0.8.7)
|
67
|
-
rcov (0.9.9)
|
68
|
-
reek (1.2.8)
|
69
|
-
ruby2ruby (~> 1.2)
|
70
|
-
ruby_parser (~> 2.0)
|
71
|
-
sexp_processor (~> 3.0)
|
72
|
-
roodi (2.1.0)
|
73
|
-
ruby_parser
|
74
|
-
rspec (2.5.0)
|
75
|
-
rspec-core (~> 2.5.0)
|
76
|
-
rspec-expectations (~> 2.5.0)
|
77
|
-
rspec-mocks (~> 2.5.0)
|
78
|
-
rspec-core (2.5.1)
|
79
|
-
rspec-expectations (2.5.0)
|
80
|
-
diff-lcs (~> 1.1.2)
|
81
|
-
rspec-mocks (2.5.0)
|
82
|
-
ruby-progressbar (0.0.9)
|
83
|
-
ruby2ruby (1.2.5)
|
84
|
-
ruby_parser (~> 2.0)
|
85
|
-
sexp_processor (~> 3.0)
|
86
|
-
ruby_parser (2.0.6)
|
87
|
-
sexp_processor (~> 3.0)
|
88
|
-
sexp_processor (3.0.5)
|
89
|
-
watchr (0.7)
|
90
|
-
yard (0.6.4)
|
9
|
+
diff-lcs (1.3)
|
10
|
+
rspec (3.6.0)
|
11
|
+
rspec-core (~> 3.6.0)
|
12
|
+
rspec-expectations (~> 3.6.0)
|
13
|
+
rspec-mocks (~> 3.6.0)
|
14
|
+
rspec-core (3.6.0)
|
15
|
+
rspec-support (~> 3.6.0)
|
16
|
+
rspec-expectations (3.6.0)
|
17
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
18
|
+
rspec-support (~> 3.6.0)
|
19
|
+
rspec-mocks (3.6.0)
|
20
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
21
|
+
rspec-support (~> 3.6.0)
|
22
|
+
rspec-support (3.6.0)
|
23
|
+
yard (0.9.9)
|
91
24
|
|
92
25
|
PLATFORMS
|
93
26
|
ruby
|
94
27
|
|
95
28
|
DEPENDENCIES
|
96
|
-
bluecloth
|
97
|
-
infinity_test
|
98
|
-
metric_fu
|
99
29
|
rspec (> 2.0)
|
100
30
|
ruby-rtf!
|
101
31
|
yard
|
32
|
+
|
33
|
+
BUNDLED WITH
|
34
|
+
1.14.6
|
data/Rakefile
CHANGED
@@ -4,8 +4,6 @@ Bundler::GemHelper.install_tasks
|
|
4
4
|
require 'yard'
|
5
5
|
require 'rspec/core/rake_task'
|
6
6
|
|
7
|
-
require 'metric_fu'
|
8
|
-
|
9
7
|
task :default => [:spec]
|
10
8
|
|
11
9
|
desc "run spec tests"
|
@@ -13,6 +11,8 @@ RSpec::Core::RakeTask.new('spec') do |t|
|
|
13
11
|
t.pattern = 'spec/**/*_spec.rb'
|
14
12
|
end
|
15
13
|
|
14
|
+
task :test => :spec
|
15
|
+
|
16
16
|
desc 'Generate Documentation'
|
17
17
|
YARD::Rake::YardocTask.new do |t|
|
18
18
|
t.files = ['lib/**/*.rb', '-', 'LICENSE']
|
data/bin/rtf_parse
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'ruby-rtf'
|
5
5
|
require 'pp'
|
6
|
+
require 'base64'
|
6
7
|
|
7
8
|
@prefix = ''
|
8
9
|
@suffix = ''
|
@@ -80,6 +81,28 @@ def format(str, section)
|
|
80
81
|
str << @prefix + section[:text].force_encoding('UTF-8') + @suffix
|
81
82
|
end
|
82
83
|
|
84
|
+
def process_image(section)
|
85
|
+
mods = section[:modifiers]
|
86
|
+
mime = ''
|
87
|
+
case mods[:picture_format]
|
88
|
+
when 'jpeg'
|
89
|
+
mime = 'image/jpg'
|
90
|
+
when 'png'
|
91
|
+
mime = 'image/png'
|
92
|
+
when 'bmp'
|
93
|
+
mime = 'image/bmp'
|
94
|
+
when 'wmf'
|
95
|
+
mime = 'image/x-wmf'
|
96
|
+
end
|
97
|
+
hex = section[:text].scan(/../).map(&:hex).pack('c*')
|
98
|
+
base64 = Base64.strict_encode64(hex)
|
99
|
+
width = 'auto'
|
100
|
+
width = mods[:picture_width] * (mods[:picture_scale_x] || 100) / 100 if mods[:picture_width]
|
101
|
+
height = 'auto'
|
102
|
+
height = mods[:picture_height] * (mods[:picture_scale_y] || 100) / 100 if mods[:picture_height]
|
103
|
+
"<img width='#{width}' height='#{height}' src=\"data:#{mime};base64,#{base64}\"/>\n"
|
104
|
+
end
|
105
|
+
|
83
106
|
doc = RubyRTF::Parser.new.parse(File.open(ARGV[0]).read)
|
84
107
|
|
85
108
|
STDERR.puts doc
|
@@ -103,6 +126,9 @@ doc.sections.each do |section|
|
|
103
126
|
end
|
104
127
|
str << "</table>\n"
|
105
128
|
next
|
129
|
+
elsif mods[:picture]
|
130
|
+
str << process_image(section)
|
131
|
+
next
|
106
132
|
end
|
107
133
|
|
108
134
|
format(str, section)
|
data/lib/ruby-rtf/parser.rb
CHANGED
@@ -3,17 +3,21 @@
|
|
3
3
|
module RubyRTF
|
4
4
|
# Handles the parsing of RTF content into an RubyRTF::Document
|
5
5
|
class Parser
|
6
|
-
attr_accessor :current_section
|
6
|
+
attr_accessor :current_section, :encoding
|
7
7
|
|
8
8
|
# @return [Array] The current formatting block to use as the basis for new sections
|
9
9
|
attr_reader :formatting_stack
|
10
10
|
|
11
11
|
attr_reader :doc
|
12
12
|
|
13
|
-
|
13
|
+
# @param unknown_control_warning_enabled [Boolean] Whether to write unknown control directive warnings to STDERR
|
14
|
+
def initialize(unknown_control_warning_enabled: true)
|
15
|
+
# default_mods needs to be the same has in the formatting stack and in
|
16
|
+
# the current_section modifiers or the first stack ends up getting lost.
|
14
17
|
default_mods = {}
|
15
18
|
@formatting_stack = [default_mods]
|
16
19
|
@current_section = {:text => '', :modifiers => default_mods}
|
20
|
+
@unknown_control_warning_enabled = unknown_control_warning_enabled
|
17
21
|
|
18
22
|
@seen = {}
|
19
23
|
|
@@ -83,6 +87,9 @@ module RubyRTF
|
|
83
87
|
# handle hex special
|
84
88
|
if src[current_pos] == "'"
|
85
89
|
val = src[(current_pos + 1), 2].hex.chr
|
90
|
+
if encoding
|
91
|
+
val = val.force_encoding(encoding).encode('UTF-8')
|
92
|
+
end
|
86
93
|
current_pos += 3
|
87
94
|
return [:hex, val, current_pos]
|
88
95
|
end
|
@@ -119,6 +126,7 @@ module RubyRTF
|
|
119
126
|
case(name)
|
120
127
|
when :rtf then ;
|
121
128
|
when :deff then @doc.default_font = val
|
129
|
+
when :ansicpg then self.encoding = "windows-#{val}"
|
122
130
|
when *[:ansi, :mac, :pc, :pca] then @doc.character_set = name
|
123
131
|
when :fonttbl then current_pos = parse_font_table(src, current_pos)
|
124
132
|
when :colortbl then current_pos = parse_colour_table(src, current_pos)
|
@@ -130,9 +138,33 @@ module RubyRTF
|
|
130
138
|
|
131
139
|
# RTF font sizes are in half-points. divide by 2 to get points
|
132
140
|
when :fs then add_section!(:font_size => (val.to_f / 2.0))
|
133
|
-
when :b then
|
134
|
-
|
135
|
-
|
141
|
+
when :b then
|
142
|
+
if val
|
143
|
+
@formatting_stack.pop
|
144
|
+
add_section!
|
145
|
+
else
|
146
|
+
add_section!(:bold => true)
|
147
|
+
end
|
148
|
+
|
149
|
+
when :i then
|
150
|
+
if val
|
151
|
+
@formatting_stack.pop
|
152
|
+
add_section!
|
153
|
+
else
|
154
|
+
add_section!(:italic => true)
|
155
|
+
end
|
156
|
+
|
157
|
+
when :ul then
|
158
|
+
if val
|
159
|
+
@formatting_stack.pop
|
160
|
+
add_section!
|
161
|
+
else
|
162
|
+
add_section!(:underline => true)
|
163
|
+
end
|
164
|
+
when :ulnone then
|
165
|
+
current_section[:modifiers][:underline] = false
|
166
|
+
@formatting_stack.pop
|
167
|
+
|
136
168
|
when :super then add_section!(:superscript => true)
|
137
169
|
when :sub then add_section!(:subscript => true)
|
138
170
|
when :strike then add_section!(:strikethrough => true)
|
@@ -153,15 +185,23 @@ module RubyRTF
|
|
153
185
|
when :cf then add_section!(:foreground_colour => @doc.colour_table[val])
|
154
186
|
when :cb then add_section!(:background_colour => @doc.colour_table[val])
|
155
187
|
when :hex then current_section[:text] << val
|
188
|
+
when :uc then @skip_byte = val.to_i
|
156
189
|
when :u then
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
190
|
+
if @skip_byte && @skip_byte == 0
|
191
|
+
val = val % 100
|
192
|
+
@skip_byte = nil
|
193
|
+
end
|
194
|
+
if val == 32 || val == 8232
|
195
|
+
add_modifier_section({:newline => true}, "\n")
|
161
196
|
else
|
162
|
-
|
197
|
+
val += 65_536 if val < 0
|
198
|
+
char = if val < 10_000
|
199
|
+
[val.to_s.hex].pack('U*')
|
200
|
+
else
|
201
|
+
[val].pack('U*')
|
202
|
+
end
|
203
|
+
current_section[:text] << char
|
163
204
|
end
|
164
|
-
current_section[:text] << eval("\"#{char}\"")
|
165
205
|
|
166
206
|
when *[:rquote, :lquote] then add_modifier_section({name => true}, "'")
|
167
207
|
when *[:rdblquote, :ldblquote] then add_modifier_section({name => true}, '"')
|
@@ -241,11 +281,22 @@ module RubyRTF
|
|
241
281
|
|
242
282
|
@context_stack.pop
|
243
283
|
end
|
284
|
+
when :pict then add_section!(picture: true)
|
285
|
+
when :jpegblip then add_section!(picture_format:'jpeg')
|
286
|
+
when :pngblip then add_section!(picture_format:'png')
|
287
|
+
when *[:dibitmap, :wbitmap] then add_section!(picture_format:'bmp')
|
288
|
+
when *[:wmetafile, :pmmetafile] then add_section!(picture_format:'wmf')
|
289
|
+
when :pich then add_section!(picture_height: RubyRTF.twips_to_points(val))
|
290
|
+
when :picw then add_section!(picture_width: RubyRTF.twips_to_points(val))
|
291
|
+
when :picscalex then add_section!(picture_scale_x: val.to_i)
|
292
|
+
when :picscaley then add_section!(picture_scale_y: val.to_i)
|
244
293
|
|
245
294
|
else
|
246
295
|
unless @seen[name]
|
247
296
|
@seen[name] = true
|
248
|
-
|
297
|
+
if @unknown_control_warning_enabled
|
298
|
+
warn "Unknown control #{name.inspect} with #{val} at #{current_pos}"
|
299
|
+
end
|
249
300
|
end
|
250
301
|
end
|
251
302
|
current_pos
|
@@ -276,6 +327,7 @@ module RubyRTF
|
|
276
327
|
group -= 1
|
277
328
|
|
278
329
|
if group <= 1
|
330
|
+
break if font.nil?
|
279
331
|
font.cleanup_names
|
280
332
|
@doc.font_table[font.number] = font
|
281
333
|
end
|
@@ -461,7 +513,8 @@ module RubyRTF
|
|
461
513
|
def force_section!(mods = {}, text = nil)
|
462
514
|
current_context << @current_section
|
463
515
|
|
464
|
-
formatting_stack.last
|
516
|
+
fs = formatting_stack.last || {}
|
517
|
+
fs.each_pair do |k, v|
|
465
518
|
next if BLACKLISTED.include?(k)
|
466
519
|
mods[k] = v
|
467
520
|
end
|
@@ -474,7 +527,9 @@ module RubyRTF
|
|
474
527
|
#
|
475
528
|
# @return [Nil]
|
476
529
|
def reset_current_section!
|
530
|
+
paragraph = current_section[:modifiers].has_key?(:paragraph)
|
477
531
|
current_section[:modifiers].clear
|
532
|
+
current_section[:modifiers][:paragraph] = true if paragraph
|
478
533
|
end
|
479
534
|
|
480
535
|
def current_context
|
data/lib/ruby-rtf/version.rb
CHANGED
data/ruby-rtf.gemspec
CHANGED
@@ -13,12 +13,8 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.summary = 'Library for working with RTF files'
|
14
14
|
s.description = s.summary
|
15
15
|
|
16
|
-
s.add_development_dependency 'infinity_test'
|
17
16
|
s.add_development_dependency 'rspec', '>2.0'
|
18
|
-
s.add_development_dependency 'metric_fu'
|
19
|
-
|
20
17
|
s.add_development_dependency 'yard'
|
21
|
-
s.add_development_dependency 'bluecloth'
|
22
18
|
|
23
19
|
s.bindir = 'bin'
|
24
20
|
s.executables << 'rtf_parse'
|
@@ -27,4 +23,4 @@ Gem::Specification.new do |s|
|
|
27
23
|
s.test_files = `git ls-files -- spec/*`.split("\n")
|
28
24
|
|
29
25
|
s.require_paths = ['lib']
|
30
|
-
end
|
26
|
+
end
|
data/spec/parser_spec.rb
CHANGED
@@ -6,6 +6,26 @@ describe RubyRTF::Parser do
|
|
6
6
|
let(:parser) { RubyRTF::Parser.new }
|
7
7
|
let(:doc) { parser.doc }
|
8
8
|
|
9
|
+
context 'with input containing invalid control directives' do
|
10
|
+
let(:parser) { RubyRTF::Parser.new(unknown_control_warning_enabled: unknown_control_warning_enabled) }
|
11
|
+
let(:doc) { '{\rtf1\ansi\xxxxx0}' }
|
12
|
+
|
13
|
+
context 'with unknown_control_warning_enabled = false' do
|
14
|
+
let(:unknown_control_warning_enabled) { false }
|
15
|
+
|
16
|
+
it 'does not write anything to stderr' do
|
17
|
+
expect { parser.parse(doc) }.not_to output.to_stderr
|
18
|
+
end
|
19
|
+
end
|
20
|
+
context 'with unknown_control_warning_enabled = true' do
|
21
|
+
let(:unknown_control_warning_enabled) { true }
|
22
|
+
|
23
|
+
it 'writes message to stderr' do
|
24
|
+
expect { parser.parse(doc) }.to output("Unknown control :xxxxx with 0 at 18\n").to_stderr
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
9
29
|
it 'parses hello world' do
|
10
30
|
src = '{\rtf1\ansi\deff0 {\fonttbl {\f0 Times New Roman;}}\f0 \fs60 Hello, World!}'
|
11
31
|
lambda { parser.parse(src) }.should_not raise_error
|
@@ -14,7 +34,7 @@ describe RubyRTF::Parser do
|
|
14
34
|
it 'returns a RTF::Document' do
|
15
35
|
src = '{\rtf1\ansi\deff0 {\fonttbl {\f0 Times New Roman;}}\f0 \fs60 Hello, World!}'
|
16
36
|
d = parser.parse(src)
|
17
|
-
d.is_a?(RubyRTF::Document).should
|
37
|
+
d.is_a?(RubyRTF::Document).should == true
|
18
38
|
end
|
19
39
|
|
20
40
|
it 'parses a default font (\deffN)' do
|
@@ -76,23 +96,82 @@ describe RubyRTF::Parser do
|
|
76
96
|
|
77
97
|
section = parser.parse(src).sections
|
78
98
|
section[0][:modifiers][:font_size].should == 30
|
79
|
-
section[0][:modifiers][:bold].should
|
80
|
-
section[0][:modifiers].has_key?(:italic).should
|
81
|
-
section[0][:modifiers].has_key?(:underline).should
|
99
|
+
section[0][:modifiers][:bold].should == true
|
100
|
+
section[0][:modifiers].has_key?(:italic).should == false
|
101
|
+
section[0][:modifiers].has_key?(:underline).should == false
|
82
102
|
section[0][:text].should == 'Hello '
|
83
103
|
|
84
104
|
section[1][:modifiers][:font_size].should == 15
|
85
|
-
section[1][:modifiers][:italic].should
|
86
|
-
section[1][:modifiers][:bold].should
|
87
|
-
section[1][:modifiers].has_key?(:underline).should
|
105
|
+
section[1][:modifiers][:italic].should == true
|
106
|
+
section[1][:modifiers][:bold].should == true
|
107
|
+
section[1][:modifiers].has_key?(:underline).should == false
|
88
108
|
section[1][:text].should == 'World'
|
89
109
|
|
90
110
|
section[2][:modifiers][:font_size].should == 30
|
91
|
-
section[2][:modifiers][:bold].should
|
92
|
-
section[2][:modifiers][:underline].should
|
93
|
-
section[2][:modifiers].has_key?(:italic).should
|
111
|
+
section[2][:modifiers][:bold].should == true
|
112
|
+
section[2][:modifiers][:underline].should == true
|
113
|
+
section[2][:modifiers].has_key?(:italic).should == false
|
94
114
|
section[2][:text].should == 'Goodbye, cruel world.'
|
95
115
|
end
|
116
|
+
|
117
|
+
context 'parses pictures' do
|
118
|
+
let(:src_bitmap) do
|
119
|
+
src = '{\rtf1 {\pict\wbitmap\picw7064\pich5292\picwgoal4005\pichgoal3000\picscalex111\picscaley109
|
120
|
+
ffd8ffe000104a4649460001010100b400b40000ffe1158a687474703a2f2f6e732e61646f62652e636f6d2f7861702f3}}'
|
121
|
+
end
|
122
|
+
let(:src_jpeg) do
|
123
|
+
src = '{\rtf1 {\pict\jpegblip\picw7064\pich5292\picwgoal4005\pichgoal3000\picscalex111\picscaley109
|
124
|
+
ffd8ffe000104a4649460001010100b400b40000ffe1158a687474703a2f2f6e732e61646f62652e636f6d2f7861702f3}}'
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should parse jpeg' do
|
128
|
+
section = parser.parse(src_jpeg).sections
|
129
|
+
section[0][:modifiers][:picture].should == true
|
130
|
+
section[0][:modifiers][:picture_format].should == 'jpeg'
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should parse bmp' do
|
134
|
+
section = parser.parse(src_bitmap).sections
|
135
|
+
section[0][:modifiers][:picture].should == true
|
136
|
+
section[0][:modifiers][:picture_format].should == 'bmp'
|
137
|
+
section = parser.parse(src_bitmap).sections
|
138
|
+
section[0][:modifiers][:picture].should == true
|
139
|
+
section[0][:modifiers][:picture_format].should == 'bmp'
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should parse width' do
|
143
|
+
section = parser.parse(src_bitmap).sections
|
144
|
+
section[0][:modifiers][:picture_width].should == 7064 / 20.0
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should parse height' do
|
148
|
+
section = parser.parse(src_bitmap).sections
|
149
|
+
section[0][:modifiers][:picture_height].should == 5292 / 20.0
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should parse scale' do
|
153
|
+
section = parser.parse(src_bitmap).sections
|
154
|
+
section[0][:modifiers][:picture_scale_x].should == 111
|
155
|
+
section[0][:modifiers][:picture_scale_y].should == 109
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'should parse picture data' do
|
159
|
+
section = parser.parse(src_bitmap).sections
|
160
|
+
section[0][:text].should == 'ffd8ffe000104a4649460001010100b400b40000ffe1158a687474703a2f2f6e732e61646f62652e636f6d2f7861702f3'
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'clears ul with ul0' do
|
165
|
+
src = '{\rtf1 \ul\b Hello\b0\ul0 World}'
|
166
|
+
section = parser.parse(src).sections
|
167
|
+
section[0][:modifiers][:bold].should == true
|
168
|
+
section[0][:modifiers][:underline].should == true
|
169
|
+
section[0][:text].should == 'Hello'
|
170
|
+
|
171
|
+
section[1][:modifiers].has_key?(:bold).should == false
|
172
|
+
section[1][:modifiers].has_key?(:underline).should == false
|
173
|
+
section[1][:text].should == 'World'
|
174
|
+
end
|
96
175
|
end
|
97
176
|
|
98
177
|
context '#parse_control' do
|
@@ -129,6 +208,13 @@ describe RubyRTF::Parser do
|
|
129
208
|
current_pos.should == 3
|
130
209
|
end
|
131
210
|
|
211
|
+
context "encoding is windows-1252" do
|
212
|
+
it 'parses a hex control' do
|
213
|
+
parser.encoding = 'windows-1252'
|
214
|
+
parser.parse_control("'93")[0, 2].should == [:hex, '“']
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
132
218
|
[' ', '{', '}', '\\', "\r", "\n"].each do |stop|
|
133
219
|
it "stops at a #{stop}" do
|
134
220
|
parser.parse_control("rtf#{stop}test")[0, 2].should == [:rtf, nil]
|
@@ -168,6 +254,13 @@ describe RubyRTF::Parser do
|
|
168
254
|
font.name.should == 'Times'
|
169
255
|
end
|
170
256
|
|
257
|
+
it 'parses an empty font table' do
|
258
|
+
src = "{\\rtf1\\ansi\\ansicpg1252\\cocoartf1187\n{\\fonttbl}\n{\\colortbl;\\red255\\green255\\blue255;}\n}"
|
259
|
+
doc = parser.parse(src)
|
260
|
+
|
261
|
+
doc.font_table.should == []
|
262
|
+
end
|
263
|
+
|
171
264
|
context '#parse_font_table' do
|
172
265
|
it 'parses a font table' do
|
173
266
|
src = '{\f0\froman Times New Roman;}{\f1\fnil Arial;}}}'
|
@@ -303,7 +396,7 @@ describe RubyRTF::Parser do
|
|
303
396
|
doc = parser.parse(src)
|
304
397
|
|
305
398
|
clr = doc.colour_table[0]
|
306
|
-
clr.use_default?.should
|
399
|
+
clr.use_default?.should == true
|
307
400
|
|
308
401
|
clr = doc.colour_table[1]
|
309
402
|
clr.red.should == 255
|
@@ -383,17 +476,17 @@ describe RubyRTF::Parser do
|
|
383
476
|
|
384
477
|
it 'sets bold' do
|
385
478
|
parser.handle_control(:b, nil, nil, 0)
|
386
|
-
parser.current_section[:modifiers][:bold].should
|
479
|
+
parser.current_section[:modifiers][:bold].should == true
|
387
480
|
end
|
388
481
|
|
389
482
|
it 'sets underline' do
|
390
483
|
parser.handle_control(:ul, nil, nil, 0)
|
391
|
-
parser.current_section[:modifiers][:underline].should
|
484
|
+
parser.current_section[:modifiers][:underline].should == true
|
392
485
|
end
|
393
486
|
|
394
487
|
it 'sets italic' do
|
395
488
|
parser.handle_control(:i, nil, nil, 0)
|
396
|
-
parser.current_section[:modifiers][:italic].should
|
489
|
+
parser.current_section[:modifiers][:italic].should == true
|
397
490
|
end
|
398
491
|
|
399
492
|
%w(rquote lquote).each do |quote|
|
@@ -401,7 +494,7 @@ describe RubyRTF::Parser do
|
|
401
494
|
parser.current_section[:text] = 'My code'
|
402
495
|
parser.handle_control(quote.to_sym, nil, nil, 0)
|
403
496
|
doc.sections.last[:text].should == "'"
|
404
|
-
doc.sections.last[:modifiers][quote.to_sym].should
|
497
|
+
doc.sections.last[:modifiers][quote.to_sym].should == true
|
405
498
|
end
|
406
499
|
end
|
407
500
|
|
@@ -410,7 +503,7 @@ describe RubyRTF::Parser do
|
|
410
503
|
parser.current_section[:text] = 'My code'
|
411
504
|
parser.handle_control(quote.to_sym, nil, nil, 0)
|
412
505
|
doc.sections.last[:text].should == '"'
|
413
|
-
doc.sections.last[:modifiers][quote.to_sym].should
|
506
|
+
doc.sections.last[:modifiers][quote.to_sym].should == true
|
414
507
|
end
|
415
508
|
end
|
416
509
|
|
@@ -445,12 +538,29 @@ describe RubyRTF::Parser do
|
|
445
538
|
parser.current_section[:text].should == 'My code道'
|
446
539
|
end
|
447
540
|
|
541
|
+
context "uc0 skips a byte in the next unicode char" do
|
542
|
+
it "u8278" do
|
543
|
+
parser.current_section[:text] = 'My code '
|
544
|
+
parser.handle_control(:uc, 0, nil, 0)
|
545
|
+
parser.handle_control(:u, 8278, nil, 0)
|
546
|
+
parser.current_section[:text].should == 'My code x'
|
547
|
+
end
|
548
|
+
|
549
|
+
it "u8232 - does newline" do
|
550
|
+
parser.current_section[:text] = "end."
|
551
|
+
parser.handle_control(:uc, 0, nil, 0)
|
552
|
+
parser.handle_control(:u, 8232, nil, 0)
|
553
|
+
doc.sections.last[:modifiers][:newline].should == true
|
554
|
+
doc.sections.last[:text].should == "\n"
|
555
|
+
end
|
556
|
+
end
|
557
|
+
|
448
558
|
context 'new line' do
|
449
559
|
['line', "\n"].each do |type|
|
450
560
|
it "sets from #{type}" do
|
451
561
|
parser.current_section[:text] = "end."
|
452
562
|
parser.handle_control(type.to_sym, nil, nil, 0)
|
453
|
-
doc.sections.last[:modifiers][:newline].should
|
563
|
+
doc.sections.last[:modifiers][:newline].should == true
|
454
564
|
doc.sections.last[:text].should == "\n"
|
455
565
|
end
|
456
566
|
end
|
@@ -465,7 +575,7 @@ describe RubyRTF::Parser do
|
|
465
575
|
it 'inserts a \tab' do
|
466
576
|
parser.current_section[:text] = "end."
|
467
577
|
parser.handle_control(:tab, nil, nil, 0)
|
468
|
-
doc.sections.last[:modifiers][:tab].should
|
578
|
+
doc.sections.last[:modifiers][:tab].should == true
|
469
579
|
doc.sections.last[:text].should == "\t"
|
470
580
|
end
|
471
581
|
|
@@ -473,7 +583,7 @@ describe RubyRTF::Parser do
|
|
473
583
|
parser.current_section[:text] = "end."
|
474
584
|
parser.handle_control(:super, nil, nil, 0)
|
475
585
|
|
476
|
-
parser.current_section[:modifiers][:superscript].should
|
586
|
+
parser.current_section[:modifiers][:superscript].should == true
|
477
587
|
parser.current_section[:text].should == ""
|
478
588
|
end
|
479
589
|
|
@@ -481,7 +591,7 @@ describe RubyRTF::Parser do
|
|
481
591
|
parser.current_section[:text] = "end."
|
482
592
|
parser.handle_control(:sub, nil, nil, 0)
|
483
593
|
|
484
|
-
parser.current_section[:modifiers][:subscript].should
|
594
|
+
parser.current_section[:modifiers][:subscript].should == true
|
485
595
|
parser.current_section[:text].should == ""
|
486
596
|
end
|
487
597
|
|
@@ -489,7 +599,7 @@ describe RubyRTF::Parser do
|
|
489
599
|
parser.current_section[:text] = "end."
|
490
600
|
parser.handle_control(:strike, nil, nil, 0)
|
491
601
|
|
492
|
-
parser.current_section[:modifiers][:strikethrough].should
|
602
|
+
parser.current_section[:modifiers][:strikethrough].should == true
|
493
603
|
parser.current_section[:text].should == ""
|
494
604
|
end
|
495
605
|
|
@@ -497,21 +607,21 @@ describe RubyRTF::Parser do
|
|
497
607
|
parser.current_section[:text] = "end."
|
498
608
|
parser.handle_control(:scaps, nil, nil, 0)
|
499
609
|
|
500
|
-
parser.current_section[:modifiers][:smallcaps].should
|
610
|
+
parser.current_section[:modifiers][:smallcaps].should == true
|
501
611
|
parser.current_section[:text].should == ""
|
502
612
|
end
|
503
613
|
|
504
614
|
it 'inserts an \emdash' do
|
505
615
|
parser.current_section[:text] = "end."
|
506
616
|
parser.handle_control(:emdash, nil, nil, 0)
|
507
|
-
doc.sections.last[:modifiers][:emdash].should
|
617
|
+
doc.sections.last[:modifiers][:emdash].should == true
|
508
618
|
doc.sections.last[:text].should == "--"
|
509
619
|
end
|
510
620
|
|
511
621
|
it 'inserts an \endash' do
|
512
622
|
parser.current_section[:text] = "end."
|
513
623
|
parser.handle_control(:endash, nil, nil, 0)
|
514
|
-
doc.sections.last[:modifiers][:endash].should
|
624
|
+
doc.sections.last[:modifiers][:endash].should == true
|
515
625
|
doc.sections.last[:text].should == "-"
|
516
626
|
end
|
517
627
|
|
@@ -537,8 +647,8 @@ describe RubyRTF::Parser do
|
|
537
647
|
parser.current_section[:modifiers][:italic] = true
|
538
648
|
parser.handle_control(type.to_sym, nil, nil, 0)
|
539
649
|
|
540
|
-
parser.current_section[:modifiers].has_key?(:bold).should
|
541
|
-
parser.current_section[:modifiers].has_key?(:italic).should
|
650
|
+
parser.current_section[:modifiers].has_key?(:bold).should == false
|
651
|
+
parser.current_section[:modifiers].has_key?(:italic).should == false
|
542
652
|
end
|
543
653
|
end
|
544
654
|
|
@@ -633,7 +743,7 @@ describe RubyRTF::Parser do
|
|
633
743
|
it 'handles :~' do
|
634
744
|
parser.current_section[:text] = "end."
|
635
745
|
parser.handle_control(:~, nil, nil, 0)
|
636
|
-
doc.sections.last[:modifiers][:nbsp].should
|
746
|
+
doc.sections.last[:modifiers][:nbsp].should == true
|
637
747
|
doc.sections.last[:text].should == " "
|
638
748
|
end
|
639
749
|
end
|
metadata
CHANGED
@@ -1,72 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-rtf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.3
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- dan sinclair
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
default_executable:
|
11
|
+
date: 2017-05-12 00:00:00.000000000 Z
|
14
12
|
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
16
|
-
name: infinity_test
|
17
|
-
requirement: &2153303300 !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
|
-
requirements:
|
20
|
-
- - ! '>='
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '0'
|
23
|
-
type: :development
|
24
|
-
prerelease: false
|
25
|
-
version_requirements: *2153303300
|
26
13
|
- !ruby/object:Gem::Dependency
|
27
14
|
name: rspec
|
28
|
-
requirement:
|
29
|
-
none: false
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
|
-
- -
|
17
|
+
- - ">"
|
32
18
|
- !ruby/object:Gem::Version
|
33
19
|
version: '2.0'
|
34
20
|
type: :development
|
35
21
|
prerelease: false
|
36
|
-
version_requirements:
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: metric_fu
|
39
|
-
requirement: &2153302140 !ruby/object:Gem::Requirement
|
40
|
-
none: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
23
|
requirements:
|
42
|
-
- -
|
24
|
+
- - ">"
|
43
25
|
- !ruby/object:Gem::Version
|
44
|
-
version: '0'
|
45
|
-
type: :development
|
46
|
-
prerelease: false
|
47
|
-
version_requirements: *2153302140
|
26
|
+
version: '2.0'
|
48
27
|
- !ruby/object:Gem::Dependency
|
49
28
|
name: yard
|
50
|
-
requirement:
|
51
|
-
none: false
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
52
30
|
requirements:
|
53
|
-
- -
|
31
|
+
- - ">="
|
54
32
|
- !ruby/object:Gem::Version
|
55
33
|
version: '0'
|
56
34
|
type: :development
|
57
35
|
prerelease: false
|
58
|
-
version_requirements:
|
59
|
-
- !ruby/object:Gem::Dependency
|
60
|
-
name: bluecloth
|
61
|
-
requirement: &2153293280 !ruby/object:Gem::Requirement
|
62
|
-
none: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
63
37
|
requirements:
|
64
|
-
- -
|
38
|
+
- - ">="
|
65
39
|
- !ruby/object:Gem::Version
|
66
40
|
version: '0'
|
67
|
-
type: :development
|
68
|
-
prerelease: false
|
69
|
-
version_requirements: *2153293280
|
70
41
|
description: Library for working with RTF files
|
71
42
|
email: dj2@everburning.com
|
72
43
|
executables:
|
@@ -74,8 +45,8 @@ executables:
|
|
74
45
|
extensions: []
|
75
46
|
extra_rdoc_files: []
|
76
47
|
files:
|
77
|
-
- .gitignore
|
78
|
-
- .infinity_test
|
48
|
+
- ".gitignore"
|
49
|
+
- ".infinity_test"
|
79
50
|
- Gemfile
|
80
51
|
- Gemfile.lock
|
81
52
|
- LICENSE
|
@@ -97,30 +68,28 @@ files:
|
|
97
68
|
- spec/font_spec.rb
|
98
69
|
- spec/parser_spec.rb
|
99
70
|
- spec/spec_helper.rb
|
100
|
-
has_rdoc: true
|
101
71
|
homepage: http://github.com/dj2/ruby-rtf
|
102
72
|
licenses: []
|
73
|
+
metadata: {}
|
103
74
|
post_install_message:
|
104
75
|
rdoc_options: []
|
105
76
|
require_paths:
|
106
77
|
- lib
|
107
78
|
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
-
none: false
|
109
79
|
requirements:
|
110
|
-
- -
|
80
|
+
- - ">="
|
111
81
|
- !ruby/object:Gem::Version
|
112
82
|
version: '0'
|
113
83
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
-
none: false
|
115
84
|
requirements:
|
116
|
-
- -
|
85
|
+
- - ">="
|
117
86
|
- !ruby/object:Gem::Version
|
118
87
|
version: '0'
|
119
88
|
requirements: []
|
120
89
|
rubyforge_project:
|
121
|
-
rubygems_version:
|
90
|
+
rubygems_version: 2.5.1
|
122
91
|
signing_key:
|
123
|
-
specification_version:
|
92
|
+
specification_version: 4
|
124
93
|
summary: Library for working with RTF files
|
125
94
|
test_files:
|
126
95
|
- spec/colour_spec.rb
|