ydocx 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 01.05.2012
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,12 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/docx2html
6
+ lib/docx2html/bin/docx2html
7
+ lib/docx2html/lib/docx2html.rb
8
+ lib/docx2html/lib/docx2html/builder.rb
9
+ lib/docx2html/lib/docx2html/document.rb
10
+ lib/docx2html/lib/docx2html/html_methods.rb
11
+ lib/docx2html/lib/docx2html/parser.rb
12
+ lib/fachinfo.rb
data/README.txt ADDED
@@ -0,0 +1,21 @@
1
+ == ydocx - © ywesee GmbH
2
+
3
+ * https://github.com/zdavatz/ydocx
4
+ * Parsing docx files with Ruby and output them as HTML.
5
+
6
+ == Supports
7
+
8
+ * Tables
9
+ * Uppercase letters, numbers
10
+ * Lowercase letters, numbers
11
+ * Umlaute
12
+ * bold, italic, underline
13
+
14
+ == Using the great libraries
15
+
16
+ * nokogiri
17
+ * htmlentities
18
+
19
+ == License GPLv2.1
20
+
21
+ * http://www.gnu.org/licenses/lgpl-2.1.html
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ # Hoe.plugin :compiler
7
+ # Hoe.plugin :gem_prelude_sucks
8
+ # Hoe.plugin :inline
9
+ # Hoe.plugin :minitest
10
+ # Hoe.plugin :racc
11
+ # Hoe.plugin :rubyforge
12
+
13
+ Hoe.spec 'ydocx' do
14
+
15
+ developer('Yasuhiro Asaka, Zeno R.R. Davatz', 'yasaka@ywesee.com, zdavatz@ywesee.com')
16
+
17
+ end
data/bin/docx2html ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require 'pathname'
5
+
6
+ VERSION = "1.0.0"
7
+
8
+ root = Pathname.new(__FILE__).realpath.parent.parent
9
+ %w(
10
+ lib/docx2html/lib
11
+ lib
12
+ ).each do |lib|
13
+ $:.unshift root.join(lib) if $0 == __FILE__
14
+ end
15
+ require 'docx2html'
16
+
17
+ if file = ARGV.first
18
+ unless File.exist?(file)
19
+ exit
20
+ else
21
+ # TODO args handling
22
+ if true
23
+ require 'fachinfo'
24
+ end
25
+ Docx2html::Document.open(file).to_html file, :style => true
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require 'pathname'
5
+
6
+ root = Pathname.new(__FILE__).realpath.parent.parent
7
+ $:.unshift root.join('lib/docx2html') if $0 == __FILE__
8
+ require 'docx2html'
9
+
10
+ if file = ARGV.first
11
+ unless File.exist?(file)
12
+ exit
13
+ else
14
+ Docx2html::Document.open(file).to_html file, :style => true
15
+ end
16
+ end
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'nokogiri'
5
+ require 'docx2html/html_methods'
6
+
7
+ module Docx2html
8
+ class Builder
9
+ include HtmlMethods
10
+ attr_accessor :body, :indecies, :style, :title
11
+ def initialize(body)
12
+ @body = body
13
+ @container = {}
14
+ @indecies = []
15
+ @style = false
16
+ @title = ''
17
+ init
18
+ if block_given?
19
+ yield self
20
+ end
21
+ end
22
+ def init
23
+ end
24
+ def build
25
+ if @container.has_key?(:content)
26
+ @container[:content] = @body
27
+ @body = [@container]
28
+ end
29
+ if before_content = build_before_content
30
+ @body.unshift before_content
31
+ end
32
+ if after_content = build_after_content
33
+ @body.push after_content
34
+ end
35
+ body = ''
36
+ @body.each do |e|
37
+ body << build_tag(e[:tag], e[:content], e[:attributes])
38
+ end
39
+ builder = Nokogiri::HTML::Builder.new do |doc|
40
+ doc.html {
41
+ doc.head {
42
+ doc.meta :charset => 'utf-8'
43
+ doc.title @title
44
+ doc.style { doc << style } if @style
45
+ }
46
+ doc.body { doc << body }
47
+ }
48
+ end
49
+ builder.to_html.gsub(/\n/, '')
50
+ end
51
+ private
52
+ def build_after_content
53
+ nil
54
+ end
55
+ def build_before_content
56
+ nil
57
+ end
58
+ def build_tag(tag, content, attributes)
59
+ return '' if content.empty?
60
+ _content = ''
61
+ if content.is_a? Array
62
+ content.each do |c|
63
+ next if c.nil? or c.empty?
64
+ if c.is_a? Hash
65
+ _content << build_tag(c[:tag], c[:content], c[:attributes])
66
+ elsif c.is_a? String
67
+ _content << c.chomp.to_s
68
+ end
69
+ end
70
+ elsif content.is_a? Hash
71
+ _content = build_tag(content[:tag], content[:content], content[:attributes])
72
+ elsif content.is_a? String
73
+ _content = content
74
+ end
75
+ _tag = tag.to_s
76
+ _attributes = ''
77
+ unless attributes.empty?
78
+ attributes.each_pair do |k, v|
79
+ _attributes << " #{k.to_s}=#{v.to_s}"
80
+ end
81
+ end
82
+ "<#{_tag}#{_attributes}>#{_content}</#{_tag}>"
83
+ end
84
+ def style
85
+ style = <<-CSS
86
+ table, tr, td {
87
+ border-collapse: collapse;
88
+ border: 1px solid gray;
89
+ }
90
+ table {
91
+ margin: 5px 0 5px 0;
92
+ }
93
+ td {
94
+ padding: 5px 10px;
95
+ }
96
+ CSS
97
+ style.gsub(/\s\s+|\n/, ' ')
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'pathname'
5
+ require 'zip/zip'
6
+ require 'docx2html/parser'
7
+ require 'docx2html/builder'
8
+
9
+ module Docx2html
10
+ class Document
11
+ attr_reader :contents
12
+ def self.open(file)
13
+ self.new(file)
14
+ end
15
+ def initialize(file)
16
+ @contents = nil
17
+ @indecies = nil
18
+ read(file)
19
+ end
20
+ def to_html(file='', options={})
21
+ html = ''
22
+ Builder.new(@contents) do |builder|
23
+ builder.title = @path
24
+ builder.style = options[:style]
25
+ if @indecies
26
+ builder.indecies = @indecies
27
+ end
28
+ html = builder.build
29
+ end
30
+ unless file.empty?
31
+ path = Pathname.new(file).realpath.sub_ext('.html')
32
+ File.open(path, 'w:utf-8') do |f|
33
+ f.puts html
34
+ end
35
+ else
36
+ html
37
+ end
38
+ end
39
+ private
40
+ def read(file)
41
+ @path = File.expand_path(file)
42
+ @zip = Zip::ZipFile.open(@path)
43
+ stream = @zip.find_entry('word/document.xml').get_input_stream
44
+ Parser.new(stream) do |parser|
45
+ @contents = parser.parse
46
+ @indecies = parser.indecies
47
+ end
48
+ @zip.close
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ module Docx2html
5
+ module HtmlMethods
6
+ def tag(tag, content = [], attributes = {})
7
+ tag_hash = {
8
+ :tag => tag,
9
+ :content => content,
10
+ :attributes => attributes
11
+ }
12
+ tag_hash
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'nokogiri'
5
+ require 'htmlentities'
6
+ require 'docx2html/html_methods'
7
+
8
+ module Docx2html
9
+ class Parser
10
+ include HtmlMethods
11
+ attr_accessor :indecies, :result
12
+ def initialize(stream)
13
+ @xml = Nokogiri::XML.parse(stream)
14
+ @coder = HTMLEntities.new
15
+ @indecies = []
16
+ @result = []
17
+ init
18
+ if block_given?
19
+ yield self
20
+ end
21
+ end
22
+ def init
23
+ end
24
+ def parse
25
+ @xml.xpath('//w:document//w:body').children.map do |node|
26
+ case node.node_name
27
+ when 'text'
28
+ @result << parse_paragraph(node)
29
+ when 'tbl'
30
+ @result << parse_table(node)
31
+ when 'image'
32
+ # pending
33
+ when 'p'
34
+ @result << parse_paragraph(node)
35
+ else
36
+ # skip
37
+ end
38
+ end
39
+ @result
40
+ end
41
+ private
42
+ def apply_fonts(rpr, text)
43
+ symbol = false
44
+ unless rpr.xpath('w:rFonts').empty?
45
+ rpr.xpath('w:rFonts').each do |font|
46
+ if font.values.include? 'Symbol'
47
+ symbol = true
48
+ end
49
+ break if symbol
50
+ end
51
+ end
52
+ if symbol
53
+ _text = ''
54
+ text.unpack('U*').each do |char|
55
+ _text << optional_replace(char.to_s(16))
56
+ end
57
+ text = _text
58
+ end
59
+ text
60
+ end
61
+ def apply_align(rpr, text)
62
+ unless rpr.xpath('w:vertAlign').empty?
63
+ script = rpr.xpath('w:vertAlign').first['val'].to_sym
64
+ if script == :subscript
65
+ text = tag(:sub, text)
66
+ elsif script == :superscript
67
+ text = tag(:sup, text)
68
+ end
69
+ end
70
+ text
71
+ end
72
+ def parse_as_block(r, text)
73
+ nil # default no block element
74
+ end
75
+ def optional_escape(text)
76
+ return text = '&nbsp;' if text.empty?
77
+ text.force_encoding('utf-8')
78
+ # NOTE
79
+ # :named only for escape at Builder
80
+ text = @coder.encode(text, :named)
81
+ text
82
+ end
83
+ def optional_replace(code)
84
+ code = '0x' + code
85
+ # NOTE
86
+ # replace with rsemble html character ref
87
+ # Symbol Font to HTML Character named ref
88
+ case code
89
+ when '0xf020' # '61472'
90
+ ""
91
+ when '0xf025' # '61477'
92
+ "%"
93
+ when '0xf02b' # '61482'
94
+ "*"
95
+ when '0xf02b' # '61483'
96
+ "+"
97
+ when '0xf02d' # '61485'
98
+ "-"
99
+ when '0xf02f' # '61487'
100
+ "/"
101
+ when '0xf03c' # '61500'
102
+ "&lt;"
103
+ when '0xf03d' # '61501'
104
+ "="
105
+ when '0xf03e' # '61502'
106
+ "&gt;"
107
+ when '0xf040' # '61504'
108
+ "&cong;"
109
+ when '0xf068' # '61544'
110
+ "&eta;"
111
+ when '0xf071' # '61553'
112
+ "&theta;"
113
+ when '0xf06d' # '61549'
114
+ "&mu;"
115
+ when '0xf0a3' # '61603'
116
+ "&le;"
117
+ when '0xf0ab' # '61611'
118
+ "&harr;"
119
+ when '0xf0ac' # '61612'
120
+ "&larr;"
121
+ when '0xf0ad' # '61613'
122
+ "&uarr;"
123
+ when '0xf0ae' # '61614'
124
+ "&rarr;"
125
+ when '0xf0ad' # '61615'
126
+ "&darr;"
127
+ when '0xf0b1' # '61617'
128
+ "&plusmn;"
129
+ when '0xf0b2' # '61618'
130
+ "&Prime;"
131
+ when '0xf0b3' # '61619'
132
+ "&ge;"
133
+ when '0xf0b4' # '61620'
134
+ "&times;"
135
+ when '0xf0b7' # '61623'
136
+ "&sdot;"
137
+ else
138
+ #p "code : " + ("&#%s;" % code)
139
+ #p "hex : " + code.hex.to_s
140
+ #p "char : " + @coder.decode("&#%s;" % code)
141
+ #@coder.decode("&#%s;" % code.hex.to_s)
142
+ end
143
+ end
144
+ def parse_image
145
+ # pending
146
+ end
147
+ def parse_paragraph(node)
148
+ paragraph = tag :p
149
+ node.xpath('w:r').each do |r|
150
+ unless r.xpath('w:t').empty?
151
+ paragraph[:content] << parse_text(r)
152
+ else
153
+ unless r.xpath('w:tab').empty?
154
+ if paragraph[:content].last != '&nbsp;' # as a space
155
+ paragraph[:content] << optional_escape('')
156
+ end
157
+ end
158
+ unless r.xpath('w:sym').empty?
159
+ code = r.xpath('w:sym').first['char'].downcase # w:char
160
+ paragraph[:content] << optional_replace(code)
161
+ end
162
+ end
163
+ end
164
+ paragraph
165
+ end
166
+ def parse_table(node)
167
+ table = tag :table
168
+ node.xpath('w:tr').each do |tr|
169
+ cells = tag :tr
170
+ tr.xpath('w:tc').each do |tc|
171
+ attributes = {}
172
+ tc.xpath('w:tcPr').each do |tcpr|
173
+ if span = tcpr.xpath('w:gridSpan') and !span.empty?
174
+ attributes[:colspan] = span.first['val'] # w:val
175
+ end
176
+ end
177
+ cell = tag :td, [], attributes
178
+ tc.xpath('w:p').each do |p|
179
+ cell[:content] << parse_paragraph(p)
180
+ end
181
+ cells[:content] << cell
182
+ end
183
+ table[:content] << cells
184
+ end
185
+ table
186
+ end
187
+ def parse_text(r)
188
+ text = r.xpath('w:t').map(&:text).join('')
189
+ text = optional_escape(text)
190
+ if rpr = r.xpath('w:rPr')
191
+ text = apply_fonts(rpr, text)
192
+ if block = parse_as_block(r, text)
193
+ block
194
+ else
195
+ # inline tag
196
+ text = apply_align(rpr, text)
197
+ unless rpr.xpath('w:u').empty?
198
+ text = tag(:span, text, {:style => "text-decoration:underline;"})
199
+ end
200
+ unless rpr.xpath('w:i').empty?
201
+ text = tag(:em, text)
202
+ end
203
+ unless rpr.xpath('w:b').empty?
204
+ text = tag(:strong, text)
205
+ end
206
+ text
207
+ end
208
+ else
209
+ text
210
+ end
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'docx2html/document'
5
+
6
+ module Docx2html
7
+ end
data/lib/fachinfo.rb ADDED
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'cgi'
5
+
6
+ module Docx2html
7
+ class Parser
8
+ private
9
+ def parse_as_block(r, text)
10
+ if r.parent.previous.nil?
11
+ # first line is package name
12
+ return tag(:h2, text)
13
+ end
14
+ text = text.strip
15
+ # TODO
16
+ # Franzoesisch
17
+ chapters = {
18
+ 'Dos./Anw.' => /^Dosierung\s*\/\s*Anwendung/u, # 5
19
+ 'Eigensch.' => /^Eigenschaften\s*\/\s*Wirkungen($|\s*\(\s*(ATC\-Code|Wirkungsmechanismus|Pharmakodyamik|Klinische\s+Wirksamkeit)\s*\)\s*$)|^Propri.t.s/iu, # 13
20
+ 'Galen.Form' => /^Galenische\s+Form\s+und\s+Wirkstoffmenge\s+pro\s+Einheit$|^Forme\s*gal.nique/iu, # 3
21
+ 'Ind./Anw.mögl.' => /^Indikationen(\s+|\s*\/\s*)Anwendungsm&ouml;glichkeiten$|^Indications/u, # 4
22
+ 'Interakt.' => /^Interaktionen$|^Interactions/u, # 8
23
+ 'Kontraind.' => /^Kontraindikationen($|\s*\(\s*absolute\s+Kontraindikationen\s*\)$)/u, # 6
24
+ 'Name' => /^Name\s+des\s+Pr&auml;parates$/, # 1
25
+ 'Packungen' => /^Packungen($|\s*\(\s*mit\s+Angabe\s+der\s+Abgabekategorie\s*\)$)/u, # 18
26
+ 'Präklin.' => /^Pr&auml;klinische\s+Daten$/u, # 15
27
+ 'Pharm.kinetik' => /^Pharmakokinetik($|\s*\((Absorption,\s*Distribution,\s*Metabolisms,\s*Elimination\s|Kinetik\s+spezieller\s+Patientengruppen)*\)$)|^Pharmacocin.tique?/iu, # 14
28
+ 'Sonstige H.' => /^Sonstige\s*Hinweise($|\s*\(\s*(Inkompatibilit&auml;ten|Beeinflussung\s*diagnostischer\s*Methoden|Haltbarkeit|Besondere\s*Lagerungshinweise|Hinweise\s+f&uuml;r\s+die\s+Handhabung)\s*\)$)|^Remarques/u, # 16
29
+ 'Schwangerschaft' => /^Schwangerschaft(,\s*|\s*\/\s*)Stillzeit$/u, # 9
30
+ 'Stand d. Info.' => /^Stand\s+der\s+Information$|^Mise\s+.\s+jour$/iu, # 20
31
+ 'Unerw.Wirkungen' => /^Unerw&uuml;nschte\s+Wirkungen$/u, # 11
32
+ 'Überdos.' => /^&Uuml;berdosierung$|^Surdosage$/u, # 12
33
+ 'Warn.hinw.' => /^Warnhinweise\s+und\s+Vorsichtsmassnahmen($|\s*\/\s*(relative\s+Kontraindikationen|Warnhinweise\s*und\s*Vorsichtsmassnahmen)$)/u, # 7
34
+ 'Fahrtücht.' => /^Wirkung\s+auf\s+die\s+Fahrt&uuml;chtigkeit\s+und\s+auf\s+das\s+Bedienen\s+von\s+Maschinen$/u, # 10
35
+ 'Swissmedic-Nr.' => /^Zulassungsnummer($|\s*\(\s*Swissmedic\s*\)$)/u, # 17
36
+ 'Reg.Inhaber' => /^Zulassungsinhaberin($|\s*\(\s*Firma\s+und\s+Sitz\s+gem&auml;ss\s*Handelsregisterauszug\s*\))/u, # 19
37
+ 'Zusammens.' => /^Zusammensetzung($|\s*\/\s*(Wirkstoffe|Hilsstoffe)$)/u, # 2
38
+ }.each_pair do |chapter, regexp|
39
+ if text =~ regexp
40
+ next unless r.next.nil? # without line break
41
+ id = CGI.escape(text.gsub(/&(.)uml;/, '\1').gsub(/\s*\/\s*|\/|\s+/, '_').downcase)
42
+ @indecies << {:text => chapter, :id => id}
43
+ return tag(:h3, text, {:id => id})
44
+ end
45
+ end
46
+ nil
47
+ end
48
+ end
49
+ class Builder
50
+ def init
51
+ @container = tag(:div, [], {:id => 'container'})
52
+ end
53
+ private
54
+ def build_after_content
55
+ link = tag(:a, 'Top', {:href => ''})
56
+ tag(:div, link, {:id => 'footer'})
57
+ end
58
+ def build_before_content
59
+ if @indecies
60
+ indices = []
61
+ @indecies.each do |index|
62
+ indices << tag(:li, tag(:a, index[:text], {:href => "#" + index[:id]}))
63
+ end
64
+ tag(:div, tag(:ul, indices), {:id => 'indecies'})
65
+ end
66
+ end
67
+ def style
68
+ style = <<-CSS
69
+ table, tr, td {
70
+ border-collapse: collapse;
71
+ border: 1px solid gray;
72
+ }
73
+ table {
74
+ margin: 5px 0 5px 0;
75
+ }
76
+ td {
77
+ padding: 5px 10px;
78
+ }
79
+ body {
80
+ position: relative;
81
+ padding: 0 0 20px 0;
82
+ margin: 0px;
83
+ width: 100%;
84
+ height: auto;
85
+ }
86
+ div#indecies {
87
+ position: relative;
88
+ padding: 0px;
89
+ float: left;
90
+ width: 200px;
91
+ }
92
+ div#indecies ul {
93
+ margin: 0;
94
+ padding: 0 0 0 25px;
95
+ }
96
+ div#container {
97
+ position: relative;
98
+ padding: 0px;
99
+ float: top left;
100
+ margin-left: 200px;
101
+ }
102
+ div#footer {
103
+ position: relative;
104
+ float: bottom right;
105
+ text-align: right;
106
+ padding-right: 25px;
107
+ }
108
+ CSS
109
+ style.gsub(/\s\s+|\n/, ' ')
110
+ end
111
+ end
112
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ydocx
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Yasuhiro Asaka, Zeno R.R. Davatz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rdoc
16
+ requirement: &21539280 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.10'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *21539280
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ requirement: &21538860 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '2.13'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *21538860
36
+ description: ''
37
+ email:
38
+ - yasaka@ywesee.com, zdavatz@ywesee.com
39
+ executables:
40
+ - docx2html
41
+ extensions: []
42
+ extra_rdoc_files:
43
+ - History.txt
44
+ - Manifest.txt
45
+ - README.txt
46
+ files:
47
+ - History.txt
48
+ - Manifest.txt
49
+ - README.txt
50
+ - Rakefile
51
+ - bin/docx2html
52
+ - lib/docx2html/bin/docx2html
53
+ - lib/docx2html/lib/docx2html.rb
54
+ - lib/docx2html/lib/docx2html/builder.rb
55
+ - lib/docx2html/lib/docx2html/document.rb
56
+ - lib/docx2html/lib/docx2html/html_methods.rb
57
+ - lib/docx2html/lib/docx2html/parser.rb
58
+ - lib/fachinfo.rb
59
+ homepage: https://github.com/zdavatz/ydocx
60
+ licenses: []
61
+ post_install_message:
62
+ rdoc_options:
63
+ - --main
64
+ - README.txt
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project: ydocx
81
+ rubygems_version: 1.8.15
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: ''
85
+ test_files: []