attparser 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +58 -0
- data/lib/attparser.rb +129 -0
- metadata +45 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7da2181748d2b153f2f668e93d938759b8a944d167f79a657c662370f3df3794
|
4
|
+
data.tar.gz: 518522c1bcbb049c8f801f67f7049df314b38ea9ff08fe91c49386f2c2f582a1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: eb8eb8b5dc1455fa8411805f7efb89d94fc32c9deb737262168e3f4881b70b8e651abb69586b0e4604f50ac14d87b865c478382c4a4de15ac0515d31b5e9d3fd
|
7
|
+
data.tar.gz: d27989e050df57bcb24ba44a02f2f00104a3510a282df65a7e8c562c2c59ec796fd8ba59d2700d42c5442d6c93c0d3f23093c888d50677ae864ecaa269839aa1
|
data/README.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# AttParser
|
2
|
+
|
3
|
+
AttParser parses a string like you might find in an HTML tag. Optionally, it will
|
4
|
+
convert certain values into other classes like Integer or TrueClass.
|
5
|
+
|
6
|
+
In its simplest use, give AttParser a string that is formatted like the
|
7
|
+
attributes in HTML. Then run the string through `AttParser.parse()`. That method
|
8
|
+
will return a hash.
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
raw = 'whatever="dude" ready YEAH=man'
|
12
|
+
atts = AttParser.parse(raw)
|
13
|
+
atts['whatever'] # => "dude"
|
14
|
+
atts['ready'] # => nil
|
15
|
+
atts['yeah'] # => "man"
|
16
|
+
```
|
17
|
+
|
18
|
+
The attribute names are downcased. Values quotes are returned as string. Values
|
19
|
+
without spaces are returned as string. If an attribute does not have a value
|
20
|
+
(i.e. there is no equals sign) then the value is `nil`.
|
21
|
+
|
22
|
+
## Infer
|
23
|
+
|
24
|
+
If you add the `infer` option then certain values are inferred as objects other
|
25
|
+
than strings. NOTE: Only unquoted strings are inferred, never quoted strings.
|
26
|
+
Quoted strings are always returned as strings.
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
raw = 'my-false=false my-true=true my-int=-2 my-float=3.4 my-nil=nil'
|
30
|
+
atts = AttParser.parse(raw, 'infer'=>true)
|
31
|
+
atts['my-false'].class # => FalseClass
|
32
|
+
atts['my-true'].class # => TrueClass
|
33
|
+
atts['my-int'].class # => Integer
|
34
|
+
atts['my-float'].class # => Float
|
35
|
+
atts['my-nil'].class # => NilClass
|
36
|
+
```
|
37
|
+
|
38
|
+
## That's it
|
39
|
+
|
40
|
+
That's what AttParser does. If you want to get more complex, it's probably best
|
41
|
+
to use JSON.
|
42
|
+
|
43
|
+
## Install
|
44
|
+
|
45
|
+
```
|
46
|
+
gem install attparser
|
47
|
+
```
|
48
|
+
|
49
|
+
## Author
|
50
|
+
|
51
|
+
Mike O'Sullivan
|
52
|
+
mike@idocs.com
|
53
|
+
|
54
|
+
## History
|
55
|
+
|
56
|
+
| version | date | notes |
|
57
|
+
|---------|---------------|-------------------------------------------------------|
|
58
|
+
| 1.0 | June 18, 2020 | Initial upload. |
|
data/lib/attparser.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
#===============================================================================
|
2
|
+
# AttParser
|
3
|
+
#
|
4
|
+
module AttParser
|
5
|
+
# version
|
6
|
+
VERSION = '1.0'
|
7
|
+
|
8
|
+
#---------------------------------------------------------------------------
|
9
|
+
# parse
|
10
|
+
#
|
11
|
+
def self.parse(raw, opts={})
|
12
|
+
# $tm.hrm
|
13
|
+
raw = raw.strip
|
14
|
+
state = 'none'
|
15
|
+
name = nil
|
16
|
+
val = nil
|
17
|
+
atts = {}
|
18
|
+
infer = opts['infer']
|
19
|
+
|
20
|
+
# split
|
21
|
+
tokens = raw.split(/(\\")|(")|(\=)|(\s+)/mu)
|
22
|
+
tokens = tokens.grep(/./mu)
|
23
|
+
|
24
|
+
# loop through tokens
|
25
|
+
tokens.each do |token|
|
26
|
+
# state: none
|
27
|
+
if state == 'none'
|
28
|
+
if token.match(/\S/mu)
|
29
|
+
name = token.downcase
|
30
|
+
val = nil
|
31
|
+
state = 'after-name'
|
32
|
+
end
|
33
|
+
|
34
|
+
# state: after-name
|
35
|
+
elsif state == 'after-name'
|
36
|
+
if token.match(/./mu)
|
37
|
+
if token == '='
|
38
|
+
state = 'after-equals'
|
39
|
+
elsif token.match(/\S/mu)
|
40
|
+
atts[name] = nil
|
41
|
+
name = token
|
42
|
+
val = nil
|
43
|
+
state = 'after-name'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# state: after-equals
|
48
|
+
elsif state == 'after-equals'
|
49
|
+
if token == '"'
|
50
|
+
val = ''
|
51
|
+
state = 'in-quote'
|
52
|
+
elsif token.match(/\S/mu)
|
53
|
+
atts[name] = self.infer(infer, token)
|
54
|
+
name = val = nil
|
55
|
+
state = 'none'
|
56
|
+
end
|
57
|
+
|
58
|
+
# state: in-quote
|
59
|
+
elsif state == 'in-quote'
|
60
|
+
if token == '"'
|
61
|
+
atts[name] = val
|
62
|
+
name = val = nil
|
63
|
+
state = 'none'
|
64
|
+
elsif token == '\\"'
|
65
|
+
val += '"'
|
66
|
+
else
|
67
|
+
val += token
|
68
|
+
end
|
69
|
+
|
70
|
+
# else unknown state
|
71
|
+
else
|
72
|
+
raise 'uknown-state: ' + state
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# if name, add to atts
|
77
|
+
if name
|
78
|
+
atts[name] = nil
|
79
|
+
end
|
80
|
+
|
81
|
+
# return
|
82
|
+
return atts
|
83
|
+
end
|
84
|
+
#
|
85
|
+
# parse
|
86
|
+
#---------------------------------------------------------------------------
|
87
|
+
|
88
|
+
|
89
|
+
#---------------------------------------------------------------------------
|
90
|
+
# infer
|
91
|
+
#
|
92
|
+
def self.infer(infer, val)
|
93
|
+
# $tm.hrm
|
94
|
+
|
95
|
+
# early exit: don't infer
|
96
|
+
infer or return val
|
97
|
+
|
98
|
+
# true
|
99
|
+
if val.downcase == 'true'
|
100
|
+
return true
|
101
|
+
|
102
|
+
# false
|
103
|
+
elsif val.downcase == 'false'
|
104
|
+
return false
|
105
|
+
|
106
|
+
# null or nil
|
107
|
+
elsif (val.downcase == 'null') or (val.downcase == 'nil')
|
108
|
+
return nil
|
109
|
+
|
110
|
+
# integer
|
111
|
+
elsif rv = Integer(val) rescue false
|
112
|
+
return rv
|
113
|
+
|
114
|
+
# float
|
115
|
+
elsif rv = Float(val) rescue false
|
116
|
+
return rv
|
117
|
+
|
118
|
+
# else return value as is
|
119
|
+
else
|
120
|
+
return val
|
121
|
+
end
|
122
|
+
end
|
123
|
+
#
|
124
|
+
# infer
|
125
|
+
#---------------------------------------------------------------------------
|
126
|
+
end
|
127
|
+
#
|
128
|
+
# AttParser
|
129
|
+
#===============================================================================
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: attparser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mike O'Sullivan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-06-18 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Parse a string of attributes like you might find in an XML tag
|
14
|
+
email: mike@idocs.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- README.md
|
20
|
+
- lib/attparser.rb
|
21
|
+
homepage: https://rubygems.org/gems/attparser
|
22
|
+
licenses:
|
23
|
+
- MIT
|
24
|
+
metadata: {}
|
25
|
+
post_install_message:
|
26
|
+
rdoc_options: []
|
27
|
+
require_paths:
|
28
|
+
- lib
|
29
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
requirements: []
|
40
|
+
rubyforge_project:
|
41
|
+
rubygems_version: 2.7.6
|
42
|
+
signing_key:
|
43
|
+
specification_version: 4
|
44
|
+
summary: Parse a string of attributes
|
45
|
+
test_files: []
|