spox-ultraviolet 0.10.4 → 0.10.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.
Files changed (4) hide show
  1. data/lib/uv.rb +77 -73
  2. data/lib/uv/render_processor.rb +128 -119
  3. data/lib/uv/utility.rb +61 -61
  4. metadata +30 -15
data/lib/uv.rb CHANGED
@@ -5,86 +5,90 @@ require 'uv/render_processor.rb'
5
5
 
6
6
 
7
7
  module Uv
8
+ class << self
9
+ attr_accessor :render_path, :theme_path, :syntax_path, :default_style, :syntaxes
10
+ end
8
11
 
9
- def Uv.path
10
- result = []
11
- result << File.join(File.dirname(__FILE__), ".." )
12
- end
13
-
14
- def Uv.copy_files output, output_dir
15
- Uv.path.each do |dir|
16
- dir_name = File.join( dir, "render", output, "files" )
17
- FileUtils.cp_r( Dir.glob(File.join( dir_name, "." )), output_dir ) if File.exists?( dir_name )
18
- end
19
- end
12
+ self.syntax_path = File.join(File.dirname(__FILE__), '..', 'syntax')
13
+ self.render_path = File.join(File.dirname(__FILE__), '..', 'render')
14
+ self.theme_path = File.join(render_path, 'xhtml', 'files', 'css')
15
+ self.default_style = 'mac_classic'
16
+ self.syntaxes = {}
17
+
18
+ def Uv.path
19
+ result = []
20
+ result << File.join(File.dirname(__FILE__), ".." )
21
+ end
20
22
 
21
- def Uv.init_syntaxes
22
- @syntaxes = {}
23
- Dir.glob( File.join(File.dirname(__FILE__), '..', 'syntax', '*.syntax') ).each do |f|
24
- @syntaxes[File.basename(f, '.syntax')] = Textpow::SyntaxNode.load( f )
23
+ def self.syntax_node_for(syntax)
24
+ if !@syntaxes.key?(syntax)
25
+ filename = File.join(@syntax_path, "#{syntax}.syntax")
26
+ @syntaxes[syntax] = if File.exist?(filename)
27
+ Textpow::SyntaxNode.load(filename)
28
+ else
29
+ false
25
30
  end
26
- end
31
+ end
32
+ if !@syntaxes[syntax]
33
+ raise ArgumentError, "No #{syntax}.syntax file in #{@syntax_path}"
34
+ end
35
+ @syntaxes[syntax]
36
+ end
27
37
 
28
- def Uv.syntaxes
29
- Dir.glob( File.join(File.dirname(__FILE__), '..', 'syntax', '*.syntax') ).collect do |f|
30
- File.basename(f, '.syntax')
31
- end
32
- end
33
-
34
- def Uv.themes
35
- Dir.glob( File.join(File.dirname(__FILE__), '..', 'render', 'xhtml', 'files', 'css', '*.css') ).collect do |f|
36
- File.basename(f, '.css')
37
- end
38
- end
38
+ def Uv.copy_files output, output_dir
39
+ Uv.path.each do |dir|
40
+ dir_name = File.join( dir, "render", output, "files" )
41
+ FileUtils.cp_r( Dir.glob(File.join( dir_name, "." )), output_dir ) if File.exists?( dir_name )
42
+ end
43
+ end
39
44
 
40
- def Uv.syntax_for_file file_name
41
- init_syntaxes unless @syntaxes
42
- first_line = ""
43
- File.open( file_name, 'r' ) { |f|
44
- while (first_line = f.readline).strip.size == 0; end
45
- }
46
- result = []
47
- @syntaxes.each do |key, value|
48
- assigned = false
49
- if value.fileTypes
50
- value.fileTypes.each do |t|
51
- if t == File.basename( file_name ) || t == File.extname( file_name )[1..-1]
52
- result << [key, value]
53
- assigned = true
54
- break
55
- end
56
- end
57
- end
58
- unless assigned
59
- if value.firstLineMatch && value.firstLineMatch =~ first_line
60
- result << [key, value]
61
- end
62
- end
63
- end
64
- result
65
- end
66
-
67
- def Uv.parse text, output = "xhtml", syntax_name = nil, line_numbers = false, render_style = "classic", headers = false
68
- init_syntaxes unless @syntaxes
69
- renderer = File.join( File.dirname(__FILE__), '..',"render", output,"#{render_style}.render")
70
- raise( ArgumentError, "Output for #{output} is not yet implemented" ) unless File.exists?(renderer)
71
- css_class = render_style
72
- render_options = YAML.load( File.open( renderer ) )
73
- render_processor = RenderProcessor.new( render_options, line_numbers, headers )
74
- @syntaxes[syntax_name].parse( text, render_processor )
75
- render_processor.string
76
- end
45
+ def Uv.syntaxes
46
+ Dir.glob( File.join(@syntax_path, '*.syntax') ).collect do |f|
47
+ File.basename(f, '.syntax')
48
+ end
49
+ end
77
50
 
78
- def Uv.debug text, syntax_name
79
- unless @syntaxes
80
- @syntaxes = {}
81
- Dir.glob( File.join(File.dirname(__FILE__), '..', 'syntax', '*.syntax') ).each do |f|
82
- @syntaxes[File.basename(f, '.syntax')] = Textpow::SyntaxNode.load( f )
83
- end
51
+ def Uv.themes
52
+ Dir.glob( File.join(@theme_path, '*.css') ).collect do |f|
53
+ File.basename(f, '.css')
54
+ end
55
+ end
56
+
57
+ def Uv.syntax_for_file file_name
58
+ init_syntaxes unless @syntaxes
59
+ first_line = ""
60
+ File.open( file_name, 'r' ) { |f|
61
+ while (first_line = f.readline).strip.size == 0; end
62
+ }
63
+ result = []
64
+ @syntaxes.each do |key, value|
65
+ assigned = false
66
+ if value.fileTypes
67
+ value.fileTypes.each do |t|
68
+ if t == File.basename( file_name ) || t == File.extname( file_name )[1..-1]
69
+ result << [key, value]
70
+ assigned = true
71
+ break
72
+ end
73
+ end
74
+ end
75
+ unless assigned
76
+ if value.firstLineMatch && value.firstLineMatch =~ first_line
77
+ result << [key, value]
78
+ end
84
79
  end
85
- processor = Textpow::DebugProcessor.new
80
+ end
81
+ result
82
+ end
83
+
84
+ def Uv.parse text, output = "xhtml", syntax_name = nil, line_numbers = false, render_style = nil, headers = false
85
+ RenderProcessor.load(output, render_style, line_numbers, headers) do |processor|
86
+ syntax_node_for(syntax_name).parse(text, processor)
87
+ end.string
88
+ end
86
89
 
87
- @syntaxes[syntax_name].parse( text, processor )
88
- end
90
+ def Uv.debug text, syntax_name
91
+ syntax_node_for(syntax_name).parse(text, Textpow::DebugProcessor.new)
92
+ end
89
93
 
90
94
  end
@@ -1,131 +1,140 @@
1
1
  require 'cgi'
2
2
 
3
- module Uv
4
-
3
+ module Uv
5
4
 
6
- class RenderProcessor
7
- @@score_manager = Textpow::ScoreManager.new
8
-
9
- attr_reader :string
10
- attr_accessor :escapeHTML
11
-
12
- def initialize render_options, line_numbers = false, headers = true, score_manager = nil
13
- @score_manager = score_manager || @@score_manager
14
- @render_options = render_options
15
- @options = {}
16
- @headers = headers
17
- @line_numbers = line_numbers
18
- @escapeHTML = true
19
- end
20
-
21
- def start_parsing name
22
- @stack = [name]
23
- @string = ""
24
- @line = nil
25
- @line_number = 0
26
- print @render_options["document"]["begin"] if @headers
27
- print @render_options["listing"]["begin"]
28
- # opt = options @stack
29
- # print opt["begin"] if opt
30
- end
31
-
32
- def print string
33
- @string << string
34
- end
35
-
36
- def escape string
37
- if @render_options["filter"]
38
- @escaped = string
39
- @escaped = self.instance_eval( @render_options["filter"] )
40
- @escaped
41
- else
42
- string
43
- end
44
- end
45
-
46
- def open_tag name, position
47
- @stack << name
48
- print escape(@line[@position...position].gsub(/\n|\r/, '')) if position > @position
49
- @position = position
50
- opt = options @stack
51
- print opt["begin"] if opt
5
+ class RenderProcessor
6
+ @@score_manager = Textpow::ScoreManager.new
7
+
8
+ attr_reader :string
9
+ attr_accessor :escapeHTML
10
+
11
+ def self.load(output, style = nil, line_numbers = false, headers = false)
12
+ style ||= Uv.default_style
13
+ renderer = File.join( Uv.render_path, output,"#{style}.render")
14
+ raise( ArgumentError, "Output for #{output} in #{style} style is not yet implemented" ) unless File.exists?(renderer)
15
+ options = YAML.load_file(renderer)
16
+ processor = RenderProcessor.new(options, line_numbers, headers)
17
+ yield processor if block_given?
18
+ processor
19
+ end
20
+
21
+ def initialize render_options, line_numbers = false, headers = true, score_manager = nil
22
+ @score_manager = score_manager || @@score_manager
23
+ @render_options = render_options
24
+ @options = {}
25
+ @headers = headers
26
+ @line_numbers = line_numbers
27
+ @escapeHTML = true
28
+ end
29
+
30
+ def start_parsing name
31
+ @stack = [name]
32
+ @string = ""
33
+ @line = nil
34
+ @line_number = 0
35
+ print @render_options["document"]["begin"] if @headers
36
+ print @render_options["listing"]["begin"]
37
+ # opt = options @stack
38
+ # print opt["begin"] if opt
39
+ end
40
+
41
+ def print string
42
+ @string << string
43
+ end
44
+
45
+ def escape string
46
+ if @render_options["filter"]
47
+ @escaped = string
48
+ @escaped = self.instance_eval( @render_options["filter"] )
49
+ @escaped
50
+ else
51
+ string
52
52
  end
53
-
54
- def close_tag name, position
55
- print escape(@line[@position...position].gsub(/\n|\r/, '')) if position > @position
56
- @position = position
57
- opt = options @stack
58
- print opt["end"] if opt
59
- @stack.pop
53
+ end
54
+
55
+ def open_tag name, position
56
+ @stack << name
57
+ print escape(@line[@position...position].gsub(/\n|\r/, '')) if position > @position
58
+ @position = position
59
+ opt = options @stack
60
+ print opt["begin"] if opt
61
+ end
62
+
63
+ def close_tag name, position
64
+ print escape(@line[@position...position].gsub(/\n|\r/, '')) if position > @position
65
+ @position = position
66
+ opt = options @stack
67
+ print opt["end"] if opt
68
+ @stack.pop
69
+ end
70
+
71
+ def close_line
72
+ stack = @stack[0..-1]
73
+ while stack.size > 1
74
+ opt = options stack
75
+ print opt["end"] if opt
76
+ stack.pop
60
77
  end
61
-
62
- def close_line
63
- stack = @stack[0..-1]
64
- while stack.size > 1
65
- opt = options stack
66
- print opt["end"] if opt
67
- stack.pop
68
- end
78
+ end
79
+
80
+ def open_line
81
+ stack = [@stack.first]
82
+ clone = @stack[1..-1]
83
+ while stack.size < @stack.size
84
+ stack << clone.shift
85
+ opt = options stack
86
+ print opt["begin"] if opt
69
87
  end
70
-
71
- def open_line
72
- stack = [@stack.first]
73
- clone = @stack[1..-1]
74
- while stack.size < @stack.size
75
- stack << clone.shift
76
- opt = options stack
77
- print opt["begin"] if opt
78
- end
88
+ end
89
+
90
+ def new_line line
91
+ if @line
92
+ print escape(@line[@position..-1].gsub(/\n|\r/, ''))
93
+ close_line
94
+ print @render_options["line"]["end"]
95
+ print "\n"
79
96
  end
80
-
81
- def new_line line
82
- if @line
83
- print escape(@line[@position..-1].gsub(/\n|\r/, ''))
84
- close_line
85
- print @render_options["line"]["end"]
86
- print "\n"
87
- end
88
- @position = 0
89
- @line_number += 1
90
- @line = line
91
- print @render_options["line"]["begin"]
92
- if @line_numbers
93
- print @render_options["line-numbers"]["begin"]
94
- print @line_number.to_s.rjust(4).ljust(5)
95
- print @render_options["line-numbers"]["end"]
96
- print " "
97
- end
98
- open_line
97
+ @position = 0
98
+ @line_number += 1
99
+ @line = line
100
+ print @render_options["line"]["begin"]
101
+ if @line_numbers
102
+ print @render_options["line-numbers"]["begin"]
103
+ print @line_number.to_s.rjust(4).ljust(5)
104
+ print @render_options["line-numbers"]["end"]
105
+ print " "
99
106
  end
100
-
101
- def end_parsing name
102
- if @line
103
- print escape(@line[@position..-1].gsub(/\n|\r/, ''))
104
- while @stack.size > 1
105
- opt = options @stack
106
- print opt["end"] if opt
107
- @stack.pop
108
- end
109
- print @render_options["line"]["end"]
110
- print "\n"
111
- end
112
- # opt = options @stack
113
- # print opt["end"] if opt
114
- @stack.pop
115
- print @render_options["listing"]["end"]
116
- print @render_options["document"]["end"] if @headers
107
+ open_line
108
+ end
109
+
110
+ def end_parsing name
111
+ if @line
112
+ print escape(@line[@position..-1].gsub(/\n|\r/, ''))
113
+ while @stack.size > 1
114
+ opt = options @stack
115
+ print opt["end"] if opt
116
+ @stack.pop
117
+ end
118
+ print @render_options["line"]["end"]
119
+ print "\n"
117
120
  end
118
-
119
- def options stack
120
- ref = stack.join ' '
121
- return @options[ref] if @options.has_key? ref
122
-
123
- result = @render_options['tags'].max do |a, b|
124
- @score_manager.score( a['selector'], ref ) <=> @score_manager.score( b['selector'], ref )
125
- end
126
- result = nil if @score_manager.score( result['selector'], ref ) == 0
127
- @options[ref] = result
121
+ # opt = options @stack
122
+ # print opt["end"] if opt
123
+ @stack.pop
124
+ print @render_options["listing"]["end"]
125
+ print @render_options["document"]["end"] if @headers
126
+ end
127
+
128
+ def options stack
129
+ ref = stack.join ' '
130
+ return @options[ref] if @options.has_key? ref
131
+
132
+ result = @render_options['tags'].max do |a, b|
133
+ @score_manager.score( a['selector'], ref ) <=> @score_manager.score( b['selector'], ref )
128
134
  end
129
- end
135
+ result = nil if @score_manager.score( result['selector'], ref ) == 0
136
+ @options[ref] = result
137
+ end
138
+ end
130
139
  end
131
140
 
@@ -1,67 +1,67 @@
1
1
  module Uv
2
- def Uv.foreground bg
3
- fg = "#FFFFFF"
4
- 3.times do |i|
5
- fg = "#000000" if bg[i*2+1, 2].hex > 0xFF / 2
6
- end
7
- fg
8
- end
9
-
10
- def Uv.alpha_blend bg, fg
11
- unless bg =~ /^#((\d|[ABCDEF]){3}|(\d|[ABCDEF]){6}|(\d|[ABCDEF]){8})$/i
12
- raise(ArgumentError, "Malformed background color '#{bg}'" )
13
- end
14
- unless fg =~ /^#((\d|[ABCDEF]){3}|(\d|[ABCDEF]){6}|(\d|[ABCDEF]){8})$/i
15
- raise(ArgumentError, "Malformed foreground color '#{fg}'" )
16
- end
17
-
18
- if bg.size == 4
19
- tbg = (fg[1,1].hex * 0xff / 0xf).to_s(16).upcase.rjust(2, '0')
20
- tbg += (fg[2,1].hex * 0xff / 0xf).to_s(16).upcase.rjust(2, '0')
21
- tbg += (fg[3,1].hex * 0xff / 0xf).to_s(16).upcase.rjust(2, '0')
22
- bg = "##{tbg}"
23
- end
24
-
25
- result = ""
26
- if fg.size == 4
27
- result += (fg[1,1].hex * 0xff / 0xf).to_s(16).upcase.rjust(2, '0')
28
- result += (fg[2,1].hex * 0xff / 0xf).to_s(16).upcase.rjust(2, '0')
29
- result += (fg[3,1].hex * 0xff / 0xf).to_s(16).upcase.rjust(2, '0')
30
- elsif fg.size == 9
31
- if bg.size == 7
32
- div0 = bg[1..-1].hex
33
- div1, alpha = fg[1..-1].hex.divmod( 0x100 )
34
- 3.times {
35
- div0, mod0 = div0.divmod( 0x100 )
36
- div1, mod1 = div1.divmod( 0x100 )
37
- result = ((mod0 * alpha + mod1 * ( 0x100 - alpha ) ) / 0x100).to_s(16).upcase.rjust(2, '0') + result
38
- }
39
- else
40
- div_a, alpha_a = bg[1..-1].hex.divmod( 0x100 )
41
- div_b, alpha_b = fg[1..-1].hex.divmod( 0x100 )
42
- alpha = alpha_a + alpha_b * (0x100 - alpha_a)
43
- 3.times {
44
- div_b, c_b = div_b.divmod( 0x100 )
45
- div_a, c_a = div_a.divmod( 0x100 )
46
- result = ((c_a * alpha_a + ( 0x100 - alpha_a ) * alpha_b * c_b ) / alpha).to_s(16).upcase.rjust(2, '0') + result
47
- }
48
- end
49
- #result = "FF00FF"
2
+ def Uv.foreground bg
3
+ fg = "#FFFFFF"
4
+ 3.times do |i|
5
+ fg = "#000000" if bg[i*2+1, 2].hex > 0xFF / 2
6
+ end
7
+ fg
8
+ end
9
+
10
+ def Uv.alpha_blend bg, fg
11
+ unless bg =~ /^#((\d|[ABCDEF]){3}|(\d|[ABCDEF]){6}|(\d|[ABCDEF]){8})$/i
12
+ raise(ArgumentError, "Malformed background color '#{bg}'" )
13
+ end
14
+ unless fg =~ /^#((\d|[ABCDEF]){3}|(\d|[ABCDEF]){6}|(\d|[ABCDEF]){8})$/i
15
+ raise(ArgumentError, "Malformed foreground color '#{fg}'" )
16
+ end
17
+
18
+ if bg.size == 4
19
+ tbg = (fg[1,1].hex * 0xff / 0xf).to_s(16).upcase.rjust(2, '0')
20
+ tbg += (fg[2,1].hex * 0xff / 0xf).to_s(16).upcase.rjust(2, '0')
21
+ tbg += (fg[3,1].hex * 0xff / 0xf).to_s(16).upcase.rjust(2, '0')
22
+ bg = "##{tbg}"
23
+ end
24
+
25
+ result = ""
26
+ if fg.size == 4
27
+ result += (fg[1,1].hex * 0xff / 0xf).to_s(16).upcase.rjust(2, '0')
28
+ result += (fg[2,1].hex * 0xff / 0xf).to_s(16).upcase.rjust(2, '0')
29
+ result += (fg[3,1].hex * 0xff / 0xf).to_s(16).upcase.rjust(2, '0')
30
+ elsif fg.size == 9
31
+ if bg.size == 7
32
+ div0 = bg[1..-1].hex
33
+ div1, alpha = fg[1..-1].hex.divmod( 0x100 )
34
+ 3.times {
35
+ div0, mod0 = div0.divmod( 0x100 )
36
+ div1, mod1 = div1.divmod( 0x100 )
37
+ result = ((mod0 * alpha + mod1 * ( 0x100 - alpha ) ) / 0x100).to_s(16).upcase.rjust(2, '0') + result
38
+ }
50
39
  else
51
- result = fg[1..-1]
40
+ div_a, alpha_a = bg[1..-1].hex.divmod( 0x100 )
41
+ div_b, alpha_b = fg[1..-1].hex.divmod( 0x100 )
42
+ alpha = alpha_a + alpha_b * (0x100 - alpha_a)
43
+ 3.times {
44
+ div_b, c_b = div_b.divmod( 0x100 )
45
+ div_a, c_a = div_a.divmod( 0x100 )
46
+ result = ((c_a * alpha_a + ( 0x100 - alpha_a ) * alpha_b * c_b ) / alpha).to_s(16).upcase.rjust(2, '0') + result
47
+ }
52
48
  end
53
- "##{result}"
54
- end
55
-
56
- def Uv.normalize_color settings, color, fg = false
57
- if color
58
- if fg
59
- alpha_blend( settings["foreground"] ? settings["foreground"] : "#000000FF", color )
60
- else
61
- alpha_blend( settings["background"] ? settings["background"] : "#000000FF", color )
62
- end
49
+ #result = "FF00FF"
50
+ else
51
+ result = fg[1..-1]
52
+ end
53
+ "##{result}"
54
+ end
55
+
56
+ def Uv.normalize_color settings, color, fg = false
57
+ if color
58
+ if fg
59
+ alpha_blend( settings["foreground"] ? settings["foreground"] : "#000000FF", color )
63
60
  else
64
- color
61
+ alpha_blend( settings["background"] ? settings["background"] : "#000000FF", color )
65
62
  end
66
- end
63
+ else
64
+ color
65
+ end
66
+ end
67
67
  end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spox-ultraviolet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.4
4
+ hash: 61
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 10
9
+ - 5
10
+ version: 0.10.5
5
11
  platform: ruby
6
12
  authors:
7
13
  - spox
@@ -9,19 +15,23 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2009-05-16 00:00:00 -07:00
18
+ date: 2010-09-27 00:00:00 -05:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: spox-textpow
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
23
32
  version: "0"
24
- version:
33
+ type: :runtime
34
+ version_requirements: *id001
25
35
  description: Ruby syntax highlighting
26
36
  email: spox@modspox.com
27
37
  executables:
@@ -42,13 +52,10 @@ files:
42
52
  - lib/uv/render_processor.rb
43
53
  - lib/uv/utility.rb
44
54
  - lib/uv.rb
45
- - render/xhtml
46
55
  - render/xhtml/amy.render
47
56
  - render/xhtml/iplastic.render
48
57
  - render/xhtml/cobalt.render
49
58
  - render/xhtml/sunburst.render
50
- - render/xhtml/files
51
- - render/xhtml/files/css
52
59
  - render/xhtml/files/css/zenburnesque.css
53
60
  - render/xhtml/files/css/sunburst.css
54
61
  - render/xhtml/files/css/slush_poppies.css
@@ -87,7 +94,6 @@ files:
87
94
  - render/xhtml/magicwb_amiga.render
88
95
  - render/xhtml/idle.render
89
96
  - render/xhtml/zenburnesque.render
90
- - render/latex
91
97
  - render/latex/amy.render
92
98
  - render/latex/iplastic.render
93
99
  - render/latex/cobalt.render
@@ -109,7 +115,6 @@ files:
109
115
  - render/latex/magicwb_amiga.render
110
116
  - render/latex/idle.render
111
117
  - render/latex/zenburnesque.render
112
- - render/old
113
118
  - render/old/txt2tags.render
114
119
  - syntax/blog_text.syntax
115
120
  - syntax/eiffel.syntax
@@ -261,6 +266,8 @@ files:
261
266
  - syntax/python.syntax
262
267
  has_rdoc: true
263
268
  homepage:
269
+ licenses: []
270
+
264
271
  post_install_message:
265
272
  rdoc_options:
266
273
  - --title
@@ -271,23 +278,31 @@ rdoc_options:
271
278
  require_paths:
272
279
  - lib
273
280
  required_ruby_version: !ruby/object:Gem::Requirement
281
+ none: false
274
282
  requirements:
275
283
  - - ">="
276
284
  - !ruby/object:Gem::Version
285
+ hash: 51
286
+ segments:
287
+ - 1
288
+ - 9
289
+ - 0
277
290
  version: 1.9.0
278
- version:
279
291
  required_rubygems_version: !ruby/object:Gem::Requirement
292
+ none: false
280
293
  requirements:
281
294
  - - ">="
282
295
  - !ruby/object:Gem::Version
296
+ hash: 3
297
+ segments:
298
+ - 0
283
299
  version: "0"
284
- version:
285
300
  requirements: []
286
301
 
287
302
  rubyforge_project:
288
- rubygems_version: 1.2.0
303
+ rubygems_version: 1.3.7
289
304
  signing_key:
290
- specification_version: 2
305
+ specification_version: 3
291
306
  summary: ultraviolet
292
307
  test_files: []
293
308