cardname 0.11.0 → 0.11.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.
- checksums.yaml +4 -4
- data/Rakefile +16 -18
- data/lib/cardname.rb +4 -4
- data/lib/cardname/contextual.rb +23 -13
- data/lib/cardname/manipulate.rb +3 -0
- data/lib/cardname/parts.rb +4 -35
- data/lib/cardname/pieces.rb +26 -0
- data/lib/cardname/predicates.rb +12 -0
- data/lib/cardname/variants.rb +7 -6
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e0d301d80ce8422ca4aeb9bf8ce2307dc57d81a9629206bf660f5ebebd63474
|
4
|
+
data.tar.gz: a52dd72d962a26173c028a0c52e55988853dfd59a810ab6a8e46cf174ef3cd8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b9de9bf4b55d4a40ac188f8150f421f4d3ee8267b5a4eea07742842645853e8fa0360bec8dbd0ca3aa2581ad6512f8dfa596c9bb2c016bcb25b7f158ff4b6a3
|
7
|
+
data.tar.gz: 534c1e4c669960e45e445a074a0c380ba9a2212f83807ede593b09c7fc132a1b0ac2e97f5e3c3be692912aeaf1a7f03dc809d235f96dff3548b17a654bf90c3d
|
data/Rakefile
CHANGED
@@ -1,39 +1,37 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
|
2
|
-
|
3
|
+
require "rubygems"
|
4
|
+
require "bundler"
|
3
5
|
|
4
|
-
|
5
|
-
require 'bundler'
|
6
|
-
|
7
|
-
VERSION = File.exist?('VERSION') ? File.read('VERSION') : ""
|
6
|
+
VERSION = File.exist?("VERSION") ? File.read("VERSION") : ""
|
8
7
|
|
9
8
|
begin
|
10
9
|
Bundler.setup(:default, :development)
|
11
10
|
rescue Bundler::BundlerError => e
|
12
|
-
|
13
|
-
|
11
|
+
warn e.message
|
12
|
+
warn "Run `bundle install` to install missing gems"
|
14
13
|
exit e.status_code
|
15
14
|
end
|
16
15
|
|
17
|
-
require
|
16
|
+
require "rake"
|
18
17
|
|
19
|
-
require
|
20
|
-
require
|
18
|
+
require "rspec/core"
|
19
|
+
require "rspec/core/rake_task"
|
21
20
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
22
|
-
spec.pattern = FileList[
|
21
|
+
spec.pattern = FileList["spec/**/*_spec.rb"]
|
23
22
|
end
|
24
23
|
|
25
24
|
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
26
|
-
spec.pattern =
|
25
|
+
spec.pattern = "spec/**/*_spec.rb"
|
27
26
|
spec.rcov = true
|
28
27
|
end
|
29
28
|
|
30
|
-
task :
|
29
|
+
task default: :spec
|
31
30
|
|
32
|
-
require
|
31
|
+
require "rdoc/task"
|
33
32
|
Rake::RDocTask.new do |rdoc|
|
34
|
-
|
35
|
-
rdoc.rdoc_dir = 'rdoc'
|
33
|
+
rdoc.rdoc_dir = "rdoc"
|
36
34
|
rdoc.title = "cardname #{VERSION}"
|
37
|
-
rdoc.rdoc_files.include(
|
38
|
-
rdoc.rdoc_files.include(
|
35
|
+
rdoc.rdoc_files.include("README*")
|
36
|
+
rdoc.rdoc_files.include("lib/**/*.rb")
|
39
37
|
end
|
data/lib/cardname.rb
CHANGED
@@ -5,12 +5,14 @@ require "htmlentities"
|
|
5
5
|
|
6
6
|
class Cardname < String
|
7
7
|
require_relative "cardname/parts"
|
8
|
+
require_relative "cardname/pieces"
|
8
9
|
require_relative "cardname/variants"
|
9
10
|
require_relative "cardname/contextual"
|
10
11
|
require_relative "cardname/predicates"
|
11
12
|
require_relative "cardname/manipulate"
|
12
13
|
|
13
14
|
include Parts
|
15
|
+
include Pieces
|
14
16
|
include Variants
|
15
17
|
include Contextual
|
16
18
|
include Predicates
|
@@ -18,12 +20,11 @@ class Cardname < String
|
|
18
20
|
|
19
21
|
OK4KEY_RE = '\p{Word}\*'
|
20
22
|
|
21
|
-
cattr_accessor :joint, :banned_array, :var_re, :uninflect, :params,
|
22
|
-
:session, :stabilize
|
23
|
+
cattr_accessor :joint, :banned_array, :var_re, :uninflect, :params, :session, :stabilize
|
23
24
|
|
24
25
|
self.joint = "+"
|
25
26
|
self.banned_array = []
|
26
|
-
self.var_re = /\{([
|
27
|
+
self.var_re = /\{([^}]*\})\}/
|
27
28
|
self.uninflect = :singularize
|
28
29
|
self.stabilize = false
|
29
30
|
|
@@ -116,7 +117,6 @@ class Cardname < String
|
|
116
117
|
end
|
117
118
|
end
|
118
119
|
|
119
|
-
# dangerous, too
|
120
120
|
def []= index, val
|
121
121
|
p = parts
|
122
122
|
p[index] = val
|
data/lib/cardname/contextual.rb
CHANGED
@@ -4,7 +4,8 @@ class Cardname
|
|
4
4
|
|
5
5
|
# @return true if name is left or right of context
|
6
6
|
def child_of? context
|
7
|
-
return false unless
|
7
|
+
return false unless compound?
|
8
|
+
|
8
9
|
context_key = context.to_name.key
|
9
10
|
absolute_name(context).parent_keys.include? context_key
|
10
11
|
end
|
@@ -26,7 +27,7 @@ class Cardname
|
|
26
27
|
end
|
27
28
|
|
28
29
|
def starts_with_joint?
|
29
|
-
|
30
|
+
compound? && parts.first.empty?
|
30
31
|
end
|
31
32
|
|
32
33
|
def from *from
|
@@ -36,16 +37,19 @@ class Cardname
|
|
36
37
|
# if possible, relativize name into one beginning with a "+". The new name must absolutize back to the correct
|
37
38
|
# original name in the context of "from"
|
38
39
|
def name_from *from
|
39
|
-
return self unless (remaining = remove_context
|
40
|
+
return self unless (remaining = remove_context(*from))
|
41
|
+
|
40
42
|
compressed = remaining.compact.unshift(nil).to_name # exactly one nil at beginning
|
41
43
|
key == compressed.absolute_name(from).key ? compressed : self
|
42
44
|
end
|
43
45
|
|
44
46
|
def remove_context *from
|
45
47
|
return false unless from.compact.present?
|
46
|
-
|
48
|
+
|
49
|
+
remaining = parts_excluding(*from)
|
47
50
|
return false if remaining.compact.empty? || # all name parts in context
|
48
51
|
remaining == parts # no name parts in context
|
52
|
+
|
49
53
|
remaining
|
50
54
|
end
|
51
55
|
|
@@ -60,6 +64,7 @@ class Cardname
|
|
60
64
|
next if part.empty?
|
61
65
|
next if part =~ /^_/ # this removes relative parts. why?
|
62
66
|
next if keys_to_ignore.member? part.to_name.key
|
67
|
+
|
63
68
|
part
|
64
69
|
end
|
65
70
|
end
|
@@ -68,6 +73,7 @@ class Cardname
|
|
68
73
|
context = (context || "").to_name
|
69
74
|
new_parts = absolutize_contextual_parts context
|
70
75
|
return "" if new_parts.empty?
|
76
|
+
|
71
77
|
absolutize_extremes new_parts, context.s
|
72
78
|
new_parts.join self.class.joint
|
73
79
|
end
|
@@ -90,10 +96,10 @@ class Cardname
|
|
90
96
|
when /^_main$/i then self.class.params[:main_name]
|
91
97
|
when /^(_self|_whole|_)$/i then context.s
|
92
98
|
when /^_left$/i then context.trunk
|
93
|
-
#
|
99
|
+
# NOTE: - inconsistent use of left v. trunk
|
94
100
|
when /^_right$/i then context.tag
|
95
|
-
when /^_(\d+)$/i then ordinal_part
|
96
|
-
when /^_(L*)(R?)$/i then partmap_part
|
101
|
+
when /^_(\d+)$/i then ordinal_part $LAST_MATCH_INFO[1].to_i, context
|
102
|
+
when /^_(L*)(R?)$/i then partmap_part $LAST_MATCH_INFO, context
|
97
103
|
else part
|
98
104
|
end.to_s.strip
|
99
105
|
end
|
@@ -109,20 +115,24 @@ class Cardname
|
|
109
115
|
end
|
110
116
|
|
111
117
|
def partmap_part match, context
|
112
|
-
l_s
|
118
|
+
l_s = match[1].size
|
119
|
+
r_s = !match[2].empty?
|
113
120
|
l_part = context.nth_left l_s
|
114
121
|
r_s ? l_part.tag : l_part.s
|
115
122
|
end
|
116
123
|
|
117
124
|
def absolutize_extremes new_parts, context
|
118
125
|
[0, -1].each do |i|
|
119
|
-
|
120
|
-
# following avoids recontextualizing with relative contexts.
|
121
|
-
# Eg, `+A+B+.absolute('+A')` should be +A+B, not +A+A+B.
|
122
|
-
next if new_parts.to_name.send "#{[ :start, :end ][i]}s_with_parts?", context
|
123
|
-
new_parts[i] = context
|
126
|
+
new_parts[i] = context if absolutize_extreme? new_parts, context, i
|
124
127
|
end
|
125
128
|
end
|
126
129
|
|
130
|
+
def absolutize_extreme? new_parts, context, index
|
131
|
+
return false if new_parts[index].present?
|
132
|
+
|
133
|
+
# following avoids recontextualizing with relative contexts.
|
134
|
+
# Eg, `+A+B+.absolute('+A')` should be +A+B, not +A+A+B.
|
135
|
+
!new_parts.to_name.send "#{%i[start end][index]}s_with_parts?", context
|
136
|
+
end
|
127
137
|
end
|
128
138
|
end
|
data/lib/cardname/manipulate.rb
CHANGED
@@ -8,6 +8,7 @@ class Cardname
|
|
8
8
|
return self if old_name.num_parts > num_parts
|
9
9
|
return swap_part(old_name, new_name) if old_name.simple?
|
10
10
|
return self unless include? old_name
|
11
|
+
|
11
12
|
swap_all_subsequences(old_name, new_name).to_name
|
12
13
|
end
|
13
14
|
|
@@ -29,6 +30,7 @@ class Cardname
|
|
29
30
|
return swap_part oldpiece, newpiece if oldpiece.simple?
|
30
31
|
return self unless starts_with_parts?(oldpiece)
|
31
32
|
return newpiece if oldpiece.num_parts == num_parts
|
33
|
+
|
32
34
|
self.class.new [newpiece, self[oldpiece.num_parts..-1]].flatten
|
33
35
|
end
|
34
36
|
|
@@ -72,6 +74,7 @@ class Cardname
|
|
72
74
|
|
73
75
|
def ensure_simpleness part, msg=nil
|
74
76
|
return if part.to_name.simple?
|
77
|
+
|
75
78
|
raise StandardError, "'#{part}' has to be simple. #{msg}"
|
76
79
|
end
|
77
80
|
end
|
data/lib/cardname/parts.rb
CHANGED
@@ -4,24 +4,12 @@ class Cardname
|
|
4
4
|
# the same methods without _name return strings
|
5
5
|
module Parts
|
6
6
|
attr_reader :parts, :part_keys, :simple
|
7
|
-
|
8
7
|
alias_method :to_a, :parts
|
9
8
|
|
10
9
|
def parts
|
11
10
|
@parts = Cardname.split_parts s
|
12
11
|
end
|
13
12
|
|
14
|
-
def simple
|
15
|
-
@simple = parts.size <= 1
|
16
|
-
end
|
17
|
-
alias simple? simple
|
18
|
-
|
19
|
-
# @return true if name has more than one part
|
20
|
-
def compound?
|
21
|
-
!simple?
|
22
|
-
end
|
23
|
-
alias junction? compound?
|
24
|
-
|
25
13
|
def part_keys
|
26
14
|
@part_keys ||= simple ? [simple_key] : parts.map { |p| p.to_name.simple_key }
|
27
15
|
end
|
@@ -51,15 +39,15 @@ class Cardname
|
|
51
39
|
end
|
52
40
|
|
53
41
|
def parents
|
54
|
-
@parents ||=
|
42
|
+
@parents ||= compound? ? [left, right] : []
|
55
43
|
end
|
56
44
|
|
57
45
|
def parent_names
|
58
|
-
@parent_names ||=
|
46
|
+
@parent_names ||= compound? ? [left_name, right_name] : []
|
59
47
|
end
|
60
48
|
|
61
49
|
def parent_keys
|
62
|
-
@parent_keys ||=
|
50
|
+
@parent_keys ||= compound? ? [left_key, right_key] : []
|
63
51
|
end
|
64
52
|
|
65
53
|
# Note that all names have a trunk and tag,
|
@@ -89,27 +77,8 @@ class Cardname
|
|
89
77
|
@piece_names ||= pieces.map(&:to_name)
|
90
78
|
end
|
91
79
|
|
92
|
-
# self and all ancestors (= parts and recursive lefts)
|
93
|
-
# @example
|
94
|
-
# "A+B+C+D".to_name.pieces
|
95
|
-
# # => ["A", "B", "C", "D", "A+B", "A+B+C", "A+B+C+D"]
|
96
|
-
def pieces
|
97
|
-
@pieces ||=
|
98
|
-
if simple?
|
99
|
-
[self]
|
100
|
-
else
|
101
|
-
junction_pieces = []
|
102
|
-
parts[1..-1].inject parts[0] do |left, right|
|
103
|
-
piece = [left, right] * self.class.joint
|
104
|
-
junction_pieces << piece
|
105
|
-
piece
|
106
|
-
end
|
107
|
-
parts + junction_pieces
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
80
|
def ancestors
|
112
|
-
@ancestors ||= pieces.reject { |p| p == self}
|
81
|
+
@ancestors ||= pieces.reject { |p| p == self }
|
113
82
|
end
|
114
83
|
|
115
84
|
# def + other
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Cardname
|
2
|
+
# Cards never have more than two "parts" (left and right), but they can have many
|
3
|
+
# "pieces". A card's pieces are all the other cards whose existence its existence
|
4
|
+
# implies. For example if A+B+C exists, that implies that A, B, C, and A+B do too.
|
5
|
+
module Pieces
|
6
|
+
# self and all ancestors (= parts and recursive lefts)
|
7
|
+
# @example
|
8
|
+
# "A+B+C+D".to_name.pieces
|
9
|
+
# # => ["A", "B", "C", "D", "A+B", "A+B+C", "A+B+C+D"]
|
10
|
+
def pieces
|
11
|
+
@pieces ||= simple? ? [self] : (parts + junction_pieces)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def junction_pieces
|
17
|
+
[].tap do |pieces|
|
18
|
+
parts[1..-1].inject parts[0] do |left, right|
|
19
|
+
piece = [left, right] * self.class.joint
|
20
|
+
pieces << piece
|
21
|
+
piece
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/cardname/predicates.rb
CHANGED
@@ -1,7 +1,19 @@
|
|
1
1
|
class Cardname
|
2
2
|
module Predicates
|
3
|
+
def simple?
|
4
|
+
@simple.nil? ? (@simple = parts.size <= 1) : @simple
|
5
|
+
end
|
6
|
+
alias_method :simple, :simple? # @deprecated
|
7
|
+
|
8
|
+
# @return true if name has more than one part
|
9
|
+
def compound?
|
10
|
+
!simple?
|
11
|
+
end
|
12
|
+
alias_method :junction?, :compound? # @deprecated
|
13
|
+
|
3
14
|
def valid?
|
4
15
|
return true if self.class.nothing_banned?
|
16
|
+
|
5
17
|
!parts.find do |pt|
|
6
18
|
pt.match self.class.banned_re
|
7
19
|
end
|
data/lib/cardname/variants.rb
CHANGED
@@ -2,19 +2,20 @@ class Cardname
|
|
2
2
|
module Variants
|
3
3
|
def simple_key
|
4
4
|
return "" if empty?
|
5
|
+
|
5
6
|
decoded
|
6
7
|
.underscore
|
7
|
-
.gsub(/[^#{OK4KEY_RE}]+/,
|
8
|
+
.gsub(/[^#{OK4KEY_RE}]+/, "_")
|
8
9
|
.split(/_+/)
|
9
10
|
.reject(&:empty?)
|
10
11
|
.map { |key| self.class.stable_key(key) }
|
11
|
-
.join(
|
12
|
+
.join("_")
|
12
13
|
end
|
13
14
|
|
14
15
|
def url_key
|
15
16
|
@url_key ||= part_names.map do |part_name|
|
16
|
-
stripped = part_name.decoded.gsub(/[^#{OK4KEY_RE}]+/,
|
17
|
-
stripped.gsub(/[\
|
17
|
+
stripped = part_name.decoded.gsub(/[^#{OK4KEY_RE}]+/, " ").strip
|
18
|
+
stripped.gsub(/[\s_]+/, "_")
|
18
19
|
end * self.class.joint
|
19
20
|
end
|
20
21
|
|
@@ -22,11 +23,11 @@ class Cardname
|
|
22
23
|
# but the key is no longer unique.
|
23
24
|
# For example "A-XB" and "A+*B" have the same safe_key
|
24
25
|
def safe_key
|
25
|
-
@safe_key ||= key.tr(
|
26
|
+
@safe_key ||= key.tr("*", "X").tr self.class.joint, "-"
|
26
27
|
end
|
27
28
|
|
28
29
|
def decoded
|
29
|
-
@decoded ||= s.index(
|
30
|
+
@decoded ||= s.index("&") ? HTMLEntities.new.decode(s) : s
|
30
31
|
end
|
31
32
|
|
32
33
|
def to_sym
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cardname
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ethan McCutchen
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2021-05-10 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -53,13 +53,19 @@ files:
|
|
53
53
|
- lib/cardname/contextual.rb
|
54
54
|
- lib/cardname/manipulate.rb
|
55
55
|
- lib/cardname/parts.rb
|
56
|
+
- lib/cardname/pieces.rb
|
56
57
|
- lib/cardname/predicates.rb
|
57
58
|
- lib/cardname/variants.rb
|
58
59
|
- lib/core_ext.rb
|
59
|
-
homepage:
|
60
|
+
homepage: https://decko.org
|
60
61
|
licenses:
|
61
62
|
- GPL-3.0
|
62
|
-
metadata:
|
63
|
+
metadata:
|
64
|
+
source_code_uri: https://github.com/decko-commons/decko
|
65
|
+
homepage_uri: https://decko.org
|
66
|
+
bug_tracker_uri: https://github.com/decko-commons/decko/issues
|
67
|
+
wiki_uri: https://decko.org
|
68
|
+
documentation_url: http://docs.decko.org/
|
63
69
|
post_install_message:
|
64
70
|
rdoc_options: []
|
65
71
|
require_paths:
|
@@ -75,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
81
|
- !ruby/object:Gem::Version
|
76
82
|
version: '0'
|
77
83
|
requirements: []
|
78
|
-
rubygems_version: 3.
|
84
|
+
rubygems_version: 3.1.4
|
79
85
|
signing_key:
|
80
86
|
specification_version: 4
|
81
87
|
summary: Card names without all the cards
|