Class: SmartName
- Includes:
- ActiveSupport::Configurable
- Defined in:
- lib/smart_name.rb
Constant Summary collapse
- RUBY19 =
RUBY_VERSION =~ /^1\.9/
- WORD_RE =
RUBY19 ? '\p{Word}' : '\w'
- JOINT =
Wagny defaults:
'+'
- @@name2nameobject =
{}
Instance Attribute Summary collapse
-
#key ⇒ Object
readonly
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~.
-
#parts ⇒ Object
readonly
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~.
-
#s ⇒ Object
(also: #to_s)
readonly
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~.
-
#simple ⇒ Object
(also: #simple?)
readonly
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~.
Class Method Summary collapse
Instance Method Summary collapse
- #==(obj) ⇒ Object
- #blank? ⇒ Boolean (also: #empty?)
- #decoded ⇒ Object
-
#initialize(str) ⇒ SmartName
constructor
A new instance of SmartName.
- #inspect ⇒ Object
- #junction? ⇒ Boolean
- #left ⇒ Object
- #left_name ⇒ Object
- #length ⇒ Object
- #nth_left(n) ⇒ Object
- #pieces ⇒ Object
- #post_cgi ⇒ Object
- #pre_cgi ⇒ Object
-
#replace_part(oldpart, newpart) ⇒ Object
~~~~~~~~~~~~~~~~~~~~ MISC ~~~~~~~~~~~~~~~~~~~~.
- #right ⇒ Object
- #right_name ⇒ Object
- #rstar? ⇒ Boolean
- #safe_key ⇒ Object
-
#simple_key ⇒ Object
~~~~~~~~~~~~~~~~~~~ VARIANTS ~~~~~~~~~~~~~~~~~~~.
- #size ⇒ Object
-
#star? ⇒ Boolean
~~~~~~~~~~~~~~~~~~~ TRAITS / STARS ~~~~~~~~~~~~~~~~~~~.
- #tag ⇒ Object
- #tag_name ⇒ Object
- #to_absolute(context, args = {}) ⇒ Object
- #to_absolute_name(*args) ⇒ Object
- #to_name ⇒ Object
-
#to_show(context, args = {}) ⇒ Object
~~~~~~~~~~~~~~~~~~~~ SHOW / ABSOLUTE ~~~~~~~~~~~~~~~~~~~~.
- #trait(tag_code) ⇒ Object
- #trait_name(tag_code) ⇒ Object
- #trait_name?(*traitlist) ⇒ Boolean
-
#trunk ⇒ Object
Note that all names have a trunk and tag, but only junctions have left and right.
- #trunk_name ⇒ Object
- #url_key ⇒ Object
- #valid? ⇒ Boolean
Constructor Details
#initialize(str) ⇒ SmartName
Returns a new instance of SmartName.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/smart_name.rb', line 61 def initialize str @s = str.to_s.strip @s = @s.encode('UTF-8') if RUBY19 @key = if @s.index(SmartName.joint) @parts = @s.split(/\s*#{Regexp.escape(SmartName.joint)}\s*/) @parts << '' if @s[-1] == SmartName.joint @simple = false @parts.map { |p| p.to_name.key } * SmartName.joint else @parts = [str] @simple = true str.empty? ? '' : simple_key end @@name2nameobject[str] = self end |
Instance Attribute Details
#key ⇒ Object (readonly)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~
58 59 60 |
# File 'lib/smart_name.rb', line 58 def key @key end |
#parts ⇒ Object (readonly)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~
58 59 60 |
# File 'lib/smart_name.rb', line 58 def parts @parts end |
#s ⇒ Object (readonly) Also known as: to_s
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~
58 59 60 |
# File 'lib/smart_name.rb', line 58 def s @s end |
#simple ⇒ Object (readonly) Also known as: simple?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~
58 59 60 |
# File 'lib/smart_name.rb', line 58 def simple @simple end |
Class Method Details
.banned_re ⇒ Object
49 50 51 |
# File 'lib/smart_name.rb', line 49 def banned_re %r{#{ (['['] + SmartName.banned_array << SmartName.joint )*'\\' + ']' }} end |
.new(obj) ⇒ Object
32 33 34 35 36 37 38 39 40 |
# File 'lib/smart_name.rb', line 32 def new obj return obj if SmartName===obj str = Array===obj ? obj*SmartName.joint : obj.to_s if known_name = @@name2nameobject[str] known_name else super str.strip end end |
.substitute!(str, hash) ⇒ Object
267 268 269 270 271 272 |
# File 'lib/smart_name.rb', line 267 def self.substitute! str, hash hash.keys.each do |var| str.gsub!(SmartName.var_re) { |x| (v=hash[var.to_sym]).nil? ? x : v } end str end |
.unescape(uri) ⇒ Object
42 43 44 45 46 47 |
# File 'lib/smart_name.rb', line 42 def unescape uri # can't instantiate because key doesn't resolve correctly in unescaped form # issue is peculiar to plus sign (+), which are interpreted as a space. # if we could make that not happen, we could avoid this (and handle spaces in urls) uri.gsub(' ','+').gsub '_',' ' end |
Instance Method Details
#==(obj) ⇒ Object
90 91 92 93 94 95 96 97 |
# File 'lib/smart_name.rb', line 90 def == obj object_key = case when obj.respond_to?(:key) ; obj.key when obj.respond_to?(:to_name) ; obj.to_name.key else ; obj.to_s end object_key == key end |
#blank? ⇒ Boolean Also known as: empty?
83 |
# File 'lib/smart_name.rb', line 83 def blank?() s.blank? end |
#decoded ⇒ Object
114 115 116 |
# File 'lib/smart_name.rb', line 114 def decoded @decoded ||= (s.index('&') ? HTMLEntities.new.decode(s) : s) end |
#inspect ⇒ Object
86 87 88 |
# File 'lib/smart_name.rb', line 86 def inspect "<SmartName key=#{key}[#{self}]>" end |
#junction? ⇒ Boolean
132 |
# File 'lib/smart_name.rb', line 132 def junction?() not simple? end |
#left ⇒ Object
134 |
# File 'lib/smart_name.rb', line 134 def left() @left ||= simple? ? nil : parts[0..-2]*SmartName.joint end |
#left_name ⇒ Object
137 |
# File 'lib/smart_name.rb', line 137 def left_name() @left_name ||= left && SmartName.new( left ) end |
#length ⇒ Object
81 |
# File 'lib/smart_name.rb', line 81 def length() parts.length end |
#nth_left(n) ⇒ Object
233 234 235 236 |
# File 'lib/smart_name.rb', line 233 def nth_left n # 1 = left; 2= left of left; 3 = left of left of left.... ( n >= length ? parts[0] : parts[0..-n-1] ).to_name end |
#pieces ⇒ Object
148 149 150 151 152 153 154 |
# File 'lib/smart_name.rb', line 148 def pieces @pieces ||= if simple? [ self ] else trunk_name.pieces + [ tag_name ] end end |
#post_cgi ⇒ Object
124 125 126 127 |
# File 'lib/smart_name.rb', line 124 def post_cgi #hmm. this could resolve to the key of some other card. move to class method? @post_cgi ||= s.gsub '~plus~', SmartName.joint end |
#pre_cgi ⇒ Object
118 119 120 121 122 |
# File 'lib/smart_name.rb', line 118 def pre_cgi #why is this necessary?? doesn't real CGI escaping handle this?? # hmmm. is this to prevent absolutizing @pre_cgi ||= parts.join '~plus~' end |
#replace_part(oldpart, newpart) ⇒ Object
~~~~~~~~~~~~~~~~~~~~ MISC ~~~~~~~~~~~~~~~~~~~~
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/smart_name.rb', line 241 def replace_part oldpart, newpart oldpart = oldpart.to_name newpart = newpart.to_name if oldpart.simple? if simple? self == oldpart ? newpart : self else parts.map do |p| oldpart == p ? newpart.to_s : p end.to_name end elsif simple? self else if oldpart == parts[0, oldpart.length] if self.length == oldpart.length newpart else (newpart.parts+(parts[oldpart.length,].lines.to_a)).to_name end else self end end end |
#right ⇒ Object
135 |
# File 'lib/smart_name.rb', line 135 def right() @right ||= simple? ? nil : parts[-1] end |
#right_name ⇒ Object
138 |
# File 'lib/smart_name.rb', line 138 def right_name() @right_name ||= right && SmartName.new( right ) end |
#rstar? ⇒ Boolean
160 |
# File 'lib/smart_name.rb', line 160 def rstar?() right and '*' == right[0] end |
#safe_key ⇒ Object
110 111 112 |
# File 'lib/smart_name.rb', line 110 def safe_key @safe_key ||= key.gsub('*','X').gsub SmartName.joint, '-' end |
#simple_key ⇒ Object
~~~~~~~~~~~~~~~~~~~ VARIANTS ~~~~~~~~~~~~~~~~~~~
102 103 104 |
# File 'lib/smart_name.rb', line 102 def simple_key decoded.underscore.gsub(/[^#{WORD_RE}\*]+/,'_').split(/_+/).reject(&:empty?).map(&(SmartName.uninflect))*'_' end |
#size ⇒ Object
82 |
# File 'lib/smart_name.rb', line 82 def size() to_s.size end |
#star? ⇒ Boolean
~~~~~~~~~~~~~~~~~~~ TRAITS / STARS ~~~~~~~~~~~~~~~~~~~
159 |
# File 'lib/smart_name.rb', line 159 def star?() simple? and '*' == s[0] end |
#tag ⇒ Object
143 |
# File 'lib/smart_name.rb', line 143 def tag() @tag ||= simple? ? s : right end |
#tag_name ⇒ Object
146 |
# File 'lib/smart_name.rb', line 146 def tag_name() @tag_name ||= simple? ? self : right_name end |
#to_absolute(context, args = {}) ⇒ Object
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/smart_name.rb', line 202 def to_absolute context, args={} context = context.to_name parts.map do |part| new_part = case part when /^_user$/i; (user=Session.user_card) ? user.name : part when /^_main$/i; SmartName.params[:main_name] when /^(_self|_whole|_)$/i; context.s when /^_left$/i; context.trunk #note - inconsistent use of left v. trunk when /^_right$/i; context.tag when /^_(\d+)$/i pos = $~[1].to_i pos = context.length if pos > context.length context.parts[pos-1] when /^_(L*)(R?)$/i l_s, r_s = $~[1].size, !$~[2].empty? l_part = context.nth_left l_s r_s ? l_part.tag : l_part.s when /^_/ custom = args[:params] ? args[:params][part] : nil custom ? CGI.escapeHTML(custom) : part #why are we escaping HTML here? else part end.to_s.strip new_part.empty? ? context.to_s : new_part end * SmartName.joint end |
#to_absolute_name(*args) ⇒ Object
229 230 231 |
# File 'lib/smart_name.rb', line 229 def to_absolute_name *args SmartName.new to_absolute(*args) end |
#to_name ⇒ Object
80 |
# File 'lib/smart_name.rb', line 80 def to_name() self end |
#to_show(context, args = {}) ⇒ Object
~~~~~~~~~~~~~~~~~~~~ SHOW / ABSOLUTE ~~~~~~~~~~~~~~~~~~~~
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/smart_name.rb', line 185 def to_show context, args={} # ignore = [ args[:ignore], context.to_name.parts ].flatten.compact.map &:to_name ignore = [ args[:ignore] ].flatten.map &:to_name fullname = parts.to_name.to_absolute_name context, args show_parts = fullname.parts.map do |part| reject = ( part.empty? or part =~ /^_/ or ignore.member? part.to_name ) reject ? nil : part end initial_blank = show_parts[0].nil? show_name = show_parts.compact.to_name.s initial_blank ? SmartName.joint + show_name : show_name end |
#trait(tag_code) ⇒ Object
177 178 179 |
# File 'lib/smart_name.rb', line 177 def trait tag_code trait_name( tag_code ).s end |
#trait_name(tag_code) ⇒ Object
172 173 174 175 |
# File 'lib/smart_name.rb', line 172 def trait_name tag_code codecard = SmartName.codes[ tag_code ] and codecard = SmartName.lookup[ codecard ] and [ self, codecard.send(SmartName.name_attribute) ].to_name end |
#trait_name?(*traitlist) ⇒ Boolean
162 163 164 165 166 167 168 169 170 |
# File 'lib/smart_name.rb', line 162 def trait_name? *traitlist junction? && begin right_key = right_name.key !!traitlist.find do |codename| codecard = SmartName.codes[ codename ] and codecard = SmartName.lookup[ codecard ] and codecard.send(SmartName.name_attribute).key == right_key end end end |
#trunk ⇒ Object
Note that all names have a trunk and tag, but only junctions have left and right
142 |
# File 'lib/smart_name.rb', line 142 def trunk() @trunk ||= simple? ? s : left end |
#trunk_name ⇒ Object
145 |
# File 'lib/smart_name.rb', line 145 def trunk_name() @trunk_name ||= simple? ? self : left_name end |