ruby-rtf 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ .rvmrc
2
+ .bundle/
3
+ .yardoc/
4
+
5
+ doc/
6
+ tmp/
7
+ data/
8
+ pkg/
9
+
10
+ *.html
data/.infinity_test ADDED
@@ -0,0 +1,24 @@
1
+ infinity_test do
2
+ notifications :growl do
3
+ show_images :mode => :hands
4
+ end
5
+
6
+ use :test_framework => :rspec
7
+
8
+ before_run { clear :terminal }
9
+
10
+ heuristics do
11
+ add('^spec/(.*)_spec.rb') do |file|
12
+ run :test_for => file
13
+ end
14
+ add('^spec/spec_helper.rb') do |file|
15
+ run :all => :tests
16
+ end
17
+ add('^lib/ruby-rtf.rb') do |file|
18
+ run :all => :tests
19
+ end
20
+ add('^lib/(.*)\.rb') do |file|
21
+ run :test_for => file[1].split('/').last
22
+ end
23
+ end
24
+ end
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,101 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ruby-rtf (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ Saikuro (1.1.0)
10
+ abstract (1.0.0)
11
+ activesupport (3.0.4)
12
+ arrayfields (4.7.4)
13
+ bluecloth (2.0.11)
14
+ chronic (0.2.3)
15
+ hoe (>= 1.2.1)
16
+ churn (0.0.13)
17
+ chronic (>= 0.2.3)
18
+ hirb
19
+ json_pure
20
+ main
21
+ ruby_parser (~> 2.0.4)
22
+ sexp_processor (~> 3.0.3)
23
+ colored (1.2)
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)
91
+
92
+ PLATFORMS
93
+ ruby
94
+
95
+ DEPENDENCIES
96
+ bluecloth
97
+ infinity_test
98
+ metric_fu
99
+ rspec (> 2.0)
100
+ ruby-rtf!
101
+ yard
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2011 dan sinclair
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to
5
+ deal in the Software without restriction, including without limitation the
6
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,12 @@
1
+ RubyRTF
2
+ =======
3
+
4
+ The Ruby RTF library is an attempt to parse RTF files. There is a lot still missing
5
+ but the basics are there including the beginnings of table support.
6
+
7
+ You can see an example of using the library in the bin/rtf_parse script which attempts
8
+ to convert an RTF file to an HTML file.
9
+
10
+ Issues
11
+ ======
12
+ Please report any issues to the GitHub Issue tracker (https://github.com/dj2/ruby-rtf).
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'yard'
5
+ require 'rspec/core/rake_task'
6
+
7
+ require 'metric_fu'
8
+
9
+ task :default => [:spec]
10
+
11
+ desc "run spec tests"
12
+ RSpec::Core::RakeTask.new('spec') do |t|
13
+ t.pattern = 'spec/**/*_spec.rb'
14
+ end
15
+
16
+ desc 'Generate Documentation'
17
+ YARD::Rake::YardocTask.new do |t|
18
+ t.files = ['lib/**/*.rb', '-', 'LICENSE']
19
+ t.options = ['--main', 'README', '--no-private', '--hide-void-return']
20
+ end
data/bin/rtf_parse ADDED
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'ruby-rtf'
5
+ require 'pp'
6
+
7
+ @prefix = ''
8
+ @suffix = ''
9
+
10
+ def add(open, close = open)
11
+ @prefix << "<#{open}>"
12
+ @suffix = "</#{close}>#{@suffix}"
13
+ end
14
+
15
+ def format(str, section)
16
+ @prefix = ''
17
+ @suffix = ''
18
+
19
+ mods = section[:modifiers]
20
+
21
+ if mods[:paragraph]
22
+ if section[:text].empty?
23
+ str << "<p></p>\n"
24
+ else
25
+ add('p')
26
+ end
27
+
28
+ elsif mods[:tab]
29
+ str << "&nbsp;&nbsp;&nbsp;&nbsp;"
30
+ return
31
+ elsif mods[:newline]
32
+ str << "<br />\n"
33
+ return
34
+ elsif mods[:rquote]
35
+ str << "&rsquo;"
36
+ return
37
+ elsif mods[:lquote]
38
+ str << "&lsquo;"
39
+ return
40
+ elsif mods[:ldblquote]
41
+ str << "&ldquo;"
42
+ return
43
+ elsif mods[:rdblquote]
44
+ str << "&rdquo;"
45
+ return
46
+ elsif mods[:emdash]
47
+ str << "&mdash;"
48
+ return
49
+ elsif mods[:endash]
50
+ str << "&ndash;"
51
+ return
52
+ elsif mods[:nbsp]
53
+ str << "&nbsp;"
54
+ return
55
+ end
56
+ return if section[:text].empty?
57
+
58
+ add('b') if mods[:bold]
59
+ add('i') if mods[:italic]
60
+ add('u') if mods[:underline]
61
+ add('sup') if mods[:superscript]
62
+ add('sub') if mods[:subscript]
63
+ add('del') if mods[:strikethrough]
64
+
65
+ style = ''
66
+ style << "font-variant: small-caps;" if mods[:smallcaps]
67
+ style << "font-size: #{mods[:font_size]}pt;" if mods[:font_size]
68
+ style << "font-family: \"#{mods[:font].name}\";" if mods[:font]
69
+ if mods[:foreground_colour] && !mods[:foreground_colour].use_default?
70
+ colour = mods[:foreground_colour]
71
+ style << "color: rgb(#{colour.red},#{colour.green},#{colour.blue});"
72
+ end
73
+ if mods[:background_colour] && !mods[:background_colour].use_default?
74
+ colour = mods[:background_colour]
75
+ style << "background-color: rgb(#{colour.red},#{colour.green},#{colour.blue});"
76
+ end
77
+
78
+ add("span style='#{style}'", 'span') unless style.empty?
79
+
80
+ str << @prefix + section[:text].force_encoding('UTF-8') + @suffix
81
+ end
82
+
83
+ doc = RubyRTF::Parser.new.parse(File.open(ARGV[0]).read)
84
+
85
+ STDERR.puts doc
86
+
87
+ str = '<html><body>'
88
+ doc.sections.each do |section|
89
+ mods = section[:modifiers]
90
+
91
+ if mods[:table]
92
+ str << "<table width=\"100%\">\n"
93
+ mods[:table].rows.each do |row|
94
+ str << "<tr>\n"
95
+ row.cells.each do |cell|
96
+ str << "<td width=\"#{cell.width}%\">\n"
97
+ cell.sections.each do |sect|
98
+ format(str, sect)
99
+ end
100
+ str << "</td>\n"
101
+ end
102
+ str << "</tr>\n"
103
+ end
104
+ str << "</table>\n"
105
+ next
106
+ end
107
+
108
+ format(str, section)
109
+ end
110
+
111
+ str << "</body></html>"
112
+ puts str
data/lib/ruby-rtf.rb ADDED
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ require 'ruby-rtf/version'
4
+ require 'ruby-rtf/invalid_document'
5
+
6
+ require 'ruby-rtf/ruby-rtf'
7
+ require 'ruby-rtf/font'
8
+ require 'ruby-rtf/colour'
9
+ require 'ruby-rtf/table'
10
+ require 'ruby-rtf/document'
11
+ require 'ruby-rtf/parser'
@@ -0,0 +1,50 @@
1
+ module RubyRTF
2
+ # Holds information about a colour
3
+ class Colour
4
+ # @return [Integer] The red value
5
+ attr_accessor :red
6
+
7
+ # @return [Integer] The green value
8
+ attr_accessor :green
9
+
10
+ # @return [Integer] The blue value
11
+ attr_accessor :blue
12
+
13
+ # @return [Integer] The shade value
14
+ attr_accessor :shade
15
+
16
+ # @return [Integer] The tint value
17
+ attr_accessor :tint
18
+
19
+ # @return [Symbol] The theme information
20
+ attr_accessor :theme
21
+
22
+ # @return [Boolean] True if reader should use it's default colour
23
+ attr_accessor :use_default
24
+ alias :use_default? :use_default
25
+
26
+ # Create a new colour
27
+ #
28
+ # @param red [Integer] Red value between 0 and 255 (default: 0)
29
+ # @param green [Integer] Green value between 0 and 255 (default: 0)
30
+ # @param blue [Integer] Blue value between 0 and 255 (default: 0)
31
+ # @return [RubyRTF::Colour] New colour object
32
+ def initialize(red = 0, green = 0, blue = 0)
33
+ @red = red
34
+ @green = green
35
+ @blue = blue
36
+ @use_default = false
37
+ end
38
+
39
+ # Convert the colour to a string
40
+ #
41
+ # @return [String] The string representation of the colour
42
+ def to_s
43
+ return "default" if use_default?
44
+ "[#{red}, #{green}, #{blue}]"
45
+ end
46
+ end
47
+
48
+ # Alias the Colour class as Color
49
+ Color = Colour
50
+ end
@@ -0,0 +1,36 @@
1
+ module RubyRTF
2
+ # Represents the entire RTF document
3
+ class Document
4
+ # @return [Array] The font table
5
+ attr_reader :font_table
6
+
7
+ # @return [Array] The colour table
8
+ attr_reader :colour_table
9
+ alias :color_table :colour_table
10
+
11
+ # @return [Integer] The default font number for the document
12
+ attr_accessor :default_font
13
+
14
+ # @return [String] The characgter set for the document (:ansi, :pc, :pca, :mac)
15
+ attr_accessor :character_set
16
+
17
+ # @return [Array] The different formatted sections of the document
18
+ attr_reader :sections
19
+
20
+ # Creates a new document
21
+ #
22
+ # @return [RubyRTF::Document] The new document
23
+ def initialize
24
+ @font_table = []
25
+ @colour_table = []
26
+ @character_set = :ansi
27
+ @default_font = 0
28
+
29
+ @sections = []
30
+ end
31
+
32
+ def <<(obj)
33
+ @sections << obj
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,83 @@
1
+ module RubyRTF
2
+ # Holds the information for a given font
3
+ class Font
4
+ # @return [Integer] The font numberb
5
+ attr_accessor :number
6
+
7
+ # @return [String] The font name
8
+ attr_accessor :name
9
+
10
+ # @return [String] The alternate name for this font
11
+ attr_accessor :alternate_name
12
+
13
+ # @return [String] The panose number for the font
14
+ attr_accessor :panose
15
+
16
+ # @return [Symbol] The theme for this font
17
+ attr_accessor :theme
18
+
19
+ # @return [Symbol] The pitch information for this font
20
+ attr_accessor :pitch
21
+
22
+ # @return [Integer] The character set number for the font
23
+ attr_accessor :character_set
24
+
25
+ # @return [String] The non-tagged name for the font
26
+ attr_accessor :non_tagged_name
27
+
28
+ # @return [Symbol] The font family command
29
+ attr_accessor :family_command
30
+
31
+ # The font families
32
+ FAMILIES = [:nil, :roman, :swiss, :modern, :script, :decor, :tech, :bldl]
33
+
34
+ # The font pitch values
35
+ PITCHES = [:default, :fixed, :variable]
36
+
37
+ # Creates a new font
38
+ #
39
+ # @param name [String] The font name to set (default: '')
40
+ # @return [RubyRTF::Font] The new font
41
+ def initialize(name = '')
42
+ @family_command = :nil
43
+ @name = name
44
+ @alternate_name = ''
45
+ @non_tagged_name = ''
46
+ @panose = ''
47
+ end
48
+
49
+ # Set the pitch value for the font
50
+ #
51
+ # @param val [Integer] The pitch value to set (0, 1, or 2)
52
+ # @return [Nil]
53
+ def pitch=(val)
54
+ @pitch = PITCHES[val]
55
+ end
56
+
57
+ # Cleans up the various font names
58
+ #
59
+ # @return [Nil]
60
+ def cleanup_names
61
+ @name = cleanup_name(@name)
62
+ @alternate_name = cleanup_name(@alternate_name)
63
+ @non_tagged_name = cleanup_name(@non_tagged_name)
64
+ end
65
+
66
+ # Convert to string format
67
+ #
68
+ # @return [String] The string representation
69
+ def to_s
70
+ "#{number}: #{name}"
71
+ end
72
+
73
+ private
74
+
75
+ # Cleanups up a given font name
76
+ #
77
+ # @param str [String] The font name to cleanup
78
+ # @return [String] The cleaned font name
79
+ def cleanup_name(str)
80
+ str.gsub(/;$/, '')
81
+ end
82
+ end
83
+ end