parse 0.0.1.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 +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/CHANGELOG +9 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +138 -0
- data/Rakefile +6 -0
- data/lib/parse/version.rb +3 -0
- data/lib/parse.rb +102 -0
- data/parse.gemspec +29 -0
- data/spec/parse_spec.rb +8 -0
- data/spec/parse_ver0_0_1_spec.rb +160 -0
- data/spec/spec_helper.rb +6 -0
- metadata +161 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: 7d04d59e0d0c1eadc1d912f109697f28b18eb6bc
         | 
| 4 | 
            +
              data.tar.gz: c0207dac3109de5a81e8265e0e339138392f76a9
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: 2047276d42adf38a1b31af30d8610ed1daae0254765c4051ed381a15da44504b345f90cf83f57fc83bdfab84dd89700dc21793f8eecd06c5f31148453ae85d25
         | 
| 7 | 
            +
              data.tar.gz: 392dc0723a262777f89086320a34c9ae50eec4197fce5f174ac087cd91b29538c660bb96a4d7fe0b39f108dc853ce32956aa59eae7a44aed91bf47f39a913365
         | 
    
        data/.gitignore
    ADDED
    
    
    
        data/.rspec
    ADDED
    
    
    
        data/.travis.yml
    ADDED
    
    
    
        data/CHANGELOG
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE.txt
    ADDED
    
    | @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            Copyright (c) 2014 Seamus Abshere
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            MIT License
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Permission is hereby granted, free of charge, to any person obtaining
         | 
| 6 | 
            +
            a copy of this software and associated documentation files (the
         | 
| 7 | 
            +
            "Software"), to deal in the Software without restriction, including
         | 
| 8 | 
            +
            without limitation the rights to use, copy, modify, merge, publish,
         | 
| 9 | 
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 10 | 
            +
            permit persons to whom the Software is furnished to do so, subject to
         | 
| 11 | 
            +
            the following conditions:
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            The above copyright notice and this permission notice shall be
         | 
| 14 | 
            +
            included in all copies or substantial portions of the Software.
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 17 | 
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 18 | 
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| 19 | 
            +
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         | 
| 20 | 
            +
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 21 | 
            +
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 22 | 
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,138 @@ | |
| 1 | 
            +
            # Parse
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Detect and convert short strings into integers, floats, dates, times, booleans, arrays, and hashes - "like a human would".
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            ## Note on versions
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            You can always use `Parse.parse`. It will always point to the most recent version of the algorithm (currently `Parse.ver0_0_1`).
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            If the algorithm changes and you need the old version, you can reference it by its version number. For example, `Parse.ver0_0_1`.
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            ## Usage
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            You get the idea:
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                Parse.parse("15,000")                        #=> 15000
         | 
| 16 | 
            +
                Parse.parse("$123.4")                        #=> 123.4
         | 
| 17 | 
            +
                Parse.parse("(10,000,000.00)")               #=> -10000000.0
         | 
| 18 | 
            +
                Parse.parse("true")                          #=> true
         | 
| 19 | 
            +
                Parse.parse("no")                            #=> true
         | 
| 20 | 
            +
                Parse.parse("1982-01-01")                    #=> Fri, 01 Jan 1982
         | 
| 21 | 
            +
                Parse.parse("2010-05-05 13:42:16 Z")         #=> 2010-05-05 10:42:16 -0300
         | 
| 22 | 
            +
                Parse.parse("2010-05-05 13:42:16 -02:00")    #=> 2010-05-05 12:42:16 -0300
         | 
| 23 | 
            +
                Parse.parse("100%")                          #=> 1.0
         | 
| 24 | 
            +
                Parse.parse("50%")                           #=> 0.5
         | 
| 25 | 
            +
                Parse.parse("12/25/82", date: :us)           #=> Sat, 25 Dec 1982
         | 
| 26 | 
            +
                Parse.parse("25/12/82", date: :euro)         #=> Sat, 25 Dec 1982
         | 
| 27 | 
            +
                Parse.parse("#DIV/0")                        #=> Infinity
         | 
| 28 | 
            +
                Parse.parse("")                              #=> nil
         | 
| 29 | 
            +
                Parse.parse("nil")                           #=> nil
         | 
| 30 | 
            +
                Parse.parse("#NAME?")                        #=> nil
         | 
| 31 | 
            +
                Parse.parse("NaN")                           #=> NaN
         | 
| 32 | 
            +
                Parse.parse(".NaN")                          #=> NaN
         | 
| 33 | 
            +
                Parse.parse("-.inf")                         #=> -Infinity
         | 
| 34 | 
            +
                Parse.parse("Inf")                           #=> "Inf"
         | 
| 35 | 
            +
                Parse.parse(":no_symbols")                   #=> ":no_symbols"
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            More esoteric stuff:
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                Parse.parse("-")                             #=> nil
         | 
| 40 | 
            +
                Parse.parse("?")                             #=> nil
         | 
| 41 | 
            +
                Parse.parse("-8e-05")                        #=> -8.0e-05
         | 
| 42 | 
            +
                Parse.parse("-1_2.5e-1_3")                   #=> -1.25e-12
         | 
| 43 | 
            +
                Parse.parse("05753")                         #=> 5753
         | 
| 44 | 
            +
                Parse.parse("15_000")                        #=> 15000
         | 
| 45 | 
            +
                Parse.parse("15_00_0")                       #=> 15000
         | 
| 46 | 
            +
                Parse.parse("15.0")                          #=> 15.0
         | 
| 47 | 
            +
                Parse.parse("15,000.0")                      #=> 15000.0
         | 
| 48 | 
            +
                Parse.parse("15_000.0")                      #=> 15000.0
         | 
| 49 | 
            +
                Parse.parse("15_00_0.0")                     #=> 15000.0
         | 
| 50 | 
            +
                Parse.parse("0015")                          #=> 15
         | 
| 51 | 
            +
                Parse.parse("0015.0")                        #=> 15.0
         | 
| 52 | 
            +
                Parse.parse("0_015.0")                       #=> 15.0
         | 
| 53 | 
            +
                Parse.parse("0x15")                          #=> 21
         | 
| 54 | 
            +
                Parse.parse("0o15")                          #=> 13
         | 
| 55 | 
            +
                Parse.parse("8e-05")                         #=> 8.0e-05
         | 
| 56 | 
            +
                Parse.parse("1_2.5e-1_3")                    #=> 1.25e-12
         | 
| 57 | 
            +
                Parse.parse("0$123.4")                       #=> 123.4
         | 
| 58 | 
            +
                Parse.parse("$15,000")                       #=> 15000
         | 
| 59 | 
            +
                Parse.parse("0$15,000")                      #=> 15000
         | 
| 60 | 
            +
                Parse.parse("$123_456")                      #=> 123456
         | 
| 61 | 
            +
                Parse.parse("$123_456.7")                    #=> 123456.7
         | 
| 62 | 
            +
                Parse.parse("10,000,000")                    #=> 10000000
         | 
| 63 | 
            +
                Parse.parse("10,000,000.00")                 #=> 10000000.0
         | 
| 64 | 
            +
                Parse.parse("$10,000,000.00")                #=> 10000000.0
         | 
| 65 | 
            +
                Parse.parse("0$10,000,000.00")               #=> 10000000.0
         | 
| 66 | 
            +
                Parse.parse("$010,000,000.00")               #=> 10000000.0
         | 
| 67 | 
            +
                Parse.parse("-15")                           #=> -15
         | 
| 68 | 
            +
                Parse.parse("-15,000")                       #=> -15000
         | 
| 69 | 
            +
                Parse.parse("-15_000")                       #=> -15000
         | 
| 70 | 
            +
                Parse.parse("-15_00_0")                      #=> -15000
         | 
| 71 | 
            +
                Parse.parse("-15.0")                         #=> -15.0
         | 
| 72 | 
            +
                Parse.parse("-15,000.0")                     #=> -15000.0
         | 
| 73 | 
            +
                Parse.parse("-15_000.0")                     #=> -15000.0
         | 
| 74 | 
            +
                Parse.parse("-15_00_0.0")                    #=> -15000.0
         | 
| 75 | 
            +
                Parse.parse("00-15")                         #=> -15
         | 
| 76 | 
            +
                Parse.parse("00-15.0")                       #=> -15.0
         | 
| 77 | 
            +
                Parse.parse("0_0-15.0")                      #=> "0_0-15.0"
         | 
| 78 | 
            +
                Parse.parse("-0x15")                         #=> -21
         | 
| 79 | 
            +
                Parse.parse("-0o15")                         #=> -13
         | 
| 80 | 
            +
                Parse.parse("-$123.4")                       #=> -123.4
         | 
| 81 | 
            +
                Parse.parse("($123.4)")                      #=> -123.4
         | 
| 82 | 
            +
                Parse.parse("0($123.4)")                     #=> -123.4
         | 
| 83 | 
            +
                Parse.parse("-$15,000")                      #=> -15000
         | 
| 84 | 
            +
                Parse.parse("($15,000)")                     #=> -15000
         | 
| 85 | 
            +
                Parse.parse("-$123_456")                     #=> -123456
         | 
| 86 | 
            +
                Parse.parse("($123_456)")                    #=> -123456
         | 
| 87 | 
            +
                Parse.parse("-$123_456.7")                   #=> -123456.7
         | 
| 88 | 
            +
                Parse.parse("($123_456.7)")                  #=> -123456.7
         | 
| 89 | 
            +
                Parse.parse("-10,000,000")                   #=> -10000000
         | 
| 90 | 
            +
                Parse.parse("(10,000,000)")                  #=> -10000000
         | 
| 91 | 
            +
                Parse.parse("-10,000,000.00")                #=> -10000000.0
         | 
| 92 | 
            +
                Parse.parse("(10,000,000.00)")               #=> -10000000.0
         | 
| 93 | 
            +
                Parse.parse("1,200")                         #=> 1200
         | 
| 94 | 
            +
                Parse.parse("1,200.0")                       #=> 1200.0
         | 
| 95 | 
            +
                Parse.parse("1,2")                           #=> 12
         | 
| 96 | 
            +
                Parse.parse("1,20")                          #=> 120
         | 
| 97 | 
            +
                Parse.parse("1,2.0")                         #=> 12.0
         | 
| 98 | 
            +
                Parse.parse("1.0,2")                         #=> "1.0,2"
         | 
| 99 | 
            +
                Parse.parse("1.0,2.0")                       #=> "1.0,2.0"
         | 
| 100 | 
            +
                Parse.parse("-1,200")                        #=> -1200
         | 
| 101 | 
            +
                Parse.parse("-1,200.0")                      #=> -1200.0
         | 
| 102 | 
            +
                Parse.parse("-1,2")                          #=> -12
         | 
| 103 | 
            +
                Parse.parse("-1,20")                         #=> -120
         | 
| 104 | 
            +
                Parse.parse("-1,2.0")                        #=> -12.0
         | 
| 105 | 
            +
                Parse.parse("-1.0,2")                        #=> "-1.0,2"
         | 
| 106 | 
            +
                Parse.parse("-1.0,2.0")                      #=> "-1.0,2.0"
         | 
| 107 | 
            +
                Parse.parse("01,200")                        #=> 1200
         | 
| 108 | 
            +
                Parse.parse("01,200.0")                      #=> 1200.0
         | 
| 109 | 
            +
                Parse.parse("01,2")                          #=> 12
         | 
| 110 | 
            +
                Parse.parse("01,20")                         #=> 120
         | 
| 111 | 
            +
                Parse.parse("01,2.0")                        #=> 12.0
         | 
| 112 | 
            +
                Parse.parse("01.0,2")                        #=> "01.0,2"
         | 
| 113 | 
            +
                Parse.parse("01.0,2.0")                      #=> "01.0,2.0"
         | 
| 114 | 
            +
                Parse.parse("#hello")                        #=> "#hello"
         | 
| 115 | 
            +
                Parse.parse("\n#hello\n#world")              #=> "#hello #world"
         | 
| 116 | 
            +
                Parse.parse("hello\nworld")                  #=> "hello world"
         | 
| 117 | 
            +
                Parse.parse(",1")                            #=> ",1"
         | 
| 118 | 
            +
                Parse.parse(",1,")                           #=> ",1,"
         | 
| 119 | 
            +
             | 
| 120 | 
            +
            Note how, for better or worse, it effectively acts as a YAML or JSON parser, but doesn't do CSV:
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                Parse.parse("1,2,3")                         #=> "1,2,3"
         | 
| 123 | 
            +
                Parse.parse("[1,2,3]")                       #=> [1, 2, 3]
         | 
| 124 | 
            +
                Parse.parse("---\na: 1\n")                   #=> {"a"=>1}
         | 
| 125 | 
            +
                Parse.parse("---\n:a: 1\n")                  #=> {":a"=>1}
         | 
| 126 | 
            +
                Parse.parse("---\na: 1\n5: |-\n  c\n  3\n")  #=> {"a"=>1, 5=>"c\n3"}
         | 
| 127 | 
            +
                Parse.parse("{\"a\":1}")                     #=> {"a"=>1}
         | 
| 128 | 
            +
                Parse.parse("{\"a\":1,\"5\":\"c\\n3\"}")     #=> {"a"=>1, "5"=>"c\n3"}
         | 
| 129 | 
            +
             | 
| 130 | 
            +
            ## Wishlist
         | 
| 131 | 
            +
             | 
| 132 | 
            +
            1. allow specifying `date: '%Y/%m/%d'` for strptime
         | 
| 133 | 
            +
            1. allow hinting like `type: Integer` or `type: Date`
         | 
| 134 | 
            +
            1. deprecate this whole thing in favor of YAML 1.2?
         | 
| 135 | 
            +
             | 
| 136 | 
            +
            ## Copyright
         | 
| 137 | 
            +
             | 
| 138 | 
            +
            2014 Seamus Abshere
         | 
    
        data/Rakefile
    ADDED
    
    
    
        data/lib/parse.rb
    ADDED
    
    | @@ -0,0 +1,102 @@ | |
| 1 | 
            +
            require "parse/version"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'date'
         | 
| 4 | 
            +
            require 'yaml'
         | 
| 5 | 
            +
            require 'safe_yaml/load'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            module Parse
         | 
| 8 | 
            +
              # only need to deal with stuff not caught by YAML or JSON
         | 
| 9 | 
            +
              NULL = [ '', '-', '?', 'N/A', 'n/a', 'NULL', 'null', '#REF!', '#NAME?', 'NIL', 'nil', 'NA', 'na', '#VALUE!', '#NULL!'] # from bigml's list
         | 
| 10 | 
            +
              NAN = [ 'NaN' ]
         | 
| 11 | 
            +
              INFINITY = [ '#DIV/0', 'Infinity' ]
         | 
| 12 | 
            +
              NEG_INFINITY = [ '-Infinity' ]
         | 
| 13 | 
            +
              DATE = {
         | 
| 14 | 
            +
                euro: ['%d-%m-%Y', '%d-%m-%y'],
         | 
| 15 | 
            +
                us:   ['%m-%d-%Y', '%m-%d-%y'],
         | 
| 16 | 
            +
              }
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              def self.parse(raw, options = nil)
         | 
| 19 | 
            +
                ver0_0_1 raw, options
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              # @private
         | 
| 23 | 
            +
              # use YAML to parse stuff like '1.5'
         | 
| 24 | 
            +
              # ruby's yaml is 1.1, which means it does weird stuff with '001' (fixed in 1.2, which jruby has)
         | 
| 25 | 
            +
              def self.ver0_0_1(raw, options = nil)
         | 
| 26 | 
            +
                return raw unless raw.is_a? String
         | 
| 27 | 
            +
                
         | 
| 28 | 
            +
                memo = raw.strip
         | 
| 29 | 
            +
              
         | 
| 30 | 
            +
                return nil if NULL.include? memo
         | 
| 31 | 
            +
                return 1.0/0 if INFINITY.include? memo
         | 
| 32 | 
            +
                return -1.0/0 if NEG_INFINITY.include? memo
         | 
| 33 | 
            +
                return 0.0/0 if NAN.include? memo
         | 
| 34 | 
            +
                
         | 
| 35 | 
            +
                if options and options[:date]
         | 
| 36 | 
            +
                  yyyy, yy = DATE.fetch options[:date]
         | 
| 37 | 
            +
                  memo.sub!(/0+/, '')
         | 
| 38 | 
            +
                  memo.gsub! '/', '-'
         | 
| 39 | 
            +
                  if memo =~ /\d{4,}/ # yyyy
         | 
| 40 | 
            +
                    return Date.strptime(memo, yyyy)
         | 
| 41 | 
            +
                  else
         | 
| 42 | 
            +
                    return Date.strptime(memo, yy)
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                not_numeric = nil
         | 
| 47 | 
            +
                not_numeric ||= memo =~ /,\d{1,2},/ # comma not used for thousands, like 10,20,30
         | 
| 48 | 
            +
                not_numeric ||= memo =~ /\..*,/ # comma following a period, like 1.0,2
         | 
| 49 | 
            +
                not_numeric ||= memo =~ /\A[^(+\-\$0-9%]/ # starts with letter or smth
         | 
| 50 | 
            +
                possible_numeric = !not_numeric
         | 
| 51 | 
            +
                accounting_negative = nil
         | 
| 52 | 
            +
                percentage = nil
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                if possible_numeric
         | 
| 55 | 
            +
                  accounting_negative = memo =~ /\A[0$]*\([0$]*/
         | 
| 56 | 
            +
                  percentage = memo.end_with?('%')
         | 
| 57 | 
            +
                  memo.sub! /%\z/, '' if percentage
         | 
| 58 | 
            +
                  memo.delete!('()') if accounting_negative # accounting negative
         | 
| 59 | 
            +
                  # in yaml 1.1, anything starting with zero is treated as octal... in 1.2, it's 0o
         | 
| 60 | 
            +
                  memo.sub!(/0+/, '') if memo =~ /\A[+\-]?0+[+\-\$]?[1-9]+/ # leading zeros
         | 
| 61 | 
            +
                  memo.delete!('$') if memo =~ /\A[+\-]?0*\$/
         | 
| 62 | 
            +
                  if memo.include?(',')
         | 
| 63 | 
            +
                    a, b = memo.split('.', 2)
         | 
| 64 | 
            +
                    a.delete! ','
         | 
| 65 | 
            +
                    memo = b ? [a, b].join('.') : a
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                not_safe_for_yaml = nil
         | 
| 70 | 
            +
                not_safe_for_yaml ||= memo.include?('#')
         | 
| 71 | 
            +
                not_safe_for_yaml ||= not_numeric && memo =~ /\A[\d,]+\z/ #1,2,3, maybe a csv
         | 
| 72 | 
            +
                safe_for_yaml = !not_safe_for_yaml
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                if safe_for_yaml
         | 
| 75 | 
            +
                  begin
         | 
| 76 | 
            +
                    memo = SafeYAML.load memo
         | 
| 77 | 
            +
                  rescue
         | 
| 78 | 
            +
                    $stderr.puts "#{memo.inspect} => #{$!}"
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                if possible_numeric
         | 
| 83 | 
            +
                  case memo
         | 
| 84 | 
            +
                  when /\A[+\-]?[\d._]+[eE][+\-]?[\d._]+\z/
         | 
| 85 | 
            +
                    # scientific notation
         | 
| 86 | 
            +
                    memo = memo.to_f
         | 
| 87 | 
            +
                  when /\A[+\-]?0o/
         | 
| 88 | 
            +
                    # octal per yaml 1.2
         | 
| 89 | 
            +
                    memo = memo.to_i 8
         | 
| 90 | 
            +
                  end
         | 
| 91 | 
            +
                end
         | 
| 92 | 
            +
                
         | 
| 93 | 
            +
                if memo.is_a?(String)
         | 
| 94 | 
            +
                  # compress whitespace
         | 
| 95 | 
            +
                  memo.gsub! /\s+/, ' '
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                memo = memo / 100.0 if percentage
         | 
| 99 | 
            +
                memo = -memo if accounting_negative
         | 
| 100 | 
            +
                memo
         | 
| 101 | 
            +
              end
         | 
| 102 | 
            +
            end
         | 
    
        data/parse.gemspec
    ADDED
    
    | @@ -0,0 +1,29 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            lib = File.expand_path('../lib', __FILE__)
         | 
| 3 | 
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 4 | 
            +
            require 'parse/version'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            Gem::Specification.new do |spec|
         | 
| 7 | 
            +
              spec.name          = "parse"
         | 
| 8 | 
            +
              spec.version       = Parse::VERSION
         | 
| 9 | 
            +
              spec.authors       = ["Seamus Abshere"]
         | 
| 10 | 
            +
              spec.email         = ["seamus@abshere.net"]
         | 
| 11 | 
            +
              spec.summary       = %q{Detect and convert short strings into integers, floats, dates, times, booleans, arrays, and hashes - "like a human would". Based on YAML and JSON.}
         | 
| 12 | 
            +
              spec.description   = %q{Detect and convert short strings into integers, floats, dates, times, booleans, arrays, and hashes - "like a human would". Based on YAML and JSON.}
         | 
| 13 | 
            +
              spec.homepage      = "https://github.com/seamusabshere/parse"
         | 
| 14 | 
            +
              spec.license       = "MIT"
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              spec.files         = `git ls-files -z`.split("\x0")
         | 
| 17 | 
            +
              spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
         | 
| 18 | 
            +
              spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
         | 
| 19 | 
            +
              spec.require_paths = ["lib"]
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              spec.add_runtime_dependency 'safe_yaml'
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              spec.add_development_dependency "bundler", "~> 1.5"
         | 
| 24 | 
            +
              spec.add_development_dependency "rake"
         | 
| 25 | 
            +
              spec.add_development_dependency "rspec"
         | 
| 26 | 
            +
              spec.add_development_dependency 'multi_json'
         | 
| 27 | 
            +
              spec.add_development_dependency 'activesupport'
         | 
| 28 | 
            +
              spec.add_development_dependency 'pry'
         | 
| 29 | 
            +
            end
         | 
    
        data/spec/parse_spec.rb
    ADDED
    
    
| @@ -0,0 +1,160 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Parse do
         | 
| 4 | 
            +
              {
         | 
| 5 | 
            +
                ''                                 => nil,
         | 
| 6 | 
            +
                'nil'                              => nil,
         | 
| 7 | 
            +
                '15'                               => 15,
         | 
| 8 | 
            +
                '15,000'                           => 15_000,
         | 
| 9 | 
            +
                '15_000'                           => 15_000,
         | 
| 10 | 
            +
                '15_00_0'                          => 15_000,
         | 
| 11 | 
            +
                '15.0'                             => 15.0,
         | 
| 12 | 
            +
                '15,000.0'                         => 15_000.0,
         | 
| 13 | 
            +
                '15_000.0'                         => 15_000.0,
         | 
| 14 | 
            +
                '15_00_0.0'                        => 15_000.0,
         | 
| 15 | 
            +
                '0015'                             => 15,   # not octal
         | 
| 16 | 
            +
                '0015.0'                           => 15.0,  # not octal
         | 
| 17 | 
            +
                '0_015.0'                          => 15.0, # just weird
         | 
| 18 | 
            +
                '0x15'                             => 0x15, # hex
         | 
| 19 | 
            +
                '0o15'                             => 015,  # octal
         | 
| 20 | 
            +
                '8e-05'                            => 8e-05,
         | 
| 21 | 
            +
                '1_2.5e-1_3'                       => 12.5e-13,
         | 
| 22 | 
            +
                '$123.4'                           => 123.4,
         | 
| 23 | 
            +
                '0$123.4'                           => 123.4,
         | 
| 24 | 
            +
                '$15,000'                          => 15_000,
         | 
| 25 | 
            +
                '0$15,000'                          => 15_000,
         | 
| 26 | 
            +
                '$123_456'                         => 123_456,
         | 
| 27 | 
            +
                '$123_456.7'                       => 123_456.7,
         | 
| 28 | 
            +
                '10,000,000'                       => 10_000_000,
         | 
| 29 | 
            +
                '10,000,000.00'                    => 10_000_000.0,
         | 
| 30 | 
            +
                '$10,000,000.00'                    => 10_000_000.0,
         | 
| 31 | 
            +
                '0$10,000,000.00'                    => 10_000_000.0,
         | 
| 32 | 
            +
                '$010,000,000.00'                    => 10_000_000.0,
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                '-15'                              => -15,
         | 
| 35 | 
            +
                '-15,000'                          => -15_000,
         | 
| 36 | 
            +
                '-15_000'                          => -15_000,
         | 
| 37 | 
            +
                '-15_00_0'                         => -15_000,
         | 
| 38 | 
            +
                '-15.0'                            => -15.0,
         | 
| 39 | 
            +
                '-15,000.0'                        => -15_000.0,
         | 
| 40 | 
            +
                '-15_000.0'                        => -15_000.0,
         | 
| 41 | 
            +
                '-15_00_0.0'                       => -15_000.0,
         | 
| 42 | 
            +
                '00-15'                            => -15,   # not octal
         | 
| 43 | 
            +
                '00-15.0'                          => -15.0,  # not octal
         | 
| 44 | 
            +
                '0_0-15.0'                         => '0_0-15.0', # just weird
         | 
| 45 | 
            +
                '-0x15'                            => -0x15, # hex
         | 
| 46 | 
            +
                '-0o15'                            => -015,  # octal
         | 
| 47 | 
            +
                '-8e-05'                           => -8e-05,
         | 
| 48 | 
            +
                '-1_2.5e-1_3'                      => -12.5e-13,
         | 
| 49 | 
            +
                '-$123.4'                          => -123.4,
         | 
| 50 | 
            +
                '($123.4)'                         => -123.4,
         | 
| 51 | 
            +
                '0($123.4)'                        => -123.4,
         | 
| 52 | 
            +
                '-$15,000'                         => -15_000,
         | 
| 53 | 
            +
                '($15,000)'                        => -15_000,
         | 
| 54 | 
            +
                '-$123_456'                        => -123_456,
         | 
| 55 | 
            +
                '($123_456)'                       => -123_456,
         | 
| 56 | 
            +
                '-$123_456.7'                      => -123_456.7,
         | 
| 57 | 
            +
                '($123_456.7)'                     => -123_456.7,
         | 
| 58 | 
            +
                '-10,000,000'                      => -10_000_000,
         | 
| 59 | 
            +
                '(10,000,000)'                     => -10_000_000,
         | 
| 60 | 
            +
                '-10,000,000.00'                   => -10_000_000.0,
         | 
| 61 | 
            +
                '(10,000,000.00)'                  => -10_000_000.0,
         | 
| 62 | 
            +
                '-10000000'                        => -10_000_000,
         | 
| 63 | 
            +
                '(10000000)'                       => -10_000_000,
         | 
| 64 | 
            +
                '-10000000.00'                     => -10_000_000.0,
         | 
| 65 | 
            +
                '(10000000.00)'                    => -10_000_000.0,
         | 
| 66 | 
            +
                '1,200'                            => 1_200,
         | 
| 67 | 
            +
                '1,200.0'                          => 1_200.0,
         | 
| 68 | 
            +
                '1,2'                              => 12,
         | 
| 69 | 
            +
                '1,20'                             => 120,
         | 
| 70 | 
            +
                '1,2.0'                            => 12.0,
         | 
| 71 | 
            +
                '1.0,2'                            => '1.0,2',
         | 
| 72 | 
            +
                '1.0,2.0'                          => '1.0,2.0',
         | 
| 73 | 
            +
                '-1,200'                           => -1_200,
         | 
| 74 | 
            +
                '-1,200.0'                         => -1_200.0,
         | 
| 75 | 
            +
                '-1,2'                             => -12,
         | 
| 76 | 
            +
                '-1,20'                            => -120,
         | 
| 77 | 
            +
                '-1,2.0'                           => -12.0,
         | 
| 78 | 
            +
                '-1.0,2'                           => '-1.0,2',
         | 
| 79 | 
            +
                '-1.0,2.0'                         => '-1.0,2.0',
         | 
| 80 | 
            +
                '01,200'                           => 1_200,
         | 
| 81 | 
            +
                '01,200.0'                         => 1_200.0,
         | 
| 82 | 
            +
                '01,2'                             => 12,
         | 
| 83 | 
            +
                '01,20'                            => 120,
         | 
| 84 | 
            +
                '01,2.0'                           => 12.0,
         | 
| 85 | 
            +
                '01.0,2'                           => '01.0,2',
         | 
| 86 | 
            +
                '01.0,2.0'                         => '01.0,2.0',
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                '05753'                            => 5753,
         | 
| 89 | 
            +
                'true'                             => true,
         | 
| 90 | 
            +
                'yes'                              => true,
         | 
| 91 | 
            +
                'false'                            => false,
         | 
| 92 | 
            +
                'no'                               => false,
         | 
| 93 | 
            +
                '#DIV/0'                           => (1.0/0),
         | 
| 94 | 
            +
                '#NAME?'                           => nil,
         | 
| 95 | 
            +
                'Inf'                              => 'Inf',
         | 
| 96 | 
            +
                'Infinity'                         => (1.0/0),
         | 
| 97 | 
            +
                '-Infinity'                        => -(1.0/0),
         | 
| 98 | 
            +
                'NaN'                              => 0.0/0, # need the dot
         | 
| 99 | 
            +
                '.NaN'                             => 0.0/0,  # NaN
         | 
| 100 | 
            +
                '-.inf'                            => -(1.0/0), # -Infinity
         | 
| 101 | 
            +
                '-'                                => nil, # per bigml
         | 
| 102 | 
            +
                '?'                                => nil,
         | 
| 103 | 
            +
                '1982-01-01'                       => Date.new(1982,1,1),
         | 
| 104 | 
            +
                '2010-05-05 13:42:16 Z'            => Time.parse('2010-05-05 13:42:16 Z'),
         | 
| 105 | 
            +
                '2010-05-05 13:42:16 -02:00'       => Time.parse('2010-05-05 13:42:16 -02:00'),
         | 
| 106 | 
            +
                ":not_a_symbol"                    => ':not_a_symbol',
         | 
| 107 | 
            +
                '#hello'                           => '#hello',
         | 
| 108 | 
            +
                "\n#hello\n#world"                 => '#hello #world',
         | 
| 109 | 
            +
                "hello\nworld"                     => 'hello world', # whitespace compression
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                '0%'                               => 0.0,
         | 
| 112 | 
            +
                '100%'                             => 1.0,
         | 
| 113 | 
            +
                '50%'                              => 0.5,
         | 
| 114 | 
            +
                '5%'                               => 0.05,
         | 
| 115 | 
            +
                '00000%'                           => 0.0,
         | 
| 116 | 
            +
                '0000100%'                         => 1.0,
         | 
| 117 | 
            +
                '000050%'                          => 0.5,
         | 
| 118 | 
            +
                '00005%'                           => 0.05,
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                ['12/25/82', {date: :us}]          => Date.new(1982,12,25),
         | 
| 121 | 
            +
                ['12/25/1982', {date: :us}]        => Date.new(1982,12,25),
         | 
| 122 | 
            +
                ['25/12/82', {date: :euro}]        => Date.new(1982,12,25),
         | 
| 123 | 
            +
                ['25/12/1982', {date: :euro}]      => Date.new(1982,12,25),
         | 
| 124 | 
            +
                ['12-25-82', {date: :us}]          => Date.new(1982,12,25),
         | 
| 125 | 
            +
                ['12-25-1982', {date: :us}]        => Date.new(1982,12,25),
         | 
| 126 | 
            +
                ['25-12-82', {date: :euro}]        => Date.new(1982,12,25),
         | 
| 127 | 
            +
                ['25-12-1982', {date: :euro}]      => Date.new(1982,12,25),
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                '12/25/82'                         => '12/25/82',
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                ',1'                               => ',1', # not a csv parser
         | 
| 132 | 
            +
                ',1,'                              => ',1,', # not a csv parser
         | 
| 133 | 
            +
                '1,2,3'                            => '1,2,3', # not a csv parser
         | 
| 134 | 
            +
                '[1,2,3]'                          => [1,2,3],
         | 
| 135 | 
            +
                YAML.dump('a' => 1)                => { 'a' => 1 },
         | 
| 136 | 
            +
                YAML.dump(a: 1)                    => { ':a' => 1 }, # doesn't parse symbols
         | 
| 137 | 
            +
                YAML.dump('a' => 1, 5 => "c\n3")   => { 'a' => 1, 5 => "c\n3" },
         | 
| 138 | 
            +
                MultiJson.dump(a: 1)               => { 'a' => 1 }, # json always loses symbols
         | 
| 139 | 
            +
                MultiJson.dump(a: 1, 5 => "c\n3")  => { 'a' => 1, '5' => "c\n3" },
         | 
| 140 | 
            +
              }.each do |input, expected|
         | 
| 141 | 
            +
                it "parses #{input.inspect} as #{expected.inspect}" do
         | 
| 142 | 
            +
                  input = Array.wrap input
         | 
| 143 | 
            +
                  got = Parse.ver0_0_1(*input)
         | 
| 144 | 
            +
                  # $lines << [ "Parse.parse(#{input.inspect})".ljust(45), "#=> #{got.inspect}" ].join
         | 
| 145 | 
            +
                  if expected.is_a?(Float) and expected.nan?
         | 
| 146 | 
            +
                    expect(got.nan?).to eq(true)
         | 
| 147 | 
            +
                  else
         | 
| 148 | 
            +
                    expect(got).to eq(expected)
         | 
| 149 | 
            +
                  end
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                  input_with_spaces = [ "\t" + input[0] + "\t", input[1] ]
         | 
| 152 | 
            +
                  got_with_spaces = Parse.ver0_0_1(*input_with_spaces)
         | 
| 153 | 
            +
                  if expected.is_a?(Float) and expected.nan?
         | 
| 154 | 
            +
                    expect(got.nan?).to eq(true)
         | 
| 155 | 
            +
                  else
         | 
| 156 | 
            +
                    expect(got_with_spaces).to eq(expected)
         | 
| 157 | 
            +
                  end
         | 
| 158 | 
            +
                end
         | 
| 159 | 
            +
              end
         | 
| 160 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    ADDED
    
    
    
        metadata
    ADDED
    
    | @@ -0,0 +1,161 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: parse
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.0.1.1
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Seamus Abshere
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2014-02-07 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: safe_yaml
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - ">="
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '0'
         | 
| 20 | 
            +
              type: :runtime
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - ">="
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '0'
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: bundler
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - "~>"
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: '1.5'
         | 
| 34 | 
            +
              type: :development
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - "~>"
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: '1.5'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: rake
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - ">="
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: '0'
         | 
| 48 | 
            +
              type: :development
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - ">="
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '0'
         | 
| 55 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 56 | 
            +
              name: rspec
         | 
| 57 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 | 
            +
                requirements:
         | 
| 59 | 
            +
                - - ">="
         | 
| 60 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            +
                    version: '0'
         | 
| 62 | 
            +
              type: :development
         | 
| 63 | 
            +
              prerelease: false
         | 
| 64 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 | 
            +
                requirements:
         | 
| 66 | 
            +
                - - ">="
         | 
| 67 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            +
                    version: '0'
         | 
| 69 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            +
              name: multi_json
         | 
| 71 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 | 
            +
                requirements:
         | 
| 73 | 
            +
                - - ">="
         | 
| 74 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            +
                    version: '0'
         | 
| 76 | 
            +
              type: :development
         | 
| 77 | 
            +
              prerelease: false
         | 
| 78 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 | 
            +
                requirements:
         | 
| 80 | 
            +
                - - ">="
         | 
| 81 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 82 | 
            +
                    version: '0'
         | 
| 83 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 84 | 
            +
              name: activesupport
         | 
| 85 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 | 
            +
                requirements:
         | 
| 87 | 
            +
                - - ">="
         | 
| 88 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 89 | 
            +
                    version: '0'
         | 
| 90 | 
            +
              type: :development
         | 
| 91 | 
            +
              prerelease: false
         | 
| 92 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 | 
            +
                requirements:
         | 
| 94 | 
            +
                - - ">="
         | 
| 95 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 96 | 
            +
                    version: '0'
         | 
| 97 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 98 | 
            +
              name: pry
         | 
| 99 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 100 | 
            +
                requirements:
         | 
| 101 | 
            +
                - - ">="
         | 
| 102 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 103 | 
            +
                    version: '0'
         | 
| 104 | 
            +
              type: :development
         | 
| 105 | 
            +
              prerelease: false
         | 
| 106 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 107 | 
            +
                requirements:
         | 
| 108 | 
            +
                - - ">="
         | 
| 109 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 110 | 
            +
                    version: '0'
         | 
| 111 | 
            +
            description: Detect and convert short strings into integers, floats, dates, times,
         | 
| 112 | 
            +
              booleans, arrays, and hashes - "like a human would". Based on YAML and JSON.
         | 
| 113 | 
            +
            email:
         | 
| 114 | 
            +
            - seamus@abshere.net
         | 
| 115 | 
            +
            executables: []
         | 
| 116 | 
            +
            extensions: []
         | 
| 117 | 
            +
            extra_rdoc_files: []
         | 
| 118 | 
            +
            files:
         | 
| 119 | 
            +
            - ".gitignore"
         | 
| 120 | 
            +
            - ".rspec"
         | 
| 121 | 
            +
            - ".travis.yml"
         | 
| 122 | 
            +
            - CHANGELOG
         | 
| 123 | 
            +
            - Gemfile
         | 
| 124 | 
            +
            - LICENSE.txt
         | 
| 125 | 
            +
            - README.md
         | 
| 126 | 
            +
            - Rakefile
         | 
| 127 | 
            +
            - lib/parse.rb
         | 
| 128 | 
            +
            - lib/parse/version.rb
         | 
| 129 | 
            +
            - parse.gemspec
         | 
| 130 | 
            +
            - spec/parse_spec.rb
         | 
| 131 | 
            +
            - spec/parse_ver0_0_1_spec.rb
         | 
| 132 | 
            +
            - spec/spec_helper.rb
         | 
| 133 | 
            +
            homepage: https://github.com/seamusabshere/parse
         | 
| 134 | 
            +
            licenses:
         | 
| 135 | 
            +
            - MIT
         | 
| 136 | 
            +
            metadata: {}
         | 
| 137 | 
            +
            post_install_message: 
         | 
| 138 | 
            +
            rdoc_options: []
         | 
| 139 | 
            +
            require_paths:
         | 
| 140 | 
            +
            - lib
         | 
| 141 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 142 | 
            +
              requirements:
         | 
| 143 | 
            +
              - - ">="
         | 
| 144 | 
            +
                - !ruby/object:Gem::Version
         | 
| 145 | 
            +
                  version: '0'
         | 
| 146 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 147 | 
            +
              requirements:
         | 
| 148 | 
            +
              - - ">="
         | 
| 149 | 
            +
                - !ruby/object:Gem::Version
         | 
| 150 | 
            +
                  version: '0'
         | 
| 151 | 
            +
            requirements: []
         | 
| 152 | 
            +
            rubyforge_project: 
         | 
| 153 | 
            +
            rubygems_version: 2.2.1
         | 
| 154 | 
            +
            signing_key: 
         | 
| 155 | 
            +
            specification_version: 4
         | 
| 156 | 
            +
            summary: Detect and convert short strings into integers, floats, dates, times, booleans,
         | 
| 157 | 
            +
              arrays, and hashes - "like a human would". Based on YAML and JSON.
         | 
| 158 | 
            +
            test_files:
         | 
| 159 | 
            +
            - spec/parse_spec.rb
         | 
| 160 | 
            +
            - spec/parse_ver0_0_1_spec.rb
         | 
| 161 | 
            +
            - spec/spec_helper.rb
         |