bio-nexml 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +15 -0
- data/Gemfile.lock +24 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +47 -0
- data/Rakefile +55 -0
- data/TODO.txt +6 -0
- data/VERSION +1 -0
- data/bio-nexml.gemspec +126 -0
- data/extconf.rb +2 -0
- data/lib/bio-nexml.rb +0 -0
- data/lib/bio.rb +321 -0
- data/lib/bio/db/nexml.rb +109 -0
- data/lib/bio/db/nexml/mapper.rb +113 -0
- data/lib/bio/db/nexml/mapper/framework.rb +157 -0
- data/lib/bio/db/nexml/mapper/inflection.rb +99 -0
- data/lib/bio/db/nexml/mapper/repository.rb +59 -0
- data/lib/bio/db/nexml/matrix.rb +1046 -0
- data/lib/bio/db/nexml/parser.rb +622 -0
- data/lib/bio/db/nexml/schema/README.txt +21 -0
- data/lib/bio/db/nexml/schema/abstract.xsd +159 -0
- data/lib/bio/db/nexml/schema/characters/README.txt +1 -0
- data/lib/bio/db/nexml/schema/characters/abstractcharacters.xsd +361 -0
- data/lib/bio/db/nexml/schema/characters/characters.xsd +22 -0
- data/lib/bio/db/nexml/schema/characters/continuous.xsd +190 -0
- data/lib/bio/db/nexml/schema/characters/dna.xsd +282 -0
- data/lib/bio/db/nexml/schema/characters/protein.xsd +280 -0
- data/lib/bio/db/nexml/schema/characters/restriction.xsd +239 -0
- data/lib/bio/db/nexml/schema/characters/rna.xsd +283 -0
- data/lib/bio/db/nexml/schema/characters/standard.xsd +261 -0
- data/lib/bio/db/nexml/schema/external/sawsdl.xsd +21 -0
- data/lib/bio/db/nexml/schema/external/xhtml-datatypes-1.xsd +177 -0
- data/lib/bio/db/nexml/schema/external/xlink.xsd +75 -0
- data/lib/bio/db/nexml/schema/external/xml.xsd +145 -0
- data/lib/bio/db/nexml/schema/meta/README.txt +2 -0
- data/lib/bio/db/nexml/schema/meta/annotations.xsd +100 -0
- data/lib/bio/db/nexml/schema/meta/meta.xsd +294 -0
- data/lib/bio/db/nexml/schema/nexml.xsd +104 -0
- data/lib/bio/db/nexml/schema/taxa/README.txt +2 -0
- data/lib/bio/db/nexml/schema/taxa/taxa.xsd +39 -0
- data/lib/bio/db/nexml/schema/trees/README.txt +2 -0
- data/lib/bio/db/nexml/schema/trees/abstracttrees.xsd +135 -0
- data/lib/bio/db/nexml/schema/trees/network.xsd +113 -0
- data/lib/bio/db/nexml/schema/trees/tree.xsd +149 -0
- data/lib/bio/db/nexml/schema/trees/trees.xsd +36 -0
- data/lib/bio/db/nexml/taxa.rb +147 -0
- data/lib/bio/db/nexml/trees.rb +663 -0
- data/lib/bio/db/nexml/writer.rb +265 -0
- data/test/data/nexml/test.xml +69 -0
- data/test/test_bio-nexml.rb +17 -0
- data/test/unit/bio/db/nexml/tc_factory.rb +119 -0
- data/test/unit/bio/db/nexml/tc_mapper.rb +78 -0
- data/test/unit/bio/db/nexml/tc_matrix.rb +551 -0
- data/test/unit/bio/db/nexml/tc_parser.rb +21 -0
- data/test/unit/bio/db/nexml/tc_taxa.rb +118 -0
- data/test/unit/bio/db/nexml/tc_trees.rb +370 -0
- data/test/unit/bio/db/nexml/tc_writer.rb +633 -0
- metadata +253 -0
data/lib/bio/db/nexml.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
#load XML library for parser and serializer
|
2
|
+
require 'xml'
|
3
|
+
|
4
|
+
#load required class and module definitions
|
5
|
+
require "bio/db/nexml/mapper"
|
6
|
+
|
7
|
+
#Autoload definition
|
8
|
+
module Bio
|
9
|
+
module NeXML
|
10
|
+
|
11
|
+
@@id_counter = 0;
|
12
|
+
def self.generate_id( klass )
|
13
|
+
myname = klass.name
|
14
|
+
local = myname.gsub(/.*:/,"")
|
15
|
+
@@id_counter += 1
|
16
|
+
newid = @@id_counter
|
17
|
+
"#{local}#{newid}"
|
18
|
+
end
|
19
|
+
|
20
|
+
module Base
|
21
|
+
attr_accessor :xml_base
|
22
|
+
attr_accessor :xml_id
|
23
|
+
attr_accessor :xml_lang
|
24
|
+
attr_accessor :xml_space
|
25
|
+
end #end module Base
|
26
|
+
|
27
|
+
# Autoload multiple modules that reside in the same file.
|
28
|
+
def self.mautoload( modules, file )
|
29
|
+
modules.each do |m|
|
30
|
+
autoload m, file
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
mautoload %w|Otu Otus|, 'bio/db/nexml/taxa.rb'
|
35
|
+
mautoload %w|Node Edge Tree Network Trees|, 'bio/db/nexml/trees.rb'
|
36
|
+
mautoload %w|State Char States Cell Sequence Format Characters|, 'bio/db/nexml/matrix.rb'
|
37
|
+
|
38
|
+
autoload :Parser, 'bio/db/nexml/parser'
|
39
|
+
autoload :Writer, 'bio/db/nexml/writer'
|
40
|
+
|
41
|
+
class Nexml
|
42
|
+
@@writer = Bio::NeXML::Writer.new
|
43
|
+
include Mapper
|
44
|
+
include Enumerable
|
45
|
+
attr_accessor :version
|
46
|
+
attr_accessor :generator
|
47
|
+
|
48
|
+
has_n :otus, :singularize => false
|
49
|
+
has_n :trees, :singularize => false
|
50
|
+
has_n :characters, :singularize => false
|
51
|
+
|
52
|
+
def initialize( version = '0.9', generator = 'bioruby' )
|
53
|
+
@version = version
|
54
|
+
@generator = generator
|
55
|
+
end
|
56
|
+
|
57
|
+
# Append a Otus, Trees, or Characters object to any
|
58
|
+
# Nexml object.
|
59
|
+
def <<( element )
|
60
|
+
case element
|
61
|
+
when Otus
|
62
|
+
add_otus element
|
63
|
+
when Trees
|
64
|
+
add_trees element
|
65
|
+
when Characters
|
66
|
+
add_characters element
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def create_otus( options = {} )
|
71
|
+
otus = Otus.new( Bio::NeXML.generate_id( Otus ), options )
|
72
|
+
self << otus
|
73
|
+
otus
|
74
|
+
end
|
75
|
+
|
76
|
+
def create_trees( options )
|
77
|
+
trees = Trees.new( Bio::NeXML.generate_id( Trees ), options )
|
78
|
+
self << trees
|
79
|
+
trees
|
80
|
+
end
|
81
|
+
|
82
|
+
def create_characters( type = "Dna", verbose = false, options = {} )
|
83
|
+
subtype = verbose ? "Cells" : "Seqs"
|
84
|
+
klass_name = "#{type.to_s.capitalize}#{subtype}"
|
85
|
+
klass = NeXML.const_get( klass_name )
|
86
|
+
characters = klass.new( Bio::NeXML.generate_id( klass ), options )
|
87
|
+
self << characters
|
88
|
+
characters
|
89
|
+
end
|
90
|
+
|
91
|
+
def to_xml
|
92
|
+
node = @@writer.create_node( "nex:nexml", :"xsi:schemaLocation" => "http://www.nexml.org/2009 http://www.nexml.org/2009/xsd/nexml.xsd", :generator => generator, :version => version )
|
93
|
+
node.namespaces = { nil => "http://www.nexml.org/2009", :xsi => "http://www.w3.org/2001/XMLSchema-instance", :xlink => "http://www.w3.org/1999/xlink", :nex => "http://www.nexml.org/2009" }
|
94
|
+
self.each_otus do |otus|
|
95
|
+
node << otus.to_xml
|
96
|
+
end
|
97
|
+
self.each_characters do |characters|
|
98
|
+
node << characters.to_xml
|
99
|
+
end
|
100
|
+
self.each_trees do |trees|
|
101
|
+
node << trees.to_xml
|
102
|
+
end
|
103
|
+
node
|
104
|
+
end
|
105
|
+
|
106
|
+
end #end class Nexml
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'bio/db/nexml/mapper/inflection'
|
2
|
+
require 'bio/db/nexml/mapper/repository'
|
3
|
+
require 'bio/db/nexml/mapper/framework'
|
4
|
+
|
5
|
+
module Bio
|
6
|
+
module NeXML
|
7
|
+
|
8
|
+
# Mapper provides a very small DSL for defining NeXML classes, specifically one-to-many relation
|
9
|
+
# between classes as they are found a lot in NeXML. Though the style has been borrowed from
|
10
|
+
# ActiveRecord, it should not be mistaken for an ORM. It just factors out repetitive chunk of
|
11
|
+
# code that would otherwise be present.
|
12
|
+
#
|
13
|
+
# Including Mapper in a class, creates <tt>has_n</tt>, and <tt>belongs_to</tt> class methods
|
14
|
+
# by extending Framework module. These methods are used to define a one-to-many relation
|
15
|
+
# between two classes. Two types of one-to-many relation occurs in NeXML.
|
16
|
+
# * parent-child - an element <em>contains</em> other elements. In raw NeXML it would mean
|
17
|
+
# nested elements.
|
18
|
+
# * association - an element <em>refers</em> to other elements. In raw NeXML it would mean
|
19
|
+
# a source element, referred to by several targets.
|
20
|
+
#
|
21
|
+
# Their implementation however is same. Defining a relation automatically creates methods to
|
22
|
+
# add, delete and query objects.
|
23
|
+
#
|
24
|
+
# class Otu
|
25
|
+
# property :id
|
26
|
+
# belongs_to :otus
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# class Otus
|
30
|
+
# property :id
|
31
|
+
# has_n :otus
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# t1 = Otu.new
|
35
|
+
# t1.id = 't1'
|
36
|
+
# t2 = Otu.new
|
37
|
+
# t2.id = 't2'
|
38
|
+
# o1 = Otus.new
|
39
|
+
# o1.id = 'o1'
|
40
|
+
#
|
41
|
+
# # add to source
|
42
|
+
# o1.add_otu( t1 )
|
43
|
+
# o1.otus
|
44
|
+
# => [ t1 ]
|
45
|
+
# t1.otus
|
46
|
+
# => o1
|
47
|
+
#
|
48
|
+
# # add to target
|
49
|
+
# t2.otus = o1
|
50
|
+
# o1.otus
|
51
|
+
# => [ t1, t2 ]
|
52
|
+
# t2.otus
|
53
|
+
# => o1
|
54
|
+
#
|
55
|
+
# # query from source
|
56
|
+
# o1.has_otu?( t1 )
|
57
|
+
# => true
|
58
|
+
# o1.get_otu_by_id( 't1' )
|
59
|
+
# => t1
|
60
|
+
#
|
61
|
+
# # delete from source
|
62
|
+
# o1.delete_otu( t1 )
|
63
|
+
# o1.otus
|
64
|
+
# => [ t2 ]
|
65
|
+
# t1.otus
|
66
|
+
# => nil
|
67
|
+
module Mapper # :nodoc: all
|
68
|
+
|
69
|
+
# Gets or sets properties of the receiver.
|
70
|
+
def properties( args = {} )
|
71
|
+
@properties ||= {}
|
72
|
+
|
73
|
+
# set properties if defined
|
74
|
+
args.each do |property, value|
|
75
|
+
raise "#{property} not defined" unless respond_to?( setter = "#{property}=" )
|
76
|
+
send( setter, value )
|
77
|
+
end unless args.empty?
|
78
|
+
|
79
|
+
# return a copy of @properties so that it is not modified inadvertently by the user
|
80
|
+
@properties.dup
|
81
|
+
end
|
82
|
+
alias properties= properties
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
# Fetches an instance variable corresponding to name. If the instance variable
|
87
|
+
# is nil, set it to defaul value and return it.
|
88
|
+
def repository( name, type = HashRepository )
|
89
|
+
ivget( name ) || ivset( name, type.new )
|
90
|
+
end
|
91
|
+
|
92
|
+
# Return an instance variable corresponding to the given name.
|
93
|
+
# '@' is automatically prepended to the name.
|
94
|
+
# object.ivget( 'name' ) #=> returns value of @name
|
95
|
+
# object.ivget( :name ) #=> returns value of @name
|
96
|
+
def ivget( name )
|
97
|
+
instance_variable_get( "@#{name}" )
|
98
|
+
end
|
99
|
+
|
100
|
+
# Set an instance variable corresponding to the given name.
|
101
|
+
# '@' is automatically prepended to the name.
|
102
|
+
# object.ivset( 'name', value ) #=> sets @name to value
|
103
|
+
# object.ivget( :name, value ) #=> sets @name to value
|
104
|
+
def ivset( name, value = nil )
|
105
|
+
instance_variable_set( "@#{name}", value )
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.included( klass )
|
109
|
+
klass.extend Framework
|
110
|
+
end
|
111
|
+
end #end module Mapper
|
112
|
+
end #end module NeXML
|
113
|
+
end #end module Bio
|
@@ -0,0 +1,157 @@
|
|
1
|
+
module Bio
|
2
|
+
module NeXML
|
3
|
+
module Mapper
|
4
|
+
|
5
|
+
# Framework is the real workhorse of Mapper.
|
6
|
+
module Framework
|
7
|
+
|
8
|
+
# Define a source for the target.
|
9
|
+
# belongs_to :source
|
10
|
+
def belongs_to( name, options = {} )
|
11
|
+
update = ( options[ :update ] || self.name.key ).to_sym
|
12
|
+
|
13
|
+
# create attribute reader for source
|
14
|
+
attr_reader name
|
15
|
+
|
16
|
+
# Add this target to a source.
|
17
|
+
# def add_to_source( source )
|
18
|
+
# return if @source == source or source.nil?
|
19
|
+
# @source = source
|
20
|
+
# source.add_target( self )
|
21
|
+
# end
|
22
|
+
define_method( "add_to_#{name}" ) do |source,|
|
23
|
+
# return if the target already belongs to
|
24
|
+
# the given source or if the source is nil.
|
25
|
+
return if ivget( name ) == source or source.nil?
|
26
|
+
|
27
|
+
# add source and send a message to source
|
28
|
+
# to add self as target.
|
29
|
+
ivset( name, source )
|
30
|
+
source.send( "add_#{update}", self )
|
31
|
+
end
|
32
|
+
|
33
|
+
# Set or remove source.
|
34
|
+
# def source=( source )
|
35
|
+
# return remove_from_source if source.nil?
|
36
|
+
# return add_to_source( self )
|
37
|
+
# end
|
38
|
+
define_method( "#{name}=" ) do |source,|
|
39
|
+
return send( "remove_from_#{name}" ) if source.nil?
|
40
|
+
return send( "add_to_#{name}", source )
|
41
|
+
end
|
42
|
+
|
43
|
+
# Remove this target from an existing source.
|
44
|
+
# def remove_from_source
|
45
|
+
# return unless source = @source
|
46
|
+
# @source = nil
|
47
|
+
# source.delete_target( self )
|
48
|
+
# end
|
49
|
+
define_method( "remove_from_#{name}" ) do
|
50
|
+
# return if a sourc is not set.
|
51
|
+
return unless source = ivget( name )
|
52
|
+
|
53
|
+
# remove source and send a message to source
|
54
|
+
# to remove itself as target.
|
55
|
+
ivset( name, nil )
|
56
|
+
source.send( "delete_#{update}", self )
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Define target set for the source.
|
61
|
+
# has_n :otu
|
62
|
+
def has_n( target, options = {} )
|
63
|
+
name = ( options[ :singularize ] == false ) ? target.to_s : target.to_s.singular
|
64
|
+
type = ( options[ :index ] == false ) ? ArrayRepository : HashRepository
|
65
|
+
update = ( options[ :update ] || self.name.key ).to_sym
|
66
|
+
|
67
|
+
# Return an Array of targets.
|
68
|
+
# def targets
|
69
|
+
# @targets.objects
|
70
|
+
# end
|
71
|
+
define_method( target ) do
|
72
|
+
repository( target, type ).objects
|
73
|
+
end
|
74
|
+
|
75
|
+
# Set an Array as a target.
|
76
|
+
# def targets=( targets )
|
77
|
+
# @targets.clear
|
78
|
+
# targets.each do |t|
|
79
|
+
# add_target( t )
|
80
|
+
# end
|
81
|
+
# end
|
82
|
+
define_method( "#{target}=" ) do |objects,|
|
83
|
+
repository( target, type ).clear
|
84
|
+
objects.each do |o|
|
85
|
+
send( "add_#{name}", o )
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Add a target.
|
90
|
+
# def add_target( target )
|
91
|
+
# return if @targets.include?( target )
|
92
|
+
# @targets.append( target )
|
93
|
+
# target.source = self
|
94
|
+
# end
|
95
|
+
define_method( "add_#{name}" ) do |object,|
|
96
|
+
repository = repository( target, type )
|
97
|
+
return if repository.include?( object )
|
98
|
+
repository.append( object )
|
99
|
+
object.send( "#{update}=", self )
|
100
|
+
self
|
101
|
+
end
|
102
|
+
|
103
|
+
# Delete a target.
|
104
|
+
# def delete_target( target )
|
105
|
+
# return unless @targets.include?( target )
|
106
|
+
# return unless deleted = @targets.delete( target )
|
107
|
+
# target.source = nil
|
108
|
+
# end
|
109
|
+
define_method( "delete_#{name}" ) do |object,|
|
110
|
+
repository = repository( target, type )
|
111
|
+
return unless deleted = repository.delete( object )
|
112
|
+
object.send( "#{update}=", nil )
|
113
|
+
deleted
|
114
|
+
end
|
115
|
+
|
116
|
+
# Return the number of targets a source has.
|
117
|
+
# def number_of_targets
|
118
|
+
# @targets.length
|
119
|
+
# end
|
120
|
+
define_method( "number_of_#{target}" ) do
|
121
|
+
repository( target, type ).length
|
122
|
+
end
|
123
|
+
|
124
|
+
# Return true if the source has the given target.
|
125
|
+
# def has_target?( target )
|
126
|
+
# @targets.include?( target )
|
127
|
+
# end
|
128
|
+
define_method( "has_#{name}?" ) do |object,|
|
129
|
+
repository( target, type ).include?( object )
|
130
|
+
end
|
131
|
+
|
132
|
+
# Iterate over each target.
|
133
|
+
# def each( &block )
|
134
|
+
# @targets.each( &block )
|
135
|
+
# end
|
136
|
+
class_eval <<_END_OF_EVAL_
|
137
|
+
def each_#{name}( &block )
|
138
|
+
repository( "#{target}", #{type} ).each( &block )
|
139
|
+
end
|
140
|
+
_END_OF_EVAL_
|
141
|
+
|
142
|
+
if type == HashRepository
|
143
|
+
define_method( "get_#{name}_by_id" ) do |id,|
|
144
|
+
repository( target, type )[ id ]
|
145
|
+
end
|
146
|
+
class_eval <<_END_OF_EVAL_
|
147
|
+
def each_#{name}_with_id( &block )
|
148
|
+
repository( #{target }, #{type } ).each_with_id( &block )
|
149
|
+
end
|
150
|
+
_END_OF_EVAL_
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
end #end module Framework
|
155
|
+
end #end module Mapper
|
156
|
+
end #end module NeXML
|
157
|
+
end #end module Mapper
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Bio
|
2
|
+
module NeXML
|
3
|
+
module Mapper # :nodoc:
|
4
|
+
|
5
|
+
# String inflections. This module is mixed with the String class.
|
6
|
+
#
|
7
|
+
# "targets".singular #=> "target"
|
8
|
+
# "target".plural #=> "targets"
|
9
|
+
# "Bio::NeXML::Otu".key #=> "otu"
|
10
|
+
module Inflections
|
11
|
+
PLURALS =
|
12
|
+
[
|
13
|
+
[ /$/, 's' ],
|
14
|
+
[ /s$/i, 's' ],
|
15
|
+
[ /(ax|test)is$/i, '\1es' ],
|
16
|
+
[ /(octop|vir)us$/i, '\1i' ],
|
17
|
+
[ /(alias|status)$/i, '\1es' ],
|
18
|
+
[ /(bu)s$/i, '\1ses' ],
|
19
|
+
[ /(buffal|tomat)o$/i, '\1oes' ],
|
20
|
+
[ /([ti])um$/i, '\1a' ],
|
21
|
+
[ /sis$/i, 'ses' ],
|
22
|
+
[ /(?:([^f])fe|([lr])f)$/i, '\1\2ves' ],
|
23
|
+
[ /(hive)$/i, '\1s' ],
|
24
|
+
[ /([^aeiouy]|qu)y$/i, '\1ies' ],
|
25
|
+
[ /(x|ch|ss|sh)$/i, '\1es' ],
|
26
|
+
[ /(matr|vert|ind)(?:ix|ex)$/i, '\1ices' ],
|
27
|
+
[ /([m|l])ouse$/i, '\1ice' ],
|
28
|
+
[ /^(ox)$/i, '\1en' ],
|
29
|
+
[ /(quiz)$/i, '\1zes' ]
|
30
|
+
]
|
31
|
+
|
32
|
+
SINGULARS =
|
33
|
+
[
|
34
|
+
[ /s$/i, '' ],
|
35
|
+
[ /(n)ews$/i, '\1ews' ],
|
36
|
+
[ /([ti])a$/i, '\1um' ],
|
37
|
+
[ /((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis' ],
|
38
|
+
[ /(^analy)ses$/i, '\1sis' ],
|
39
|
+
[ /([^f])ves$/i, '\1fe' ],
|
40
|
+
[ /(hive)s$/i, '\1' ],
|
41
|
+
[ /(tive)s$/i, '\1' ],
|
42
|
+
[ /([lr])ves$/i, '\1f' ],
|
43
|
+
[ /([^aeiouy]|qu)ies$/i, '\1y' ],
|
44
|
+
[ /(s)eries$/i, '\1eries' ],
|
45
|
+
[ /(m)ovies$/i, '\1ovie' ],
|
46
|
+
[ /(x|ch|ss|sh)es$/i, '\1' ],
|
47
|
+
[ /([m|l])ice$/i, '\1ouse' ],
|
48
|
+
[ /(bus)es$/i, '\1' ],
|
49
|
+
[ /(o)es$/i, '\1' ],
|
50
|
+
[ /(shoe)s$/i, '\1' ],
|
51
|
+
[ /(cris|ax|test)es$/i, '\1is' ],
|
52
|
+
[ /(octop|vir)i$/i, '\1us' ],
|
53
|
+
[ /(alias|status)es$/i, '\1' ],
|
54
|
+
[ /^(ox)en/i, '\1' ],
|
55
|
+
[ /(vert|ind)ices$/i, '\1ex' ],
|
56
|
+
[ /(matr)ices$/i, '\1ix' ],
|
57
|
+
[ /(quiz)zes$/i, '\1' ],
|
58
|
+
[ /(database)s$/i, '\1' ]
|
59
|
+
]
|
60
|
+
|
61
|
+
# Return the singular form of string.
|
62
|
+
def singular
|
63
|
+
result = self.dup
|
64
|
+
SINGULARS.each do |match, replace|
|
65
|
+
rule = Regexp.compile( match )
|
66
|
+
unless match( rule ).nil?
|
67
|
+
result = gsub( rule, replace)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
return result
|
71
|
+
end
|
72
|
+
|
73
|
+
# Return the plural form of a string.
|
74
|
+
def plural
|
75
|
+
result = self.dup
|
76
|
+
PLURALS.each do |match_exp, replacement_exp|
|
77
|
+
unless match(Regexp.compile(match_exp)).nil?
|
78
|
+
result = gsub(Regexp.compile(match_exp), replacement_exp)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
return result
|
82
|
+
end
|
83
|
+
|
84
|
+
# For a module name as "Bio::NeXML" return "nexml".
|
85
|
+
def key
|
86
|
+
result = self.dup
|
87
|
+
if i = rindex( ':' )
|
88
|
+
result = self[ i + 1 .. -1 ]
|
89
|
+
end
|
90
|
+
result.downcase
|
91
|
+
end
|
92
|
+
end # end module Inflections
|
93
|
+
|
94
|
+
String.class_eval do
|
95
|
+
include Inflections
|
96
|
+
end
|
97
|
+
end #end module Mapper
|
98
|
+
end #end module NeXML
|
99
|
+
end #end module Bio
|