bismas 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,27 @@
1
+ module Bismas
2
+
3
+ module Version
4
+
5
+ MAJOR = 0
6
+ MINOR = 1
7
+ TINY = 0
8
+
9
+ class << self
10
+
11
+ # Returns array representation.
12
+ def to_a
13
+ [MAJOR, MINOR, TINY]
14
+ end
15
+
16
+ # Short-cut for version string.
17
+ def to_s
18
+ to_a.join('.')
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ VERSION = Version.to_s
26
+
27
+ end
@@ -0,0 +1,105 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # bismas -- A Ruby client for BISMAS databases #
5
+ # #
6
+ # Copyright (C) 2015 Jens Wille #
7
+ # #
8
+ # Authors: #
9
+ # Jens Wille <jens.wille@gmail.com> #
10
+ # #
11
+ # bismas is free software; you can redistribute it and/or modify it #
12
+ # under the terms of the GNU Affero General Public License as published by #
13
+ # the Free Software Foundation; either version 3 of the License, or (at your #
14
+ # option) any later version. #
15
+ # #
16
+ # bismas is distributed in the hope that it will be useful, but #
17
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY #
18
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public #
19
+ # License for more details. #
20
+ # #
21
+ # You should have received a copy of the GNU Affero General Public License #
22
+ # along with bismas. If not, see <http://www.gnu.org/licenses/>. #
23
+ # #
24
+ ###############################################################################
25
+ #++
26
+
27
+ require_relative 'parser'
28
+
29
+ module Bismas
30
+
31
+ class Writer < Base
32
+
33
+ DEFAULT_IO = $stdout
34
+
35
+ class << self
36
+
37
+ def write(*args, &block)
38
+ new(args.extract_options!, &block).write(*args)
39
+ end
40
+
41
+ def write_file(*args, &block)
42
+ file_method(:write, 'wb', *args, &block)
43
+ end
44
+
45
+ def open(*args, &block)
46
+ file_method(nil, 'wb', *args, &block)
47
+ end
48
+
49
+ end
50
+
51
+ def initialize(options = {})
52
+ @category_length = options[:category_length] || DEFAULT_CATEGORY_LENGTH
53
+ @padding_length = options[:padding_length] || DEFAULT_PADDING_LENGTH
54
+ @sort = options[:sort]
55
+
56
+ @chars = Bismas.chars(options)
57
+
58
+ super
59
+ end
60
+
61
+ def write(records, *args)
62
+ !records.is_a?(Hash) ?
63
+ records.each { |record| write_i(nil, record, *args) } :
64
+ records.each { |id, record| write_i(id, record, *args) }
65
+
66
+ self
67
+ end
68
+
69
+ def put(record, *args)
70
+ record.is_a?(Hash) ?
71
+ write_i(nil, record, *args) :
72
+ write_i(*args.unshift(*record))
73
+
74
+ self
75
+ end
76
+
77
+ alias_method :<<, :put
78
+
79
+ def []=(id, record)
80
+ write_i(id, record)
81
+ end
82
+
83
+ private
84
+
85
+ def write_i(id, record, io = io())
86
+ return if record.empty?
87
+
88
+ category_format, fs = "%-#{@category_length}s", @chars[:fs]
89
+
90
+ record[key] = id || auto_id.call if key && !record.key?(key)
91
+
92
+ io << @chars[:rs]
93
+
94
+ (@sort ? Hash[record.sort] : record).each { |k, v| Array(v).each { |w|
95
+ io << category_format % k if k
96
+ io << w.to_s << fs
97
+ } if v }
98
+
99
+ io << @chars[:padding] * @padding_length << fs if @padding_length > 0
100
+ io << @chars[:newline]
101
+ end
102
+
103
+ end
104
+
105
+ end
data/lib/bismas.rb ADDED
@@ -0,0 +1,146 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # bismas -- A Ruby client for BISMAS databases #
5
+ # #
6
+ # Copyright (C) 2015 Jens Wille #
7
+ # #
8
+ # Authors: #
9
+ # Jens Wille <jens.wille@gmail.com> #
10
+ # #
11
+ # bismas is free software; you can redistribute it and/or modify it #
12
+ # under the terms of the GNU Affero General Public License as published by #
13
+ # the Free Software Foundation; either version 3 of the License, or (at your #
14
+ # option) any later version. #
15
+ # #
16
+ # bismas is distributed in the hope that it will be useful, but #
17
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY #
18
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public #
19
+ # License for more details. #
20
+ # #
21
+ # You should have received a copy of the GNU Affero General Public License #
22
+ # along with bismas. If not, see <http://www.gnu.org/licenses/>. #
23
+ # #
24
+ ###############################################################################
25
+ #++
26
+
27
+ module Bismas
28
+
29
+ # Default file encoding
30
+ DEFAULT_ENCODING = 'CP850'
31
+
32
+ CHARS = { rs: 1, deleted: 255, padding: 219, fs: 0, newline: "\r\n" }
33
+
34
+ REGEX = Hash[CHARS.keys.map { |k| [k, "%{#{k}}"] }].update(
35
+ field: '(.*?)%{padding}*%{fs}',
36
+ skip_rest: '.*?(?=%{newline})',
37
+ skip_line: '.*?%{newline}',
38
+ skip_field: '.*?%{fs}'
39
+ )
40
+
41
+ CATEGORY_CHAR_SKIP = %i[rs deleted padding fs].each { |k|
42
+ CHARS[k] = CHARS[k].chr.force_encoding(DEFAULT_ENCODING) }
43
+
44
+ # See parameter +FELD+ in BISMAS <tt>*.CAT</tt>
45
+ DEFAULT_CATEGORY_LENGTH = 4
46
+
47
+ # See parameter +FUELLZEICHEN+ in BISMAS <tt>*.CFG</tt>
48
+ DEFAULT_PADDING_LENGTH = 20
49
+
50
+ class << self
51
+
52
+ def chars(options = {})
53
+ encoding = amend_encoding(options).split(':').last
54
+
55
+ Hash[CHARS.map { |k, v| [k, begin
56
+ v.encode(encoding)
57
+ rescue Encoding::UndefinedConversionError
58
+ v.dup.force_encoding(encoding)
59
+ end] }]
60
+ end
61
+
62
+ def regex(options = {}, chars = chars(options))
63
+ category_length = options[:category_length] || DEFAULT_CATEGORY_LENGTH
64
+
65
+ Hash[REGEX.map { |k, v| [k, Regexp.new(v % chars)] }].update(category:
66
+ /[^#{chars.values_at(*CATEGORY_CHAR_SKIP).join}]{#{category_length}}/)
67
+ end
68
+
69
+ def filter(klass, options, &block)
70
+ execute = %i[execute execute_mapped].map { |key|
71
+ value = Array(options[key]); lambda { |bind|
72
+ value.each { |code| eval(code, bind) } } }
73
+
74
+ mapping = mapping(options[:mapping], &block)
75
+
76
+ key_format = options[:key_format]
77
+
78
+ writer_options = {
79
+ encoding: encoding = options[:output_encoding],
80
+ key: options[:output_key],
81
+ sort: options[:sort],
82
+ padding_length: options[:padding_length],
83
+ category_length: options[:category_length]
84
+ }
85
+
86
+ reader_options = {
87
+ encoding: options[:input_encoding],
88
+ key: options[:input_key],
89
+ strict: options[:strict],
90
+ silent: options[:silent],
91
+ legacy: options[:legacy],
92
+ category_length: options[:category_length]
93
+ }
94
+
95
+ klass.open(options[:output], writer_options) { |writer|
96
+ Reader.parse_file(options[:input], reader_options) { |id, record|
97
+ execute[0][bind = binding]
98
+ record = mapping.apply(encode(record, encoding))
99
+
100
+ execute[1][bind]
101
+ writer[key_format % id] = record
102
+ }
103
+ }
104
+ end
105
+
106
+ def mapping(mapping, &block)
107
+ block ||= method(:abort)
108
+
109
+ Mapping[case mapping
110
+ when nil, Hash then mapping
111
+ when /\A\{.*\}\z/ then SafeYAML.load(mapping)
112
+ when String then File.readable?(mapping) ?
113
+ SafeYAML.load_file(mapping) : block["No such file: #{mapping}"]
114
+ else block["Invalid mapping: #{mapping.inspect}"]
115
+ end]
116
+ end
117
+
118
+ def encode(record, encoding)
119
+ return record unless encoding
120
+
121
+ fallback = Hash.new { |h, k| h[k] = '?' }
122
+
123
+ record.each { |key, values|
124
+ values.each { |value| value.encode!(encoding, fallback: fallback) }
125
+
126
+ unless fallback.empty?
127
+ chars = fallback.keys.map(&:inspect).join(', '); fallback.clear
128
+ warn "Undefined characters at #{$.}:#{key}: #{chars}"
129
+ end
130
+ }
131
+ end
132
+
133
+ def amend_encoding(options, default_encoding = DEFAULT_ENCODING)
134
+ (options[:encoding] ||= default_encoding).tap { |encoding|
135
+ encoding.prepend(default_encoding) if encoding.start_with?(':') }
136
+ end
137
+
138
+ end
139
+
140
+ end
141
+
142
+ require_relative 'bismas/base'
143
+ require_relative 'bismas/reader'
144
+ require_relative 'bismas/writer'
145
+ require_relative 'bismas/mapping'
146
+ require_relative 'bismas/version'
@@ -0,0 +1,18 @@
1
+ describe Bismas::Parser do
2
+
3
+ subject { described_class.new(strict: true) }
4
+
5
+ def self.expect_parse_error(msg, input)
6
+ example { expect{subject.parse(StringIO.new(*encode(input)))}
7
+ .to(raise_error(described_class::ParseError, /\A#{msg}/)) }
8
+ end
9
+
10
+ expect_parse_error('Malformed record', "foo\r\n")
11
+ expect_parse_error('Unexpected data', "\x010\r\n")
12
+ expect_parse_error('Unclosed field', "\x01000\r\n")
13
+ expect_parse_error('Unclosed field', "\x01foo\r\n")
14
+ expect_parse_error('Malformed field', "\x01foo\x00\r\n")
15
+ expect_parse_error('Malformed record', "\x01\r\nfoo\r\n")
16
+ expect_parse_error('Malformed record', "\x01\r\nfoo\r\n000")
17
+
18
+ end
@@ -0,0 +1,22 @@
1
+ describe Bismas::Reader do
2
+
3
+ example do
4
+ expect(described_class.parse_file(data('test.dat'), strict: true)).to eq({
5
+ 1 => { "005" => ["Bock, F."], "020" => ["Zur Geschichte des Schlagwortkatalogs in Praxis und Theorie"], "030" => ["Zentralblatt f\x81r Bibliothekswesen. 40(1923), S.494-502."], "055" => ["1923"], "060" => ["Geschichte des Schlagwortkataloges"], "059" => ["d"], "053" => ["a"], "120" => ["D"] },
6
+ 2 => { "005" => ["Bravo, B.R. => Rodriguez Bravo, B."], "150" => ["22. 4.2007 19:43:53"] },
7
+ 3 => { "005" => ["Simmons, P."], "020" => ["Microcomputer software for ISO 2709 record conversion"], "030" => ["Microcomputers for information management. 6(1989), S.197-205."], "055" => ["1989"], "060" => ["Bibliographische Software"], "053" => ["a"], "059" => ["e"], "100" => ["ISO 2709"], "065" => ["Datenformate"] },
8
+ 4 => { "005" => ["Fugmann, R."], "020" => ["\xAADie Aufgabenteilung zwischen Wortschatz und Grammatik in einer Indexsprache"], "030" => ["Datenbasen, Datenbanken, Netzwerke. Bd.1."], "045" => ["M\x81nchen"], "055" => ["1979"], "060" => ["Theorie verbaler Dokumentationssprachen"], "051" => ["S.67-93"], "059" => ["d"], "053" => ["a"] },
9
+ 5 => { "005" => ["Babu, B.Ramesh => Ramesh Babu, B."], "150" => ["10.12.2005 11:31:20"] },
10
+ 6 => { "005" => ["Rau, P."], "020" => ["\xAADie Facettenmethode und ihre Anwendung auf die Philologie"], "055" => ["1970"], "045" => ["Hamburg"], "058" => ["Assessorarbeit"], "053" => ["x"], "059" => ["d"], "115" => ["Geisteswissenschaften"] },
11
+ 7 => { "005" => ["Bo\xE1meyer, C."], "020" => ["RSWK-Anwendung und Schlagwortnormdatei unter Einsatz der Datenverarbeitung"], "030" => ["Zeitschrift f\x81r Bibliothekswesen und Bibliographie. 35(1988), S.113-121."], "055" => ["1988"], "060" => ["Regeln f\x81r den Schlagwortkatalog (RSWK)"], "100" => ["RSWK"], "101" => ["SWD"], "059" => ["d"], "053" => ["a"] },
12
+ 8 => { "005" => ["Bock, K."], "020" => ["RSWK oder der S\x81ndenkatalog"], "030" => ["BuB. 40(1988), S.262-267."], "055" => ["1988"], "060" => ["Regeln f\x81r den Schlagwortkatalog (RSWK)"], "058" => ["Forts. in: BuB 40(1988) S.926-927."], "059" => ["d"], "053" => ["a"] },
13
+ 9 => { "005" => ["Bock, K."], "020" => ["RSWK und die entt\x84uschte Liebe"], "030" => ["BuB. 40(1988), S.926-927."], "055" => ["1988"], "060" => ["Regeln f\x81r den Schlagwortkatalog (RSWK)"], "025" => ["ein Nachtrag"], "059" => ["d"], "053" => ["a"], "150" => [" "], "152" => [" 7. 4.2001 15:39:33"], "120" => ["D"] },
14
+ 10 => { "020" => ["SISIS"], "030" => ["Bibliotheksdienst. 35(2001) H.9, S.1179-1182."], "055" => ["2001"], "053" => ["a"], "059" => ["d"], "150" => [" "], "152" => ["29. 9.2001 11:38:17"], "005" => ["Klau\xE1, H."], "025" => ["15. Anwenderforum Berlin-Brandenburg"], "100" => ["SISIS"], "120" => ["Berlin", "Brandenburg", "D"] },
15
+ 11 => { "005" => ["Notess, G.R."], "020" => ["Tracking title search capabilities"], "030" => ["Online. 25(2001) no.3, S.72-74."], "053" => ["a"], "055" => ["2001"], "059" => ["e"], "060" => ["Volltextretrieval"], "150" => [" 5. 6.2001 11:36:02"] },
16
+ 12 => { "005" => ["G\x94dert, W."], "020" => ["Online-Katalog und bibliothekarische Inhaltserschlie\xE1ung"], "030" => ["77. Deutscher Bibliothekartag in Augsburg 1987. Reden und Vortr\x84ge. Hrsg.: Y.A. Haase u.a."], "045" => ["Frankfurt a.M."], "055" => ["1988"], "060" => ["Grundlagen u. Einf\x81hrungen: Allgemeine Literatur"], "065" => ["Regeln f\x81r den Schlagwortkatalog (RSWK)"], "050" => ["Klostermann"], "035" => ["Zeitschrift f\x81r Bibliothekswesen und Bibliographie: Sonderh.46"], "051" => ["S.279-302"], "053" => ["a"], "059" => ["d"] },
17
+ 13 => { "005" => ["Aluri, R.D."], "010" => ["Kemp, A."], "015" => ["Boll, J.J."], "020" => ["Subject analysis in online catalogs"], "045" => ["Englewood, CO"], "050" => ["Libraries Unlimited"], "055" => ["1991"], "060" => ["Klassifikationssysteme im Online-Retrieval"], "065" => ["Verbale Doksprachen im Online-Retrieval"], "058" => ["Rez. in: Technical services quarterly. 9(1992) no.3, S.87-88 (H.L. Hoerman); Knowledge organization 20(1993) no.3, S.165-166 (O. Oberhauser); JASIS 44(1993) S.593 (D. Vizine-Goetz)", "\r\r2. Aufl. unter: Olson, H.A., J.J. Boll: Subject access in online catalogs. 2nd ed. Englewood, CO: Libraries Unlimited 2001. xv, 333 S. ISBN 1-56308-800-2"], "051" => ["XII,303 S"], "052" => ["0-87287-670-5"], "053" => ["m"], "059" => ["e"], "130" => ["025.3'132--dc20"], "131" => ["Z699.35.S92A46 1990"], "136" => ["Catalogs, On-line--Subject access", "Subject cataloguing--Data processing", "Machine-readable bibliographic data", "Information retrieval"], "150" => [" "], "152" => ["26. 8.2005 15:16:28"] },
18
+ 14 => { "020" => ["Multilingual information management"], "055" => ["1999"], "059" => ["e"], "060" => ["Multilinguale Probleme"], "150" => [" 2. 8.2001 9:04:29"], "017" => ["Hovy, N. et al."], "025" => ["current levels and future abilities. A report commissioned by the US National Science Foundation and also delivered to the European's Commission's Language Engineering Office and the US Defense Advanced Research Projects Agency"], "050" => ["US National Science Foundation"], "058" => ["Vgl. auch: http://www.cs.cmu.edu/~ref/mlim/index.shtml"], "045" => ["?"], "056" => ["Over the past 50 years, a variety of language-related capabilities has been developed in machine translation, information retrieval, speech recognition, text summarization, and so on. These applications rest upon a set of core techniques such as language modeling, information extraction, parsing, generation, and multimedia planning and integration; and they involve methods using statistics, rules, grammars, lexicons, ontologies, training techniques, and so on. It is a puzzling fact that although all of this work deals with language in some form or other, the major applications have each developed a separate research field. For example, there is no reason why speech recognition techniques involving n-grams and hidden Markov models could not have been used in machine translation 15 years earlier than they were, or why some of the lexical and semantic insights from the subarea called Computational Linguistics are still not used in information retrieval. This picture will rapidly change. The twin challenges of massive information overload via the web and ubiquitous computers present us with an unavoidable task: developing techniques to handle multilingual and multi-modal information robustly and efficiently, with as high quality performanceas possible. The most effective way for us to address such a mammoth task, and to ensure that our various techniques and applications fit together, is to start talking across the artificial research boundaries. Extending the current technologies will require integrating the various capabilities into multi-functional and multi-lingual natural language systems. However, at this time there is no clear vision of how these technologies could or should be assembled into a coherent framework. What would be involved in connecting a speech recognition system to an information retrieval engine, and then using machine translation and summarization software to process the retrieved text? How can traditional parsing and generation be enhanced with statistical techniques? What would be the effect of carefully crafted lexicons on traditional information retrieval? At which points should machine translation be interleaved within information retrieval systems to"] }
19
+ }.each_value { |h| h.each_value { |a| encode(*a) } })
20
+ end
21
+
22
+ end
Binary file
@@ -0,0 +1,15 @@
1
+ $:.unshift('lib') unless $:.first == 'lib'
2
+
3
+ require 'bismas'
4
+
5
+ RSpec.configure { |config|
6
+ config.include(Module.new {
7
+ def encode(*args)
8
+ args.each { |s| s.force_encoding(Bismas::DEFAULT_ENCODING) }
9
+ end
10
+
11
+ def data(file)
12
+ File.join(File.dirname(__FILE__), 'data', file)
13
+ end
14
+ })
15
+ }
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bismas
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jens Wille
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-11-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cyclops
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: nuggets
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: hen
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.8'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 0.8.3
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '0.8'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 0.8.3
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ description: Access BISMAS databases from Ruby.
90
+ email: jens.wille@gmail.com
91
+ executables:
92
+ - bismas
93
+ extensions: []
94
+ extra_rdoc_files:
95
+ - README
96
+ - COPYING
97
+ - ChangeLog
98
+ files:
99
+ - COPYING
100
+ - ChangeLog
101
+ - README
102
+ - Rakefile
103
+ - bin/bismas
104
+ - lib/bismas.rb
105
+ - lib/bismas/base.rb
106
+ - lib/bismas/cli.rb
107
+ - lib/bismas/mapping.rb
108
+ - lib/bismas/parser.rb
109
+ - lib/bismas/reader.rb
110
+ - lib/bismas/version.rb
111
+ - lib/bismas/writer.rb
112
+ - spec/bismas/parser_spec.rb
113
+ - spec/bismas/reader_spec.rb
114
+ - spec/data/test.dat
115
+ - spec/spec_helper.rb
116
+ homepage: http://github.com/blackwinter/bismas
117
+ licenses:
118
+ - AGPL-3.0
119
+ metadata: {}
120
+ post_install_message: |2+
121
+
122
+ bismas-0.1.0 [2015-11-20]:
123
+
124
+ * First release.
125
+
126
+ rdoc_options:
127
+ - "--title"
128
+ - bismas Application documentation (v0.1.0)
129
+ - "--charset"
130
+ - UTF-8
131
+ - "--line-numbers"
132
+ - "--all"
133
+ - "--main"
134
+ - README
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '2.0'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubyforge_project:
149
+ rubygems_version: 2.5.0
150
+ signing_key:
151
+ specification_version: 4
152
+ summary: A Ruby client for BISMAS databases.
153
+ test_files: []