cardname 0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 15f37bd2c96222cfff562f06782c52e27a803dc0
4
+ data.tar.gz: 86752b10ed33282d3cafa93eaca1320aea1e8e94
5
+ SHA512:
6
+ metadata.gz: d66817487594c22c30d7f1374c53711312c6d314609ec0d34ac8724def65bb7e853f1a5ce5e29a03aec902b4c28d136d535b2cbae2e87d7fa069575139ed8fdf
7
+ data.tar.gz: a3867d0234a9f27360e3bcf47328c5ff1380066b1af3ffad1487578796c0f6a47f14b5008d970d87b3ae3697fb12c86ebeafc8753d19cf13f9178437b416e498
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Add dependencies to develop your gem here.
4
+ # Include everything needed to run rake, tests, features, etc.
5
+ group :development do
6
+ gem "rspec"
7
+ gem "rdoc"
8
+ gem "bundler"
9
+ gem "jeweler"
10
+ #gem "rcov"
11
+ end
12
+
13
+ gem "activesupport"
14
+ gem 'htmlentities'
data/Gemfile.lock ADDED
@@ -0,0 +1,91 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (5.0.1)
5
+ concurrent-ruby (~> 1.0, >= 1.0.2)
6
+ i18n (~> 0.7)
7
+ minitest (~> 5.1)
8
+ tzinfo (~> 1.1)
9
+ addressable (2.5.0)
10
+ public_suffix (~> 2.0, >= 2.0.2)
11
+ builder (3.2.3)
12
+ concurrent-ruby (1.0.4)
13
+ descendants_tracker (0.0.4)
14
+ thread_safe (~> 0.3, >= 0.3.1)
15
+ diff-lcs (1.3)
16
+ faraday (0.9.2)
17
+ multipart-post (>= 1.2, < 3)
18
+ git (1.3.0)
19
+ github_api (0.11.3)
20
+ addressable (~> 2.3)
21
+ descendants_tracker (~> 0.0.1)
22
+ faraday (~> 0.8, < 0.10)
23
+ hashie (>= 1.2)
24
+ multi_json (>= 1.7.5, < 2.0)
25
+ nokogiri (~> 1.6.0)
26
+ oauth2
27
+ hashie (3.5.4)
28
+ highline (1.7.8)
29
+ htmlentities (4.3.4)
30
+ i18n (0.8.1)
31
+ jeweler (2.3.3)
32
+ builder
33
+ bundler (>= 1.0)
34
+ git (>= 1.2.5)
35
+ github_api (~> 0.11.0)
36
+ highline (>= 1.6.15)
37
+ nokogiri (>= 1.5.10)
38
+ psych (~> 2.2)
39
+ rake
40
+ rdoc
41
+ semver2
42
+ jwt (1.5.6)
43
+ mini_portile2 (2.1.0)
44
+ minitest (5.10.1)
45
+ multi_json (1.12.1)
46
+ multi_xml (0.6.0)
47
+ multipart-post (2.0.0)
48
+ nokogiri (1.6.8.1)
49
+ mini_portile2 (~> 2.1.0)
50
+ oauth2 (1.3.0)
51
+ faraday (>= 0.8, < 0.11)
52
+ jwt (~> 1.0)
53
+ multi_json (~> 1.3)
54
+ multi_xml (~> 0.5)
55
+ rack (>= 1.2, < 3)
56
+ psych (2.2.4)
57
+ public_suffix (2.0.5)
58
+ rack (2.0.1)
59
+ rake (12.0.0)
60
+ rdoc (5.1.0)
61
+ rspec (3.5.0)
62
+ rspec-core (~> 3.5.0)
63
+ rspec-expectations (~> 3.5.0)
64
+ rspec-mocks (~> 3.5.0)
65
+ rspec-core (3.5.4)
66
+ rspec-support (~> 3.5.0)
67
+ rspec-expectations (3.5.0)
68
+ diff-lcs (>= 1.2.0, < 2.0)
69
+ rspec-support (~> 3.5.0)
70
+ rspec-mocks (3.5.0)
71
+ diff-lcs (>= 1.2.0, < 2.0)
72
+ rspec-support (~> 3.5.0)
73
+ rspec-support (3.5.0)
74
+ semver2 (3.4.2)
75
+ thread_safe (0.3.6)
76
+ tzinfo (1.2.2)
77
+ thread_safe (~> 0.1)
78
+
79
+ PLATFORMS
80
+ ruby
81
+
82
+ DEPENDENCIES
83
+ activesupport
84
+ bundler
85
+ htmlentities
86
+ jeweler
87
+ rdoc
88
+ rspec
89
+
90
+ BUNDLED WITH
91
+ 1.12.5
data/README.rdoc ADDED
@@ -0,0 +1,7 @@
1
+
2
+ == Cardname
3
+
4
+ Wiki Segmented Name Logic
5
+
6
+ == Abstract
7
+
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+
2
+ # encoding: utf-8
3
+
4
+ require 'rubygems'
5
+ require 'bundler'
6
+
7
+ VERSION = File.exist?('VERSION') ? File.read('VERSION') : ""
8
+
9
+ begin
10
+ Bundler.setup(:default, :development)
11
+ rescue Bundler::BundlerError => e
12
+ $stderr.puts e.message
13
+ $stderr.puts "Run `bundle install` to install missing gems"
14
+ exit e.status_code
15
+ end
16
+
17
+ require 'rake'
18
+
19
+ require 'rspec/core'
20
+ require 'rspec/core/rake_task'
21
+ RSpec::Core::RakeTask.new(:spec) do |spec|
22
+ spec.pattern = FileList['spec/**/*_spec.rb']
23
+ end
24
+
25
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
26
+ spec.pattern = 'spec/**/*_spec.rb'
27
+ spec.rcov = true
28
+ end
29
+
30
+ task :default => :spec
31
+
32
+ require 'rdoc/task'
33
+ Rake::RDocTask.new do |rdoc|
34
+
35
+ rdoc.rdoc_dir = 'rdoc'
36
+ rdoc.title = "cardname #{VERSION}"
37
+ rdoc.rdoc_files.include('README*')
38
+ rdoc.rdoc_files.include('lib/**/*.rb')
39
+ end
@@ -0,0 +1,114 @@
1
+ class Cardname
2
+ module Contextual
3
+ RELATIVE_REGEXP = /\b_(left|right|whole|self|user|main|\d+|L*R?)\b/
4
+
5
+ def relative_name context_name
6
+ to_show(*context_name.to_name.parts).to_name
7
+ end
8
+
9
+ def absolute_name context_name
10
+ to_absolute_name(context_name)
11
+ end
12
+
13
+ # @return true if name is left or right of context
14
+ def child_of? context
15
+ return false unless junction?
16
+ context_key = context.to_name.key
17
+ absolute_name(context).parent_keys.include? context_key
18
+ end
19
+
20
+ def relative?
21
+ s =~ RELATIVE_REGEXP || starts_with_joint?
22
+ end
23
+
24
+ def simple_relative?
25
+ relative? && stripped.to_name.starts_with_joint?
26
+ end
27
+
28
+ def absolute?
29
+ !relative?
30
+ end
31
+
32
+ def stripped
33
+ s.gsub RELATIVE_REGEXP, ""
34
+ end
35
+
36
+ def starts_with_joint?
37
+ length >= 2 && parts.first.empty?
38
+ end
39
+
40
+ def to_show *ignore
41
+ ignore.map!(&:to_name)
42
+
43
+ show_parts = parts.map do |part|
44
+ reject = (part.empty? || (part =~ /^_/) || ignore.member?(part.to_name))
45
+ reject ? nil : part
46
+ end
47
+
48
+ show_name = show_parts.compact.to_name.s
49
+
50
+ case
51
+ when show_parts.compact.empty? then self
52
+ when show_parts[0].nil? then self.class.joint + show_name
53
+ else show_name
54
+ end
55
+ end
56
+
57
+ def to_absolute context, args={}
58
+ context = context.to_name
59
+
60
+ new_parts = replace_contextual_parts context
61
+ return "" if new_parts.empty?
62
+
63
+ if new_parts.first.empty? && !new_parts.to_name.starts_with?(context)
64
+ new_parts[0] = context.to_s
65
+ end
66
+ if new_parts.last.empty? && !new_parts.to_name.ends_with?(context)
67
+ new_parts[-1] = context.to_s
68
+ end
69
+ new_parts.join self.class.joint
70
+ end
71
+
72
+ def to_absolute_name *args
73
+ self.class.new to_absolute(*args)
74
+ end
75
+
76
+ def nth_left n
77
+ # 1 = left; 2= left of left; 3 = left of left of left....
78
+ (n >= length ? parts[0] : parts[0..-n - 1]).to_name
79
+ end
80
+
81
+ private
82
+
83
+ def replace_contextual_parts context
84
+ parts.map do |part|
85
+ new_part =
86
+ case part
87
+ when /^_user$/i
88
+ name_proc = self.class.session
89
+ name_proc ? name_proc.call : part
90
+ when /^_main$/i then self.class.params[:main_name]
91
+ when /^(_self|_whole|_)$/i then context.s
92
+ when /^_left$/i then context.trunk
93
+ # note - inconsistent use of left v. trunk
94
+ when /^_right$/i then context.tag
95
+ when /^_(\d+)$/i
96
+ pos = $~[1].to_i
97
+ pos = context.length if pos > context.length
98
+ context.parts[pos - 1]
99
+ when /^_(L*)(R?)$/i
100
+ l_s, r_s = $~[1].size, !$~[2].empty?
101
+ l_part = context.nth_left l_s
102
+ r_s ? l_part.tag : l_part.s
103
+ # when /^_/
104
+ # custom = args[:params] ? args[:params][part] : nil
105
+ # custom ? CGI.escapeHTML(custom) : part
106
+ # why are we escaping HTML here?
107
+ else
108
+ part
109
+ end.to_s.strip
110
+ new_part
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,73 @@
1
+ class Cardname
2
+ module Manipulate
3
+ # replace a subname
4
+ # keys are used for comparison
5
+ def replace old, new
6
+ old_name = old.to_name
7
+ new_name = new.to_name
8
+ return self if old_name.length > length
9
+ return replace_part(old_name, new_name) if old_name.simple?
10
+ return self unless include? old_name
11
+ replace_all_subsequences(old_name, new_name).to_name
12
+ end
13
+
14
+ def replace_part oldpart, newpart
15
+ ensure_simpliness oldpart, "Use 'replace' to replace junctions"
16
+
17
+ oldpart = oldpart.to_name
18
+ newpart = newpart.to_name
19
+
20
+ parts.map do |p|
21
+ oldpart == p ? newpart : p
22
+ end.to_name
23
+ end
24
+
25
+ def replace_piece oldpiece, newpiece
26
+ oldpiece = oldpiece.to_name
27
+ newpiece = newpiece.to_name
28
+
29
+ return replace_part oldpiece, newpiece if oldpiece.simple?
30
+ return self unless self.starts_with?(oldpiece)
31
+ return newpiece if oldpiece.length == length
32
+ newpiece + self[oldpiece.length..-1]
33
+ end
34
+
35
+ private
36
+
37
+ def replace_all_subsequences oldseq, newseq
38
+ res = []
39
+ i = 0
40
+ while i <= length - oldseq.length
41
+ # for performance reasons: check first character first then the rest
42
+ if oldseq.part_keys.first == part_keys[i] &&
43
+ oldseq.part_keys == part_keys[i, oldseq.length]
44
+ res += newseq.parts
45
+ i += oldseq.length
46
+ else
47
+ res << parts[i]
48
+ i += 1
49
+ end
50
+ end
51
+ res += parts[i..-1] if i < length
52
+ res
53
+ end
54
+
55
+ def ensure_simpliness part, msg=nil
56
+ return if part.to_name.simple?
57
+ raise StandardError, "'#{part}' has to be simple. #{msg}"
58
+ end
59
+ end
60
+
61
+ # ~~~~~~~~~~~~~~~~~~~~ MISC ~~~~~~~~~~~~~~~~~~~~
62
+
63
+ # HACK. This doesn't belong here.
64
+ # shouldn't it use inclusions???
65
+ def self.substitute! str, hash
66
+ hash.keys.each do |var|
67
+ str.gsub! var_re do |x|
68
+ hash[var.to_sym]
69
+ end
70
+ end
71
+ str
72
+ end
73
+ end
@@ -0,0 +1,126 @@
1
+ class Cardname
2
+ # naming conventions:
3
+ # methods that end with _name return name objects
4
+ # the same methods without _name return strings
5
+ module Parts
6
+ attr_reader :parts, :part_keys, :simple
7
+
8
+ alias simple? simple
9
+ alias_method :to_a, :parts
10
+
11
+ def initialize_parts
12
+ # -1 = don't suppress trailing null fields
13
+ @parts = @s.split(/\s*#{JOINT_RE}\s*/, -1)
14
+ @simple = @parts.size <= 1
15
+ # simple check needed to avoid inifinite recursion
16
+ @part_keys =
17
+ @simple ? [simple_key] : @parts.map { |p| p.to_name.simple_key }
18
+ end
19
+
20
+ def left
21
+ @left ||= simple? ? nil : parts[0..-2] * self.class.joint
22
+ end
23
+
24
+ def right
25
+ @right ||= simple? ? nil : parts[-1]
26
+ end
27
+
28
+ def left_name
29
+ @left_name ||= left && self.class.new(left)
30
+ end
31
+
32
+ def right_name
33
+ @right_name ||= right && self.class.new(right)
34
+ end
35
+
36
+ def left_key
37
+ @left_key ||= simple? ? nil : part_keys[0..-2] * self.class.joint
38
+ end
39
+
40
+ def right_key
41
+ @right_key ||= simple? ? nil : part_keys.last
42
+ end
43
+
44
+ def parents
45
+ @parents ||= junction? ? [left, right] : []
46
+ end
47
+
48
+ def parent_names
49
+ @parent_names ||= junction? ? [left_name, right_name] : []
50
+ end
51
+
52
+ def parent_keys
53
+ @parent_keys ||= junction? ? [left_key, right_key] : []
54
+ end
55
+
56
+ # Note that all names have a trunk and tag,
57
+ # but only junctions have left and right
58
+
59
+ def trunk
60
+ @trunk ||= simple? ? s : left
61
+ end
62
+
63
+ def tag
64
+ @tag ||= simple? ? s : right
65
+ end
66
+
67
+ def trunk_name
68
+ @trunk_name ||= simple? ? self : left_name
69
+ end
70
+
71
+ def tag_name
72
+ @tag_name ||= simple? ? self : right_name
73
+ end
74
+
75
+ def part_names
76
+ @part_names ||= parts.map(&:to_name)
77
+ end
78
+
79
+ def piece_names
80
+ @piece_names ||= pieces.map(&:to_name)
81
+ end
82
+
83
+ # self and all ancestors (= parts and recursive lefts)
84
+ # @example
85
+ # "A+B+C+D".to_name.pieces
86
+ # # => ["A", "B", "C", "D", "A+B", "A+B+C", "A+B+C+D"]
87
+ def pieces
88
+ @pieces ||=
89
+ if simple?
90
+ [self]
91
+ else
92
+ junction_pieces = []
93
+ parts[1..-1].inject parts[0] do |left, right|
94
+ piece = [left, right] * self.class.joint
95
+ junction_pieces << piece
96
+ piece
97
+ end
98
+ parts + junction_pieces
99
+ end
100
+ end
101
+
102
+ def + other
103
+ self.class.new(parts + other.to_name.parts)
104
+ end
105
+
106
+ def [] *args
107
+ self.class.new parts[*args]
108
+ end
109
+
110
+ # full support of array methods caused trouble with `flatten` calls
111
+ # It splits the parts of cardnames in arrays
112
+ # # name parts can be accessed and manipulated like an array
113
+ # def method_missing method, *args, &block
114
+ # if ARRAY_METHODS.include? method # parts.respond_to?(method)
115
+ # self.class.new parts.send(method, *args, &block)
116
+ # else
117
+ # super
118
+ # end
119
+ # end
120
+ #
121
+ # def respond_to? method, include_private=false
122
+ # return true if ARRAY_METHODS.include? method
123
+ # super || parts.respond_to?(method, include_private)
124
+ # end
125
+ end
126
+ end
@@ -0,0 +1,39 @@
1
+ class Cardname
2
+ module Predicates
3
+ # @return true if name has more than one part
4
+ def junction?
5
+ !simple?
6
+ end
7
+
8
+ def blank?
9
+ s.blank?
10
+ end
11
+ alias empty? blank?
12
+
13
+ def valid?
14
+ !parts.find do |pt|
15
+ pt.match self.class.banned_re
16
+ end
17
+ end
18
+
19
+ # @return true if name starts with the same parts as `prefix`
20
+ def starts_with? prefix
21
+ start_name = prefix.to_name
22
+ start_name == self[0, start_name.length]
23
+ end
24
+ alias_method :start_with?, :starts_with?
25
+
26
+ # @return true if name ends with the same parts as `prefix`
27
+ def ends_with? postfix
28
+ end_name = postfix.to_name
29
+ end_name == self[-end_name.length..-1]
30
+ end
31
+ alias_method :end_with?, :ends_with?
32
+
33
+ # @return true if name has a chain of parts that equals `subname`
34
+ def include? subname
35
+ subkey = subname.to_name.key
36
+ key =~ /(^|#{JOINT_RE})#{Regexp.quote subkey}($|#{JOINT_RE})/
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,36 @@
1
+ class Cardname
2
+ module Variants
3
+ def simple_key
4
+ return "" if @s.empty?
5
+ decoded
6
+ .underscore
7
+ .gsub(/[^#{OK4KEY_RE}]+/, '_')
8
+ .split(/_+/)
9
+ .reject(&:empty?)
10
+ .map { |key| Cardname.stable_uninflect(key) }
11
+ .join('_')
12
+ end
13
+
14
+ def url_key
15
+ @url_key ||= part_names.map do |part_name|
16
+ stripped = part_name.decoded.gsub(/[^#{OK4KEY_RE}]+/, ' ').strip
17
+ stripped.gsub(/[\s\_]+/, '_')
18
+ end * self.class.joint
19
+ end
20
+
21
+ # safe to be used in HTML as id ('*' and '+' are not allowed),
22
+ # but the key is no longer unique.
23
+ # For example "A-XB" and "A+*B" have the same safe_key
24
+ def safe_key
25
+ @safe_key ||= key.tr('*', 'X').tr self.class.joint, '-'
26
+ end
27
+
28
+ def decoded
29
+ @decoded ||= s.index('&') ? HTMLEntities.new.decode(s) : s
30
+ end
31
+
32
+ def to_sym
33
+ s.to_sym
34
+ end
35
+ end
36
+ end
data/lib/cardname.rb ADDED
@@ -0,0 +1,114 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ require 'active_support/configurable'
4
+ require 'active_support/inflector'
5
+ require 'htmlentities'
6
+ require_relative 'cardname/parts'
7
+ require_relative 'cardname/variants'
8
+ require_relative 'cardname/contextual'
9
+ require_relative 'cardname/predicates'
10
+ require_relative 'cardname/manipulate'
11
+
12
+ class Cardname < Object
13
+
14
+ include Parts
15
+ include Variants
16
+ include Contextual
17
+ include Predicates
18
+ include Manipulate
19
+
20
+ RUBYENCODING = RUBY_VERSION !~ /^1\.8/
21
+ OK4KEY_RE = RUBYENCODING ? '\p{Word}\*' : '\w\*'
22
+
23
+ include ActiveSupport::Configurable
24
+
25
+ config_accessor :joint, :banned_array, :var_re, :uninflect, :params,
26
+ :session, :stabilize
27
+
28
+ Cardname.joint = '+'
29
+ Cardname.banned_array = ['/', '~', '|']
30
+ Cardname.var_re = /\{([^\}]*\})\}/
31
+ Cardname.uninflect = :singularize
32
+ Cardname.stabilize = false
33
+
34
+ JOINT_RE = Regexp.escape joint
35
+
36
+ @@name2nameobject = {} # name cache
37
+
38
+ class << self
39
+ def new obj
40
+ return obj if obj.is_a? self.class
41
+ str = stringify obj
42
+ known_name(str) || super(str.strip)
43
+ end
44
+
45
+ def known_name str
46
+ @@name2nameobject[str]
47
+ end
48
+
49
+ def stringify obj
50
+ if obj.is_a?(Array)
51
+ obj.map(&:to_s) * joint
52
+ else
53
+ obj.to_s
54
+ end
55
+ end
56
+
57
+ def banned_re
58
+ %r{#{ (['['] + banned_array << joint) * '\\' + ']' }}
59
+ end
60
+
61
+ # Sometimes the core rule "the key's key must be itself" (called "stable" below) is violated
62
+ # eg. it fails with singularize as uninflect method for Matthias -> Matthia -> Matthium
63
+ # Usually that means the name is a proper noun and not a plural.
64
+ # You can choose between two solutions:
65
+ # 1. don't uninflect if the uninflected key is not stable (stabilize = false)
66
+ # (probably the best choice because you want Matthias not to be the same as Matthium)
67
+ # 2. uninflect until the key is stable (stabilize = true)
68
+ def stable_uninflect name
69
+ key_one = name.send(Cardname.uninflect)
70
+ key_two = key_one.send(Cardname.uninflect)
71
+ return key_one unless key_one != key_two
72
+ Cardname.stabilize ? stable_uninflect(key_two) : name
73
+ end
74
+ end
75
+
76
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
77
+ # ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~
78
+ attr_reader :key, :s
79
+ alias to_s s
80
+
81
+ def initialize str
82
+ @s = str.to_s.strip
83
+ @s = @s.encode('UTF-8') if RUBYENCODING
84
+ initialize_parts
85
+ @key = @part_keys.join(self.class.joint)
86
+ @@name2nameobject[str] = self
87
+ end
88
+
89
+ def to_name
90
+ self
91
+ end
92
+
93
+ def length
94
+ parts.length
95
+ end
96
+
97
+ def size
98
+ to_s.size
99
+ end
100
+
101
+ def inspect
102
+ "<#{self.class.name} key=#{key}[#{self}]>"
103
+ end
104
+
105
+ def == other
106
+ other_key =
107
+ case
108
+ when other.respond_to?(:key) then other.key
109
+ when other.respond_to?(:to_name) then other.to_name.key
110
+ else other.to_s
111
+ end
112
+ other_key == key
113
+ end
114
+ end
data/lib/core_ext.rb ADDED
@@ -0,0 +1,5 @@
1
+ class Object
2
+ def to_name
3
+ Cardname.new self
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cardname
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Gerry Gleason
8
+ - Ethan McCutchen
9
+ - Philipp Kühl
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2017-08-02 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: '5.1'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '5.1'
29
+ - !ruby/object:Gem::Dependency
30
+ name: htmlentities
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '4.3'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '4.3'
43
+ description: Naming patterns abstracted from Decko cards
44
+ email: info@decko.org
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files:
48
+ - README.rdoc
49
+ files:
50
+ - Gemfile
51
+ - Gemfile.lock
52
+ - README.rdoc
53
+ - Rakefile
54
+ - lib/cardname.rb
55
+ - lib/cardname/contextual.rb
56
+ - lib/cardname/manipulate.rb
57
+ - lib/cardname/parts.rb
58
+ - lib/cardname/predicates.rb
59
+ - lib/cardname/variants.rb
60
+ - lib/core_ext.rb
61
+ homepage: http://decko.org
62
+ licenses:
63
+ - GPL-2.0
64
+ - GPL-3.0
65
+ metadata: {}
66
+ post_install_message:
67
+ rdoc_options:
68
+ - "--main"
69
+ - README.rdoc
70
+ - "--inline-source"
71
+ - "--line-numbers"
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 2.6.6
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: Card names without all the cards
90
+ test_files: []