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