class String
Alteration to <string> class
Public Class Methods
:macos text handling notes: hints.macworld.com/article.php?story=20060825071728278 Also, research UTF8_MAC <-> UTF8_HFS <-> UTF8 normalization conversions.
# File lib/gxg/gxg_augmented.rb, line 1850 def self.transcode_options(destination_encoding, source_encoding, options={}) # TODO: ::String::transcode_options : complete transcoding back-end supports. # select a default encoding_option set given the two encodings, then merge options over that and return. Explore Hash deep-merge ideas. # new_options = {} # fallback set/method or replace char if options[:fallback] # Note: I *confirmed* (thanks VGoff) that :invalid/:undef/:replace and :fallback are exclusive - So maybe this is really an optimized :fallback thing? # Sets the replacement string by the given object for undefined character. The object should be a Hash, a Proc, a Method, # or an object which has [] method. Its key is an undefined character encoded in the source encoding of current transcoder. # Its value can be any encoding until it can be converted into the destination encoding of the transcoder. if (options[:fallback].is_any?(::Hash, ::Struct, ::Proc, ::Method) || options[:fallback].respond_to?(:[])) # if :fallback will not process an Array as mentioned above ... remove :[] respond_to? condition. new_options[:fallback] = options[:fallback].dup end else # if options[:invalid] == :replace # If the value is :replace, encode replaces invalid byte sequences in str with the replacement character. The default is to # raise the Encoding::InvalidByteSequenceError exception new_options[:invalid] = :replace end # if options[:undef] == :replace # If the value is :replace, encode replaces characters which are undefined in the destination encoding with the replacement character. # The default is to raise the Encoding::UndefinedConversionError. new_options[:undef] = :replace end # if options[:replace] # Sets the replacement string to the given value. The default replacement string is “uFFFD” for Unicode encoding forms, and “?” otherwise. new_options[:replace] = options[:replace].dup end # end # xml if options[:xml] # The value must be :text or :attr. If the value is :text encode replaces undefined characters with their (upper-case hexadecimal) numeric character # references. ‘&’, ‘<’, and ‘>’ are converted to “&”, “<”, and “>”, respectively. If the value is :attr, encode also quotes the replacement # result (using ‘“’), and replaces ‘”’ with “"”. if [:text, :attr].include?(options[:xml]) new_options[:xml] = options[:xml].dup end end # if options[:universal_newline] # Replaces CRLF (“rn”) and CR (“r”) with LF (“n”) if value is true. unless (new_options[:cr_newline] || new_options[:crlf_newline]) if options[:universal_newline] == true new_options[:universal_newline] = true end end else if options[:crlf_newline] # Replaces LF (“n”) with CRLF (“rn”) if value is true. unless (new_options[:cr_newline] || new_options[:universal_newline]) if options[:crlf_newline] == true new_options[:crlf_newline] = true end end else if options[:cr_newline] # Replaces LF (“n”) with CR (“r”) if value is true. unless (new_options[:crlf_newline] || new_options[:universal_newline]) if options[:cr_newline] == true new_options[:cr_newline] = true end end else # default end end end # default_options = {} # find the default conversion options given the destination and source encodings # then ... new_options # deep-merge new_options into a provided default_options # then return default_options # default_options end
Public Instance Methods
Base64 Stuff:
# File lib/gxg/gxg_augmented.rb, line 2932 def base64?() # RFC 4648 # SOMEDAY: use regex based detection, current is open to some bugs. # See: http://ruby.about.com/od/advancedruby/ss/Base64-In-Ruby.htm # See: http://www.perlmonks.org/?node_id=775820 # See: http://mattfaus.com/blog/2007/02/14/base64-regular-expression/ # See: http://stackoverflow.com/questions/475074/regex-to-parse-or-validate-base64-data # Regex Testing: http://www.myregexp.com/signedJar.html # For now: begin # Review : So, for a work-around - keep adding exclusion tests to this conditional set as you discover them. if (self.size > 0) && (not ["html","form","page","head","body"].include?(self.downcase)) # Review : *almost perfect* - words like 'html' 'form' 'page' get mangled because this regex senses they are base64 when they are not! (consult regex expert for remedy) if self.match(/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/) true else false end else false end rescue Exception => the_error false end end
# File lib/gxg/gxg_augmented.rb, line 2733 def byte_at(*args) # Random-access indexed byte value retrieval. Returns a Integer or nil. # why? This is to pluck a single byte value out of a string as if it were merely a string of bytes. 1.8.7 used to provide a [] method for this purpose. if args[0].is_a?(Numeric) args[0] = args[0].to_i else raise ArgumentError.new("The parameter needs to be a Numeric, you provided #{args[0].inspect}") end if self.bytesize > 0 if self.encoding == ::Encoding::ASCII_8BIT self[(args[0])].ord else self.slice_bytes(args[0])[0].ord end else nil end end
# File lib/gxg/gxg_augmented.rb, line 2752 def bytes_at(*args) # Returns GxG::ByteArray unless args.size > 0 args = [(0..-1)] end GxG::ByteArray.new(1,self.slice_bytes(*args)) end
# File lib/gxg/gxg_augmented.rb, line 2278 def camel_case?() # self.match(/([A-Z][a-z]+[A-Z][a-zA-Z]+)/) if self.match(/[A-Z]([A-Z0-9]*[a-z][a-z0-9]*[A-Z]|[a-z0-9]*[A-Z][A-Z0-9]*[a-z])[A-Za-z0-9]*/) true else false end end
# File lib/gxg/gxg_augmented.rb, line 2967 def decode64() # RFC 4648 if self.base64?() ::Base64::strict_decode64(self) else self end end
# File lib/gxg/gxg_augmented.rb, line 2984 def decode64!() data = self.decode64() if data != self self.replace(data) end self end
# File lib/gxg/gxg_augmented.rb, line 3029 def decrypt(withkey="") # if withkey.to_s.size > 0 the_encoding = self.encoding() keybytes = ::GxG::ByteArray.new(withkey.to_s) container = ::GxG::ByteArray.new(self) # container.each_index do |index| the_value = container[(index)] # keybytes.each do |the_byte| [127,63,31,15,7,3,1,0].each do |the_bit| if the_byte > the_bit the_value -= 1 if the_value < 0 the_value = 255 end else the_value += 1 if the_value > 255 the_value = 0 end end end end # container[(index)] = the_value end # result = container.to_s result.force_encoding(the_encoding) result else self.dup end end
# File lib/gxg/gxg_augmented.rb, line 2818 def each_byte(&block) enumerator = self.to_enum(:bytes) if block.respond_to?(:call) enumerator.each do |item| block.call(item) end self else enumerator end end
# File lib/gxg/gxg_augmented.rb, line 2830 def each_byte_with_index(offset=0,&block) # Thanks to Hanmac from IRC :) enumerator = self.to_enum(:bytes).with_index(offset) if block.respond_to?(:call) enumerator.each do |item,index| block.call(item,index) end self else enumerator end end
# File lib/gxg/gxg_augmented.rb, line 2793 def each_char(&block) enumerator = self.to_enum(:chars) if block.respond_to?(:call) enumerator.each do |item| block.call(item) end self else enumerator end end
# File lib/gxg/gxg_augmented.rb, line 2805 def each_char_with_index(offset=0,&block) # Thanks to Hanmac from IRC :) enumerator = self.to_enum(:chars).with_index(offset) if block.respond_to?(:call) enumerator.each do |item,index| block.call(item,index) end self else enumerator end end
# File lib/gxg/gxg_augmented.rb, line 2843 def each_codepoint(&block) # String.codepoint will not return a GxG::Enumerator (non-blocking), so I'm providing these methods. enumerator = self.to_enum(:codepoints) if block.respond_to?(:call) enumerator.each do |item| block.call(item) end self else enumerator end end
# File lib/gxg/gxg_augmented.rb, line 2856 def each_codepoint_with_index(offset=0,&block) enumerator = self.to_enum(:codepoints).with_index(offset) if block.respond_to?(:call) enumerator.each do |item,index| block.call(item,index) end self else enumerator end end
Note: documentation: recommend use of these methods and NOT those which they call to ensure cooperative event processing. LATER: String: look into c code : is there a way to pluck a char off a string w/o using chars,bytes,codepoints,lines ? This would afford an opportunity to override chars,bytes,codepoints and lines so that cooperative event processing was truly and invisibly supported. This would be slower than the c code, but would let you load up gems w/o overriding another author's code to make it cooperative. (i.e. facets, etc)
# File lib/gxg/gxg_augmented.rb, line 2769 def each_line(separator=$/,&block) enumerator = self.lines(separator).to_enum if block.respond_to?(:call) enumerator.each do |item| block.call(item) end self else enumerator end end
# File lib/gxg/gxg_augmented.rb, line 2781 def each_line_with_index(separator=$/,offset=0,&block) enumerator = self.lines(separator).to_enum.with_index(offset) if block.respond_to?(:call) enumerator.each do |item,index| block.call(item,index) end self else enumerator end end
# File lib/gxg/gxg_augmented.rb, line 2958 def encode64() # RFC 4648 if self.base64?() self else ::Base64::strict_encode64(self) end end
# File lib/gxg/gxg_augmented.rb, line 2976 def encode64!() data = self.encode64() if data != self self.replace(data) end self end
# File lib/gxg/gxg_augmented.rb, line 2992 def encrypt(withkey="") # if withkey.to_s.size > 0 the_encoding = self.encoding() keybytes = ::GxG::ByteArray.new(withkey.to_s) container = ::GxG::ByteArray.new(self) # container.each_index do |index| the_value = container[(index)] # keybytes.each do |the_byte| [127,63,31,15,7,3,1,0].each do |the_bit| if the_byte > the_bit the_value += 1 if the_value > 255 the_value = 0 end else the_value -= 1 if the_value < 0 the_value = 255 end end end end # container[(index)] = the_value end # result = container.to_s result.force_encoding(the_encoding) result else self.dup end end
# File lib/gxg/gxg_augmented.rb, line 2896 def from_json(symbolize_names = true) if self.json? the_object = ::JSON::parse(self,{:symbolize_names => symbolize_names}) if the_object.is_any?(::Hash, ::Array) the_object.process! do |value, selector, container| if value.is_a?(::String) item = value.numeric_values() if item.is_a?(::Hash) if item[:integer] item = item[:integer] container[(selector)] = item else if item[:float] item = item[:float] container[(selector)] = item end end else if (value.valid_datetime? || value.valid_datetime_nolocale?) container[(selector)] = ::DateTime::parse(value) end end # if value[0..6] == "binary:" && value[7..-1].base64? container[(selector)] = GxG::ByteArray.new(value[7..-1].decode64) end end nil end # end else self end end
def from_xml(options={})
# unless options[:no_test] == true unless self.xml?() raise Exception, "String is NOT formatted as XML." end end result = nil visit = Proc.new do |the_node=nil, accumulator=[]| node_stack = [] if the_node node_stack.push(the_node) while (node_stack.size > 0) do a_node = node_stack.pop() # process(a_node) if a_node.is_a?(::Oga::XML::Text) accumulator << a_node.text() end if a_node.is_any?(::Oga::XML::Element, ::Oga::XML::Document) record = {:name => "document_root", :attributes => {}, :parent => nil, :object => nil, :path => "/", :assembled => false} if a_node.respond_to?(:name) record[:name] = a_node.name() end if a_node.respond_to?(:attributes) a_node.attributes.each do |the_attr| record[:attributes][(the_attr.name.to_s.to_sym)] = the_attr.value end end if a_node.respond_to?(:parent) record[:parent] = a_node.parent() else record[:parent] = a_node end record[:object] = a_node unless a_node.is_a?(::Oga::XML::Document) # set accumulator path # end accumulator << record end if a_node.children.size > 0 a_node.children.each do |entry| node_stack.push(entry) end end end end accumulator end # begin if options[:sax] == true database = visit.call(::Oga::sax_parse_xml(self.transcode({:replace => "."},::Encoding::UTF_8)),[]) else database = visit.call(::Oga::parse_xml(self.transcode({:replace => "."},::Encoding::UTF_8)),[]) end link_db = [] accumulator = [] # Build link_db database.each do |the_node| if the_node.is_a?(::Hash) node_record = {} as_key = the_node[:name].to_s.to_sym if the_node[:object].is_a?(::Oga::XML::Document) node_record[(as_key)] = {:attributes => (the_node[:attributes]), :text => "", :children => []} else node_record[(as_key)] = {:attributes => (the_node[:attributes]), :text => (the_node[:object].text), :children => []} end link_record = {:desendents => [], :accumulator => (node_record[(as_key)][:children])} # database.each do |a_node| if a_node.is_a?(::Hash) if a_node[:parent].object_id == the_node[:object].object_id link_record[:desendents] << a_node[:object] end end end link_db << link_record if the_node[:parent].is_a?(::Oga::XML::Document) accumulator << node_record end else accumulator << the_node end end # while (link_db.size > 0) do entry = link_db.shift if entry.is_a?(::Hash) entry[:desendents].each do |node| unless node.is_a?(::Oga::XML::Document) if node.is_a?(::Oga::XML::Text) node_record = node.text else if node.is_a?(::Oga::XML::Comment) node_record = {:comment => node.text} else node_record = {} as_key = node.name.to_s.to_sym node_record[(as_key)] = {:attributes => {}, :text => (node.text), :children => []} node.attributes.each do |the_attr| node_record[(as_key)][:attributes][(the_attr.name.to_s.to_sym)] = the_attr.value end link_record = {:desendents => [], :accumulator => (node_record[(as_key)][:children])} node.children.each do |node_descendent| link_record[:desendents] << node_descendent end if link_record[:desendents].size > 0 link_db.push(link_record) end end end # entry[:accumulator] << node_record end end # end end # result = accumulator rescue Exception => the_error end # result
end
def from_xml_simple()
if self.xml? the_hash = ::XmlSimple.xml_in(self) if the_hash.is_a?(::Hash) the_hash.symbolize_keys the_hash.process! do |value, selector, container| if value.is_a?(::String) item = value.numeric_values() if item.is_a?(::Hash) if item[:integer] item = item[:integer] container[(selector)] = item else if item[:float] item = item[:float] container[(selector)] = item end end else # Cast all time elements to ISO-8601 if (value.valid_time? || value.valid_date? || value.valid_datetime? || value.valid_datetime_nolocale?) container[(selector)] = ::DateTime::parse(value.to_s) end end end nil end end the_hash else nil end
end
# File lib/gxg/gxg_augmented.rb, line 2482 def html?() declaration_test = (self.include?('<!DOCTYPE HTML') || self.include?('<!DOCTYPE html') || self.include?('<!DOCTYPE xhtml')) parse_test = false if declaration_test begin mime = self.mime_type() if mime.is_a?(::Hash) if ["html", "xhtml", "xhtml+xml"].include?(mime[:subtype]) parse_test = true end end rescue Exception => the_error end end (declaration_test && parse_test) end
# File lib/gxg/gxg_augmented.rb, line 2892 def json?() self.json_1?() || self.json_2?() end
# File lib/gxg/gxg_augmented.rb, line 2884 def json_1?() self.slice(0,1) == '{' end
# File lib/gxg/gxg_augmented.rb, line 2888 def json_2?() (self.json_1?() && (self.match('"apiVersion"\s?:\s?"2.0"') || false)) end
# File lib/gxg/gxg_augmented.rb, line 2295 def mime_type() result = nil raw = ::MimeMagic.by_magic(::StringIO.new(self.clone)) if raw result = {:type => (raw.type), :mediatype => (raw.mediatype), :subtype => (raw.subtype)} end result end
# File lib/gxg/gxg_augmented.rb, line 2108 def numeric_values(categories=:any,delimiter="\t",locale=:en_US, numeric_base=10) results = [] prepared = [] # SOMEDAY: <string>.numeric_values: formulate regex patterns per locale and numeric_base quanta_pattern = /[a-zA-Z]*/ # proposed: /^-{0,1}\d*\.{0,1}\d+$/ # /^[-+]{0,1}\d*\.{0,1}\d+$/ # old: /[0-9.,]*/ numerical_pattern = /[-+0-9.,]*/ self.to_enum(:each_line).each do |row_text| # ?? allow empty lines ?? I'm just not sure if I really *want* to attempt to preserve the structure that much. row_prep = [] row_text.split(delimiter).to_enum.each do |column_text| if column_text.size > 0 column_entry = {:text => column_text, :denomination => nil, :multiplier => nil} column_text.scan(quanta_pattern).to_enum.each do |quanta| if quanta.size > 0 # interpretation = ::GxG::Units::interpret_units({:text => quanta,:categories => categories,:locale => locale, :base => numeric_base}) # if interpretation[:error] raise interpretation[:error] else # SOMEDAY: <string>.numeric_values: a bit more discernment here than just the first interpretation. interpretation = interpretation[:result] if interpretation[0].is_a?(Hash) if interpretation[0][:quantum].is_a?(Hash) denomination = interpretation[0][:quantum].keys[0] multiplier = interpretation[0][:quantum][(denomination)] column_entry = {:text => column_text, :denomination => denomination, :multiplier => multiplier} if interpretation[0][:attributes].is_a?(Hash) column_entry[:attributes] = interpretation[0][:attributes] end break end end end # end # end # row_prep << column_entry # else row_prep << nil end end prepared << row_prep # end # process prepared array prepared.to_enum.each do |row| results << row.to_enum.map do |column| result = nil if column.is_a?(Hash) column[:text].scan(numerical_pattern).to_enum.each do |text| text.gsub!(",","") if text.size > 0 denomination = column[:denomination] multiplier = column[:multiplier] if text.include?(".") # Note: defaults *assume* base-10 numbers unless denomination denomination = :float end unless multiplier multiplier = 1.0 end result = {} result[(denomination)] = text.to_f * multiplier.to_f else # Note: defaults *assume* base-10 numbers unless denomination denomination = :integer end unless multiplier multiplier = 1 end result = {} result[(denomination)] = text.to_i * multiplier.to_i end if column[:attributes].is_a?(Hash) result.merge(column[:attributes]) end break end end end result end end # unless it is a multi-line, or multi-column result, pass only the found denomination/value Hash. if results.size == 1 # single row results = results[0] if results.size == 1 # single column results = results[0] end end # results end
Encoding format detection and handling: Serialized, JSON & binhex(base64)
# File lib/gxg/gxg_augmented.rb, line 2868 def serialized?() if ((self[0..7].to_s == "marshal:" || self[0..9].to_s == "structure:") && (self[8..-1].to_s.base64?() || self[10..-1].to_s.base64?())) true else false end end
# File lib/gxg/gxg_augmented.rb, line 2641 def slice_bytes(*args) # Return an ASCII_8BIT encoded sub-string result = nil the_range = nil if args[0].is_a?(Numeric) args[0] = args[0].to_i if args[0] < 0 args[0] = self.bytesize + args[0] end the_range = ((args[0])..(args[0])) if args[1].is_a?(Numeric) args[1] = args[1].to_i if args[1] < 1 raise ArgumentError.new("Second parameter needs to be a Numeric greater than 0, you provided #{args[1].inspect}") else the_range = ((args[0])..(args[0] + (args[1] - 1))) end end else if args[0].is_a?(Range) if args[0].first < 0 args[1] = self.bytesize + args[0].first else args[1] = args[0].first end if args[0].last < 0 args[2] = self.bytesize + args[0].last else args[2] = args[0].last end if args[1] <= args[2] the_range = ((args[1])..(args[2])) else the_range = ((args[2])..(args[1])) end else raise ArgumentError.new("First parameter needs to be a Numeric or a Range, you provided #{args[0].inspect}") end end # if the_range result = "" result.force_encoding(::Encoding::ASCII_8BIT) # if self.encoding == ::Encoding::ASCII_8BIT if self.bytesize > 0 if the_range.min != the_range.max result << self.slice(the_range) else result << self[(the_range.min)] end end else # based upon memory-load and processing-load of Ruby Engine, select space-vs-speed or speed-vs-space techniques. if (GxG::Engine::memory_load_high?() && (self.to_enum(:bytes).heap_used() < self.heap_used())) # trade off speed for space considerations # long-way 'round position = 0 index = 0 # self.to_enum(:bytes).each do |the_byte| if the_range.include?(position) if the_range.min == the_range.max result << the_byte.chr break else result[(index)] = the_byte.chr end index += 1 end position += 1 end # else # trade off space for speed considerations if self.bytesize > 0 raw_text = self.clone raw_text.force_encoding(::Encoding::ASCII_8BIT) if the_range.min != the_range.max result << raw_text.slice(the_range) else result << raw_text[(the_range.min)] end end # end end # end result end
# File lib/gxg/gxg_augmented.rb, line 2287 def split_camelcase() if self.camel_case?() self.split(/(?=[A-Z])/) else self end end
# File lib/gxg/gxg_augmented.rb, line 2637 def to_uri() ::URI::parse(self) end
# File lib/gxg/gxg_augmented.rb, line 1933 def transcode(*args) destination_encoding = nil conversion_options = nil if args.size > 0 if args[0].is_a?(::Hash) conversion_options = args[0] if args[1].is_a?(::Encoding) destination_encoding = args[1] else destination_encoding = ::Encoding.default_external end else # if args[0].is_a?(::Encoding) destination_encoding = args[0] if args[1].is_a?(::Hash) conversion_options = args[1] else conversion_options = {} end end end args = nil end # unless destination_encoding.is_a?(::Encoding) raise ArgumentError, "You must provide a valid Encoding, instead you provided #{destination_encoding.class}" end unless conversion_options.is_a?(::Hash) raise ArgumentError, "You must provide a Hash for conversion options, instead you provided #{conversion_options.class}" end in_options = {} out_options = {} # if (conversion_options[:invalid] || conversion_options[:undef] || conversion_options[:replace]) # Note: I *confirmed* (thanks VGoff) that :invalid/:undef/:replace and :fallback are exclusive. # # If the value is :replace, encode replaces invalid byte sequences in str with the replacement character. The default is to # raise the Encoding::InvalidByteSequenceError exception if conversion_options[:invalid] == :replace in_options[:invalid] = :replace out_options[:invalid] = :replace end # If the value is :replace, encode replaces characters which are undefined in the destination encoding with the replacement character. # The default is to raise the Encoding::UndefinedConversionError. if conversion_options[:undef] == :replace in_options[:undef] = :replace out_options[:undef] = :replace end # # Sets the replacement string to the given value. The default replacement string is “uFFFD” for Unicode encoding forms, and “?” otherwise. if conversion_options[:replace].is_a?(::String) in_options[:replace] = conversion_options[:replace] out_options[:replace] = conversion_options[:replace] end # else # Sets the replacement string by the given object for undefined character. The object should be a Hash, a Proc, a Method, # or an object which has [] method. Its key is an undefined character encoded in the source encoding of current transcoder. # Its value can be any encoding until it can be converted into the destination encoding of the transcoder. if (conversion_options[:fallback].is_any?(::Hash, ::Struct, ::Proc, ::Method) || conversion_options[:fallback].respond_to?(:[])) # if :fallback will not process an Array as mentioned above ... remove :[] respond_to? condition. if conversion_options[:fallback].is_any?(::Proc, ::Method) # TODO: study arguments and output expected, and construct one in and one out proc as wrapper. # FIX: Odd Bug : MRI 1.9.3 will attempt to convert a Proc into a Hash directly and raise exception, instead of calling the proc. # Also, when a method is supplied: it does call it, but passes no data and I don't think even collects a response. (wtf?) what is the point then?? # So ... as a work around (FORNOW) I will simply construct a Hash and use that resultant Hash as fallback. # LATER: I think I'd like to add the above comparison to simply check for a .respond_to?(:call) on action objects. in_fallback = {} out_fallback = {} self.each_char do |the_char| dst_defined_char = conversion_options[:fallback].call(the_char).to_s.chars.first if (dst_defined_char.size > 0 && the_char != dst_defined_char) utf_bridge = the_char.encode(::Encoding::UTF_8) in_fallback[(the_char)] = utf_bridge out_fallback[(utf_bridge)] = dst_defined_char end end in_options[:fallback] = in_fallback out_options[:fallback] = out_fallback else if conversion_options[:fallback].is_any?(::Hash, ::Struct) # in_fallback = {} out_fallback = {} # conversion_options[:fallback].to_enum(:each_pair).each do |src_undefined_char,dst_defined_char| utf_bridge = src_undefined_char.encode(::Encoding::UTF_8) in_fallback[(src_undefined_char)] = utf_bridge out_fallback[(utf_bridge)] = dst_defined_char end # in_options[:fallback] = in_fallback out_options[:fallback] = out_fallback else if (conversion_options[:fallback].respond_to?(:[]) && conversion_options[:fallback].respond_to?(:to_a)) in_fallback = {} out_fallback = {} the_data = conversion_options[:fallback].to_a.flatten the_size = the_data.size if (the_size.even? && the_size > 0) (0..(the_size)).step(2) do |index| src_undefined_char = the_data[(index)] dst_defined_char = the_data[(index + 1)] utf_bridge = src_undefined_char.encode(::Encoding::UTF_8) in_fallback[(src_undefined_char)] = utf_bridge out_fallback[(utf_bridge)] = dst_defined_char end else # raise error? this really requires matched pairs of things end in_options[:fallback] = in_fallback out_options[:fallback] = out_fallback end end end end end # # The value must be :text or :attr. If the value is :text encode replaces undefined characters with their (upper-case hexadecimal) numeric character # references. ‘&’, ‘<’, and ‘>’ are converted to “&”, “<”, and “>”, respectively. If the value is :attr, encode also quotes the replacement # result (using ‘“’), and replaces ‘”’ with “"”. if [:text, :attr].include?(conversion_options[:xml]) in_options[:xml] = conversion_options[:xml] out_options[:xml] = conversion_options[:xml] end # # Replaces LF (“n”) with CR (“r”) if value is true. unless (conversion_options[:crlf_newline] || conversion_options[:universal_newline]) if conversion_options[:cr_newline] == true in_options[:cr_newline] = true out_options[:cr_newline] = true end end # # Replaces LF (“n”) with CRLF (“rn”) if value is true. unless (conversion_options[:cr_newline] || conversion_options[:universal_newline]) if conversion_options[:crlf_newline] == true in_options[:crlf_newline] = true out_options[:crlf_newline] = true end end # # Replaces CRLF (“rn”) and CR (“r”) with LF (“n”) if value is true. unless (conversion_options[:cr_newline] || conversion_options[:crlf_newline]) if conversion_options[:universal_newline] == true in_options[:universal_newline] = true out_options[:universal_newline] = true end end # ### # the_string = self.encode(::Encoding::UTF_8,self.external_encoding,in_options) # the_string.encode!(destination_encoding,::Encoding::UTF_8,out_options) # --or-- if self.encoding == ::Encoding::UTF_8 the_string = self.dup else the_string = self.encode(::Encoding::UTF_8,self.encoding,in_options) end if destination_encoding != ::Encoding::UTF_8 the_string.encode!(destination_encoding,::Encoding::UTF_8,out_options) end # the_string end
# File lib/gxg/gxg_augmented.rb, line 2099 def transcode!(*args) data = self.transcode(*args) if data.is_a?(::String) self.force_encoding(data.encoding) self.replace(data) end self end
# File lib/gxg/gxg_augmented.rb, line 2760 def unpack_bytes(format_template_string="") # See : http://ruby-doc.org/core-1.9.3/String.html#method-i-byteslice#This%20table%20summarizes GxG::ByteArray.new(self.unpack(format_template_string)) end
# File lib/gxg/gxg_augmented.rb, line 2876 def unserialize() if self.serialized?() ::GxG::reconstitute(self) else self end end
# File lib/gxg/gxg_augmented.rb, line 2227 def valid_date?() # Match for Date pattern if (/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/.match(self)) true else false end end
# File lib/gxg/gxg_augmented.rb, line 2236 def valid_datetime?() # Match for ISO 8601 pattern if (/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9][+-][0-9][0-9]:[0-9][0-9]/.match(self)) true else false end end
# File lib/gxg/gxg_augmented.rb, line 2245 def valid_datetime_nolocale?() # Match for not-so-much ISO 8601-ish pattern if (/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/.match(self)) true else false end end
# File lib/gxg/gxg_augmented.rb, line 2262 def valid_jid?() # From Blather: /^(?:([^@]*)@)??([^@\/]*)(?:\/(.*?))?$/ # From xmpp4r: /^(?:([^@\/<>\'\"]+)@)?([^@\/<>\'\"]+)(?:\/([^<>\'\"]*))?$/ # Note: for now - using the one from Blather if /^(?:([^@]*)@)??([^@\/]*)(?:\/(.*?))?$/.match(self) true else false end # if /^(?:([^@]*)@)??([^@\/]*)(?:\/(.*?))?$/.match(self) # true # else # false # end end
# File lib/gxg/gxg_augmented.rb, line 2254 def valid_path?() if (/.*(?:\\|\/)(.+)$/.match(self) || (self.split(" ").size == 1 || self.split("/").size > 1 || self == "/")) true else false end end
# File lib/gxg/gxg_augmented.rb, line 2213 def valid_time?() # Parse for Time class instance = nil begin instance = ::Chronic::parse(self) rescue Exception end if instance.is_a?(::Time) true else false end end
def from_html(options={})
# unless options[:no_test] == true unless self.html?() raise Exception, "String is NOT formatted as HTML." end end result = nil visit = Proc.new do |the_node=nil, accumulator=[]| node_stack = [] if the_node node_stack.push(the_node) while (node_stack.size > 0) do a_node = node_stack.pop() # process(a_node) if a_node.is_a?(::Oga::XML::Text) accumulator << a_node.text() end if a_node.is_any?(::Oga::XML::Element, ::Oga::XML::Document) record = {:name => "document_root", :attributes => {}, :parent => nil, :object => nil, :path => "/", :assembled => false} if a_node.respond_to?(:name) record[:name] = a_node.name() end if a_node.respond_to?(:attributes) a_node.attributes.each do |the_attr| record[:attributes][(the_attr.name.to_s.to_sym)] = the_attr.value end end if a_node.respond_to?(:parent) record[:parent] = a_node.parent() else record[:parent] = a_node end record[:object] = a_node unless a_node.is_a?(::Oga::XML::Document) # set accumulator path # end accumulator << record end if a_node.children.size > 0 a_node.children.each do |entry| node_stack.push(entry) end end end end accumulator end # begin if options[:sax] == true database = visit.call(::Oga::sax_parse_html(self.transcode({:replace => "."},::Encoding::UTF_8)),[]) else database = visit.call(::Oga::parse_html(self.transcode({:replace => "."},::Encoding::UTF_8)),[]) end link_db = [] accumulator = [] # Build link_db database.each do |the_node| if the_node.is_a?(::Hash) node_record = {} as_key = the_node[:name].to_s.to_sym if the_node[:object].is_a?(::Oga::XML::Document) node_record[(as_key)] = {:attributes => (the_node[:attributes]), :text => "", :children => []} else node_record[(as_key)] = {:attributes => (the_node[:attributes]), :text => (the_node[:object].text), :children => []} end link_record = {:desendents => [], :accumulator => (node_record[(as_key)][:children])} # database.each do |a_node| if a_node.is_a?(::Hash) if a_node[:parent].object_id == the_node[:object].object_id link_record[:desendents] << a_node[:object] end end end link_db << link_record if the_node[:parent].is_a?(::Oga::XML::Document) accumulator << node_record end else accumulator << the_node end end # while (link_db.size > 0) do entry = link_db.shift if entry.is_a?(::Hash) entry[:desendents].each do |node| unless node.is_a?(::Oga::XML::Document) if node.is_a?(::Oga::XML::Text) node_record = node.text else if node.is_a?(::Oga::XML::Comment) node_record = {:comment => node.text} else node_record = {} as_key = node.name.to_s.to_sym node_record[(as_key)] = {:attributes => {}, :text => (node.text), :children => []} node.attributes.each do |the_attr| node_record[(as_key)][:attributes][(the_attr.name.to_s.to_sym)] = the_attr.value end link_record = {:desendents => [], :accumulator => (node_record[(as_key)][:children])} node.children.each do |node_descendent| link_record[:desendents] << node_descendent end if link_record[:desendents].size > 0 link_db.push(link_record) end end end # entry[:accumulator] << node_record end end # end end # result = accumulator rescue Exception => the_error end # result
end
# File lib/gxg/gxg_augmented.rb, line 2626 def valid_uri?() result = false begin if ::URI::parse(self).is_a?(::URI::Generic) result = true end rescue Exception end result end
# File lib/gxg/gxg_augmented.rb, line 2304 def xml?() declaration_test = self.include?("<?xml version=") parse_test = false if declaration_test begin mime = self.mime_type() if mime.is_a?(::Hash) if mime[:subtype] == "xml" || mime[:subtype] = "xhtml+xml" parse_test = true end end rescue Exception => the_error end end (declaration_test && parse_test) end