opmlparser 0.1.0
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/CHANGELOG.md +4 -0
- data/Manifest.txt +11 -0
- data/README.md +259 -0
- data/Rakefile +28 -0
- data/lib/opmlparser.rb +175 -0
- data/lib/opmlparser/version.rb +20 -0
- data/test/helper.rb +7 -0
- data/test/outlines/category.opml.xml +9 -0
- data/test/outlines/places_lived.opml.xml +42 -0
- data/test/outlines/states.opml.xml +90 -0
- data/test/test_opml.rb +44 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1455ca218d239221d91a9a7a6e7e0abeded5eec6
|
4
|
+
data.tar.gz: 7c0235eae9f9f68a4d265fc6e6201626d4fa8959
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f195f8738c2982242ff251e31ec1595c3af4b1d00cde8d5c2141bf80dd93afb8b777c80e1dff62fe7f403526743a5569aac068d5dac487bcc7e1d5468294c171
|
7
|
+
data.tar.gz: 2eba54b6d6cd14b72b188ffbdd7e1bdc668bedc1a76e5de11a5006e99f8b08ac75a94e087f50a9b6f36a921ba896657b4b2688d5d11161d4ada6d45c5ac22316
|
data/CHANGELOG.md
ADDED
data/Manifest.txt
ADDED
data/README.md
ADDED
@@ -0,0 +1,259 @@
|
|
1
|
+
# opmlparser gem - read / parse outlines (incl. feed subscription lists) in the OPML (Outline Processor Markup Language) format in xml
|
2
|
+
|
3
|
+
|
4
|
+
* home :: [github.com/feedreader/pluto](https://github.com/feedreader/pluto)
|
5
|
+
* bugs :: [github.com/feedreader/pluto/issues](https://github.com/feedreader/pluto/issues)
|
6
|
+
* gem :: [rubygems.org/gems/opmlparser](https://rubygems.org/gems/opmlparser)
|
7
|
+
* rdoc :: [rubydoc.info/gems/opmlparser](http://rubydoc.info/gems/opmlparser)
|
8
|
+
* forum :: [groups.google.com/group/wwwmake](http://groups.google.com/group/wwwmake)
|
9
|
+
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
`OPML.load` • `OPML.load_file`
|
14
|
+
|
15
|
+
|
16
|
+
Option 1) `OPML.load` - load from string. Example:
|
17
|
+
|
18
|
+
``` ruby
|
19
|
+
hash = OPML.load( <<TXT )
|
20
|
+
<opml version="1.1">
|
21
|
+
<head>
|
22
|
+
<title>Planet Ruby</title>
|
23
|
+
<dateCreated>Mon, 02 Mar 2020 08:21:56 -0000</dateCreated>
|
24
|
+
</head>
|
25
|
+
<body>
|
26
|
+
<outline text="Ruby Lang News" xmlUrl="http://www.ruby-lang.org/en/feeds/news.rss"/>
|
27
|
+
<outline text="JRuby Lang News" xmlUrl="http://www.jruby.org/atom.xml"/>
|
28
|
+
<outline text="RubyGems News" xmlUrl="http://blog.rubygems.org/atom.xml"/>
|
29
|
+
<outline text="Sinatra News" xmlUrl="http://sinatrarb.com/feed.xml"/>
|
30
|
+
<outline text="Hanami News" xmlUrl="https://hanamirb.org/atom.xml"/>
|
31
|
+
<outline text="Jekyll News" xmlUrl="http://jekyllrb.com/feed.xml"/>
|
32
|
+
</body>
|
33
|
+
</opml>
|
34
|
+
TXT
|
35
|
+
```
|
36
|
+
|
37
|
+
|
38
|
+
Option 2) `OPML.load_file` - load from file (shortcut). Example:
|
39
|
+
|
40
|
+
``` ruby
|
41
|
+
hash = OPML.load_file( './planet.opml.xml' )
|
42
|
+
```
|
43
|
+
|
44
|
+
|
45
|
+
All together now. Example:
|
46
|
+
|
47
|
+
``` ruby
|
48
|
+
require 'opmlparser'
|
49
|
+
|
50
|
+
xml = <<TXT
|
51
|
+
<opml version="1.1">
|
52
|
+
<head>
|
53
|
+
<title>Planet Ruby</title>
|
54
|
+
<dateCreated>Mon, 02 Mar 2020 08:21:56 -0000</dateCreated>
|
55
|
+
</head>
|
56
|
+
<body>
|
57
|
+
<outline text="Ruby Lang News" xmlUrl="http://www.ruby-lang.org/en/feeds/news.rss"/>
|
58
|
+
<outline text="JRuby Lang News" xmlUrl="http://www.jruby.org/atom.xml"/>
|
59
|
+
<outline text="RubyGems News" xmlUrl="http://blog.rubygems.org/atom.xml"/>
|
60
|
+
<outline text="Sinatra News" xmlUrl="http://sinatrarb.com/feed.xml"/>
|
61
|
+
<outline text="Hanami News" xmlUrl="https://hanamirb.org/atom.xml"/>
|
62
|
+
<outline text="Jekyll News" xmlUrl="http://jekyllrb.com/feed.xml"/>
|
63
|
+
</body>
|
64
|
+
</opml>
|
65
|
+
TXT
|
66
|
+
|
67
|
+
hash = OPML.load( xml )
|
68
|
+
pp hash
|
69
|
+
```
|
70
|
+
|
71
|
+
resulting in:
|
72
|
+
|
73
|
+
``` ruby
|
74
|
+
{"meta"=>
|
75
|
+
{"title"=>"Planet Ruby",
|
76
|
+
"dateCreated"=>"Mon, 02 Mar 2020 08:21:56 -0000"},
|
77
|
+
"outline"=>
|
78
|
+
[{"text"=>"Ruby Lang News", "xmlUrl"=>"http://www.ruby-lang.org/en/feeds/news.rss"},
|
79
|
+
{"text"=>"JRuby Lang News", "xmlUrl"=>"http://www.jruby.org/atom.xml"},
|
80
|
+
{"text"=>"RubyGems News", "xmlUrl"=>"http://blog.rubygems.org/atom.xml"},
|
81
|
+
{"text"=>"Sinatra News", "xmlUrl"=>"http://sinatrarb.com/feed.xml"},
|
82
|
+
{"text"=>"Hanami News", "xmlUrl"=>"https://hanamirb.org/atom.xml"},
|
83
|
+
{"text"=>"Jekyll News", "xmlUrl"=>"http://jekyllrb.com/feed.xml"}]}
|
84
|
+
```
|
85
|
+
|
86
|
+
to access use:
|
87
|
+
|
88
|
+
``` ruby
|
89
|
+
hash['meta']['title'] #=> "Planet Ruby"
|
90
|
+
hash['outline'][0]['text'] #=> "Ruby Lang News"
|
91
|
+
hash['outline'][0]['xmlUrl'] #=> "http://www.ruby-lang.org/en/feeds/news.rss"
|
92
|
+
hash['outline'][1]['text'] #=> "JRuby Lang News"
|
93
|
+
hash['outline'][1]['xmlUrl'] #=> "http://www.jruby.org/atom.xml"
|
94
|
+
```
|
95
|
+
|
96
|
+
|
97
|
+
What about using a "type-safe" outline struct(ure)?
|
98
|
+
|
99
|
+
`Outline.parse` • `Outline.read`
|
100
|
+
|
101
|
+
Option 1) `Outline.parse` - parse from string. Example:
|
102
|
+
|
103
|
+
``` ruby
|
104
|
+
outline = Outline.parse( <<TXT )
|
105
|
+
<opml version="1.1">
|
106
|
+
<head>
|
107
|
+
<title>Planet Ruby</title>
|
108
|
+
<dateCreated>Mon, 02 Mar 2020 08:21:56 -0000</dateCreated>
|
109
|
+
</head>
|
110
|
+
<body>
|
111
|
+
<outline text="Ruby Lang News" xmlUrl="http://www.ruby-lang.org/en/feeds/news.rss"/>
|
112
|
+
<outline text="JRuby Lang News" xmlUrl="http://www.jruby.org/atom.xml"/>
|
113
|
+
<outline text="RubyGems News" xmlUrl="http://blog.rubygems.org/atom.xml"/>
|
114
|
+
<outline text="Sinatra News" xmlUrl="http://sinatrarb.com/feed.xml"/>
|
115
|
+
<outline text="Hanami News" xmlUrl="https://hanamirb.org/atom.xml"/>
|
116
|
+
<outline text="Jekyll News" xmlUrl="http://jekyllrb.com/feed.xml"/>
|
117
|
+
</body>
|
118
|
+
</opml>
|
119
|
+
TXT
|
120
|
+
```
|
121
|
+
|
122
|
+
Option 2) `Outline.read` - read from file (shortcut). Example:
|
123
|
+
|
124
|
+
``` ruby
|
125
|
+
outline = Outline.read( './planet.opml.xml' )
|
126
|
+
```
|
127
|
+
|
128
|
+
to access use:
|
129
|
+
|
130
|
+
``` ruby
|
131
|
+
outline.meta.title #=> "Planet Ruby"
|
132
|
+
outline[0].text #=> "Ruby Lang News"
|
133
|
+
outline[0].xml_url #=> "http://www.ruby-lang.org/en/feeds/news.rss"
|
134
|
+
outline[1].text #=> "JRuby Lang News"
|
135
|
+
outline[1].xml_url #=> "http://www.jruby.org/atom.xml"
|
136
|
+
```
|
137
|
+
|
138
|
+
|
139
|
+
What about "non-flat" nested tree outlines?
|
140
|
+
|
141
|
+
Example - `states.opml.xml`:
|
142
|
+
|
143
|
+
``` xml
|
144
|
+
<opml version="2.0">
|
145
|
+
<head>
|
146
|
+
<title>states.opml</title>
|
147
|
+
<dateCreated>Tue, 15 Mar 2005 16:35:45 GMT</dateCreated>
|
148
|
+
<dateModified>Thu, 14 Jul 2005 23:41:05 GMT</dateModified>
|
149
|
+
<ownerName>Dave Winer</ownerName>
|
150
|
+
<ownerEmail>dave@scripting.com</ownerEmail>
|
151
|
+
</head>
|
152
|
+
<body>
|
153
|
+
<outline text="United States">
|
154
|
+
<outline text="Far West">
|
155
|
+
<outline text="Alaska"/>
|
156
|
+
<outline text="California"/>
|
157
|
+
<outline text="Hawaii"/>
|
158
|
+
<outline text="Nevada">
|
159
|
+
<outline text="Reno" created="Tue, 12 Jul 2005 23:56:35 GMT"/>
|
160
|
+
<outline text="Las Vegas" created="Tue, 12 Jul 2005 23:56:37 GMT"/>
|
161
|
+
<outline text="Ely" created="Tue, 12 Jul 2005 23:56:39 GMT"/>
|
162
|
+
<outline text="Gerlach" created="Tue, 12 Jul 2005 23:56:47 GMT"/>
|
163
|
+
</outline>
|
164
|
+
<outline text="Oregon"/>
|
165
|
+
<outline text="Washington"/>
|
166
|
+
</outline>
|
167
|
+
<outline text="Great Plains">
|
168
|
+
<outline text="Kansas"/>
|
169
|
+
<outline text="Nebraska"/>
|
170
|
+
<outline text="North Dakota"/>
|
171
|
+
<outline text="Oklahoma"/>
|
172
|
+
<outline text="South Dakota"/>
|
173
|
+
</outline>
|
174
|
+
<outline text="Mid-Atlantic">
|
175
|
+
<outline text="Delaware"/>
|
176
|
+
<outline text="Maryland"/>
|
177
|
+
<outline text="New Jersey"/>
|
178
|
+
<outline text="New York"/>
|
179
|
+
<outline text="Pennsylvania"/>
|
180
|
+
</outline>
|
181
|
+
<outline text="Midwest">
|
182
|
+
<outline text="Illinois"/>
|
183
|
+
<outline text="Indiana"/>
|
184
|
+
<outline text="Iowa"/>
|
185
|
+
<outline text="Kentucky"/>
|
186
|
+
<outline text="Michigan"/>
|
187
|
+
<outline text="Minnesota"/>
|
188
|
+
<outline text="Missouri"/>
|
189
|
+
<outline text="Ohio"/>
|
190
|
+
<outline text="West Virginia"/>
|
191
|
+
<outline text="Wisconsin"/>
|
192
|
+
</outline>
|
193
|
+
<outline text="Mountains">
|
194
|
+
<outline text="Colorado"/>
|
195
|
+
<outline text="Idaho"/>
|
196
|
+
<outline text="Montana"/>
|
197
|
+
<outline text="Utah"/>
|
198
|
+
<outline text="Wyoming"/>
|
199
|
+
</outline>
|
200
|
+
<outline text="New England">
|
201
|
+
<outline text="Connecticut"/>
|
202
|
+
<outline text="Maine"/>
|
203
|
+
<outline text="Massachusetts"/>
|
204
|
+
<outline text="New Hampshire"/>
|
205
|
+
<outline text="Rhode Island"/>
|
206
|
+
<outline text="Vermont"/>
|
207
|
+
</outline>
|
208
|
+
<outline text="South">
|
209
|
+
<outline text="Alabama"/>
|
210
|
+
<outline text="Arkansas"/>
|
211
|
+
<outline text="Florida"/>
|
212
|
+
<outline text="Georgia"/>
|
213
|
+
<outline text="Louisiana"/>
|
214
|
+
<outline text="Mississippi"/>
|
215
|
+
<outline text="North Carolina"/>
|
216
|
+
<outline text="South Carolina"/>
|
217
|
+
<outline text="Tennessee"/>
|
218
|
+
<outline text="Virginia"/>
|
219
|
+
</outline>
|
220
|
+
<outline text="Southwest">
|
221
|
+
<outline text="Arizona"/>
|
222
|
+
<outline text="New Mexico"/>
|
223
|
+
<outline text="Texas"/>
|
224
|
+
</outline>
|
225
|
+
</outline>
|
226
|
+
</body>
|
227
|
+
</opml>
|
228
|
+
```
|
229
|
+
|
230
|
+
Yes, use `OPML.load` / `load_file`. To access use:
|
231
|
+
|
232
|
+
``` ruby
|
233
|
+
hash['outline'][0]['text'] #=> "United States"
|
234
|
+
hash['outline'][0]['outline'][0]['text'] #=> "Far West"
|
235
|
+
hash['outline'][0]['outline'][0]['outline'][0]['text'] #=> "Alaska"
|
236
|
+
hash['outline'][0]['outline'][1]['text'] #=> "Great Plains"
|
237
|
+
```
|
238
|
+
|
239
|
+
Or use `Outline.parse` / `read`. To access use:
|
240
|
+
|
241
|
+
``` ruby
|
242
|
+
outline[0].text #=> "United States"
|
243
|
+
outline[0][0].text #=> "Far West"
|
244
|
+
outline[0][0][0].text #=> "Alaska"
|
245
|
+
outline[0][1].text #=> "Great Plains"
|
246
|
+
```
|
247
|
+
|
248
|
+
That's all for now.
|
249
|
+
|
250
|
+
|
251
|
+
## License
|
252
|
+
|
253
|
+
The `opmlparser` scripts are dedicated to the public domain.
|
254
|
+
Use it as you please with no restrictions whatsoever.
|
255
|
+
|
256
|
+
## Questions? Comments?
|
257
|
+
|
258
|
+
Send them along to the [wwwmake Forum/Mailing List](http://groups.google.com/group/wwwmake).
|
259
|
+
Thanks!
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'hoe'
|
2
|
+
require './lib/opmlparser/version.rb'
|
3
|
+
|
4
|
+
Hoe.spec 'opmlparser' do
|
5
|
+
|
6
|
+
self.version = OPML::VERSION
|
7
|
+
|
8
|
+
self.summary = "opmlparser - read / parse outlines (incl. feed subscription lists) in the OPML (Outline Processor Markup Language) format in xml"
|
9
|
+
self.description = summary
|
10
|
+
|
11
|
+
self.urls = ['https://github.com/feedreader/pluto']
|
12
|
+
|
13
|
+
self.author = 'Gerald Bauer'
|
14
|
+
self.email = 'wwwmake@googlegroups.com'
|
15
|
+
|
16
|
+
# switch extension to .markdown for gihub formatting
|
17
|
+
self.readme_file = 'README.md'
|
18
|
+
self.history_file = 'CHANGELOG.md'
|
19
|
+
|
20
|
+
self.extra_deps = []
|
21
|
+
|
22
|
+
self.licenses = ['Public Domain']
|
23
|
+
|
24
|
+
self.spec_extras = {
|
25
|
+
required_ruby_version: '>= 2.2.2'
|
26
|
+
}
|
27
|
+
|
28
|
+
end
|
data/lib/opmlparser.rb
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require 'date'
|
3
|
+
require 'time'
|
4
|
+
require 'rexml/Document'
|
5
|
+
|
6
|
+
|
7
|
+
# our own code
|
8
|
+
require 'opmlparser/version' # note: let version always go first
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
module OPML
|
13
|
+
|
14
|
+
def self.load( xml )
|
15
|
+
parse( xml, outlinify: false )
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.load_file( path )
|
19
|
+
xml = File.open( path, 'r:utf-8' ) { |f| f.read }
|
20
|
+
load( xml )
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
#####################################
|
25
|
+
### helper methods
|
26
|
+
## (internal) helper method
|
27
|
+
def self.parse( xml, outlinify: false )
|
28
|
+
opml = REXML::Document.new( xml )
|
29
|
+
|
30
|
+
### parse head
|
31
|
+
meta = {}
|
32
|
+
opml.elements['opml/head'].elements.each do |el|
|
33
|
+
meta[ el.name ] = el.text
|
34
|
+
end
|
35
|
+
|
36
|
+
## parse body
|
37
|
+
outline = []
|
38
|
+
parse_outline( outline, opml.elements['opml/body'], outlinify: outlinify )
|
39
|
+
|
40
|
+
if outlinify
|
41
|
+
Outline.new( { 'meta' => Outline::Meta.new( meta ),
|
42
|
+
'outline' => outline } )
|
43
|
+
else
|
44
|
+
{ 'meta' => meta,
|
45
|
+
'outline' => outline }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.parse_outline( outlines, node, outlinify:)
|
50
|
+
node.elements.each( 'outline' ) do |el|
|
51
|
+
outline = {}
|
52
|
+
|
53
|
+
el.attributes.each do |attr|
|
54
|
+
outline[ attr[0] ] = attr[1]
|
55
|
+
end
|
56
|
+
|
57
|
+
if el.elements.size > 0
|
58
|
+
children = []
|
59
|
+
parse_outline( children, el, outlinify: outlinify )
|
60
|
+
outline[ 'outline' ] = children
|
61
|
+
end
|
62
|
+
|
63
|
+
## todo/fix: find a better name - use easyaccess or something?
|
64
|
+
## outlinify - wrap hash for easy access in Outline class
|
65
|
+
outlines << if outlinify ## wrap in Outline
|
66
|
+
Outline.new( outline )
|
67
|
+
else
|
68
|
+
outline
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
class Outline
|
75
|
+
def self.parse( xml )
|
76
|
+
Parser.new( xml ).parse
|
77
|
+
end
|
78
|
+
def self.read( path )
|
79
|
+
xml = File.open( path, 'r:utf-8' ) { |f| f.read }
|
80
|
+
parse( xml )
|
81
|
+
end
|
82
|
+
|
83
|
+
class << self ## add aliases
|
84
|
+
alias_method :load, :parse ## todo/check: add load alias - why? why not?
|
85
|
+
alias_method :load_file, :read ## todo/check: add load_file alias - why? why not?
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
class Parser
|
90
|
+
def initialize( xml )
|
91
|
+
@xml = xml
|
92
|
+
end
|
93
|
+
|
94
|
+
def parse
|
95
|
+
OPML.parse( @xml, outlinify: true )
|
96
|
+
end
|
97
|
+
end # class Parser
|
98
|
+
|
99
|
+
|
100
|
+
class Meta
|
101
|
+
def initialize( h )
|
102
|
+
@h = h
|
103
|
+
end
|
104
|
+
|
105
|
+
def [](key) @h[key]; end
|
106
|
+
|
107
|
+
def title() @h['title']; end
|
108
|
+
def dateCreated() @h['dateCreated' ]; end
|
109
|
+
alias_method :date_created, :dateCreated
|
110
|
+
alias_method :created, :dateCreated
|
111
|
+
|
112
|
+
def dateModified() @h['dateModified']; end
|
113
|
+
alias_method :date_modified, :dateModified
|
114
|
+
alias_method :modified, :dateModified
|
115
|
+
|
116
|
+
def ownerName() @h['ownerName']; end
|
117
|
+
alias_method :owner_name, :ownerName
|
118
|
+
|
119
|
+
def ownerEmail() @h['ownerEmail']; end
|
120
|
+
alias_method :owner_email, :ownerEmail
|
121
|
+
|
122
|
+
def ownerId() @h['ownerId']; end
|
123
|
+
alias_method :owner_id, :ownerId
|
124
|
+
end # class Meta
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
def initialize( h )
|
129
|
+
@h = h
|
130
|
+
end
|
131
|
+
|
132
|
+
def [](index)
|
133
|
+
if index.is_a?(Integer)
|
134
|
+
h = @h['outline'][index]
|
135
|
+
h = Outline.new( h ) if h.is_a?(Hash) ## allow "on-demand" use/wrapping too - why? why not?
|
136
|
+
h
|
137
|
+
else ## assume index is a text key
|
138
|
+
@h[ index ]
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
## array delegates for outline children
|
143
|
+
## todo/fix: check if outline can be nil? !!!!
|
144
|
+
def size() @h['outline'].size; end
|
145
|
+
alias_method :length, :size
|
146
|
+
|
147
|
+
def each( &blk ) @h['outline'].each( &blk ); end
|
148
|
+
|
149
|
+
|
150
|
+
def text() @h['text']; end
|
151
|
+
def xmlUrl() @h['xmlUrl']; end
|
152
|
+
alias_method :xml_url, :xmlUrl
|
153
|
+
|
154
|
+
def url() @h['url']; end
|
155
|
+
def htmlUrl() @h['htmlUrl']; end
|
156
|
+
alias_method :html_url, :htmlUrl
|
157
|
+
|
158
|
+
def created() @h['created']; end
|
159
|
+
def title() @h['title']; end
|
160
|
+
def type() @h['type']; end
|
161
|
+
def category() @h['category']; end
|
162
|
+
|
163
|
+
|
164
|
+
def meta() @h['meta']; end
|
165
|
+
end # class Outline
|
166
|
+
end # module OPML
|
167
|
+
|
168
|
+
|
169
|
+
## add some convenience shortcuts
|
170
|
+
Outline = OPML::Outline
|
171
|
+
|
172
|
+
|
173
|
+
|
174
|
+
# say hello
|
175
|
+
puts OPML.banner if $DEBUG || (defined?($RUBYLIBS_DEBUG) && $RUBYLIBS_DEBUG)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
module OPML
|
3
|
+
MAJOR = 0 ## todo: namespace inside version or something - why? why not??
|
4
|
+
MINOR = 1
|
5
|
+
PATCH = 0
|
6
|
+
VERSION = [MAJOR,MINOR,PATCH].join('.')
|
7
|
+
|
8
|
+
def self.version
|
9
|
+
VERSION
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.banner
|
13
|
+
"opmlparser/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.root
|
17
|
+
"#{File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )}"
|
18
|
+
end
|
19
|
+
end # module OPML
|
20
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
<opml version="2.0">
|
2
|
+
<head>
|
3
|
+
<title>Illustrating the category attribute</title>
|
4
|
+
<dateCreated>Mon, 31 Oct 2005 19:23:00 GMT</dateCreated>
|
5
|
+
</head>
|
6
|
+
<body>
|
7
|
+
<outline text="The Mets are the best team in baseball." category="/Philosophy/Baseball/Mets,/Tourism/New York" created="Mon, 31 Oct 2005 18:21:33 GMT"/>
|
8
|
+
</body>
|
9
|
+
</opml>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<opml version="2.0">
|
2
|
+
<head>
|
3
|
+
<title>placesLived.opml</title>
|
4
|
+
<dateCreated>Mon, 27 Feb 2006 12:09:48 GMT</dateCreated>
|
5
|
+
<dateModified>Mon, 27 Feb 2006 12:11:44 GMT</dateModified>
|
6
|
+
<ownerName>Dave Winer</ownerName>
|
7
|
+
<ownerId>http://www.opml.org/profiles/sendMail?usernum=1</ownerId>
|
8
|
+
<expansionState>1, 2, 5, 10, 13, 15</expansionState>
|
9
|
+
<vertScrollState>1</vertScrollState>
|
10
|
+
<windowTop>242</windowTop>
|
11
|
+
<windowLeft>329</windowLeft>
|
12
|
+
<windowBottom>665</windowBottom>
|
13
|
+
<windowRight>547</windowRight>
|
14
|
+
</head>
|
15
|
+
<body>
|
16
|
+
<outline text="Places I've lived">
|
17
|
+
<outline text="Boston">
|
18
|
+
<outline text="Cambridge"/>
|
19
|
+
<outline text="West Newton"/>
|
20
|
+
</outline>
|
21
|
+
<outline text="Bay Area">
|
22
|
+
<outline text="Mountain View"/>
|
23
|
+
<outline text="Los Gatos"/>
|
24
|
+
<outline text="Palo Alto"/>
|
25
|
+
<outline text="Woodside"/>
|
26
|
+
</outline>
|
27
|
+
<outline text="New Orleans">
|
28
|
+
<outline text="Uptown"/>
|
29
|
+
<outline text="Metairie"/>
|
30
|
+
</outline>
|
31
|
+
<outline text="Wisconsin">
|
32
|
+
<outline text="Madison"/>
|
33
|
+
</outline>
|
34
|
+
<outline text="Florida" type="include" url="http://hosting.opml.org/dave/florida.opml"/>
|
35
|
+
<outline text="New York">
|
36
|
+
<outline text="Jackson Heights"/>
|
37
|
+
<outline text="Flushing"/>
|
38
|
+
<outline text="The Bronx"/>
|
39
|
+
</outline>
|
40
|
+
</outline>
|
41
|
+
</body>
|
42
|
+
</opml>
|
@@ -0,0 +1,90 @@
|
|
1
|
+
<opml version="2.0">
|
2
|
+
<head>
|
3
|
+
<title>states.opml</title>
|
4
|
+
<dateCreated>Tue, 15 Mar 2005 16:35:45 GMT</dateCreated>
|
5
|
+
<dateModified>Thu, 14 Jul 2005 23:41:05 GMT</dateModified>
|
6
|
+
<ownerName>Dave Winer</ownerName>
|
7
|
+
<ownerEmail>dave@scripting.com</ownerEmail>
|
8
|
+
<expansionState>1, 6, 13, 16, 18, 20</expansionState>
|
9
|
+
<vertScrollState>1</vertScrollState>
|
10
|
+
<windowTop>106</windowTop>
|
11
|
+
<windowLeft>106</windowLeft>
|
12
|
+
<windowBottom>558</windowBottom>
|
13
|
+
<windowRight>479</windowRight>
|
14
|
+
</head>
|
15
|
+
<body>
|
16
|
+
<outline text="United States">
|
17
|
+
<outline text="Far West">
|
18
|
+
<outline text="Alaska"/>
|
19
|
+
<outline text="California"/>
|
20
|
+
<outline text="Hawaii"/>
|
21
|
+
<outline text="Nevada">
|
22
|
+
<outline text="Reno" created="Tue, 12 Jul 2005 23:56:35 GMT"/>
|
23
|
+
<outline text="Las Vegas" created="Tue, 12 Jul 2005 23:56:37 GMT"/>
|
24
|
+
<outline text="Ely" created="Tue, 12 Jul 2005 23:56:39 GMT"/>
|
25
|
+
<outline text="Gerlach" created="Tue, 12 Jul 2005 23:56:47 GMT"/>
|
26
|
+
</outline>
|
27
|
+
<outline text="Oregon"/>
|
28
|
+
<outline text="Washington"/>
|
29
|
+
</outline>
|
30
|
+
<outline text="Great Plains">
|
31
|
+
<outline text="Kansas"/>
|
32
|
+
<outline text="Nebraska"/>
|
33
|
+
<outline text="North Dakota"/>
|
34
|
+
<outline text="Oklahoma"/>
|
35
|
+
<outline text="South Dakota"/>
|
36
|
+
</outline>
|
37
|
+
<outline text="Mid-Atlantic">
|
38
|
+
<outline text="Delaware"/>
|
39
|
+
<outline text="Maryland"/>
|
40
|
+
<outline text="New Jersey"/>
|
41
|
+
<outline text="New York"/>
|
42
|
+
<outline text="Pennsylvania"/>
|
43
|
+
</outline>
|
44
|
+
<outline text="Midwest">
|
45
|
+
<outline text="Illinois"/>
|
46
|
+
<outline text="Indiana"/>
|
47
|
+
<outline text="Iowa"/>
|
48
|
+
<outline text="Kentucky"/>
|
49
|
+
<outline text="Michigan"/>
|
50
|
+
<outline text="Minnesota"/>
|
51
|
+
<outline text="Missouri"/>
|
52
|
+
<outline text="Ohio"/>
|
53
|
+
<outline text="West Virginia"/>
|
54
|
+
<outline text="Wisconsin"/>
|
55
|
+
</outline>
|
56
|
+
<outline text="Mountains">
|
57
|
+
<outline text="Colorado"/>
|
58
|
+
<outline text="Idaho"/>
|
59
|
+
<outline text="Montana"/>
|
60
|
+
<outline text="Utah"/>
|
61
|
+
<outline text="Wyoming"/>
|
62
|
+
</outline>
|
63
|
+
<outline text="New England">
|
64
|
+
<outline text="Connecticut"/>
|
65
|
+
<outline text="Maine"/>
|
66
|
+
<outline text="Massachusetts"/>
|
67
|
+
<outline text="New Hampshire"/>
|
68
|
+
<outline text="Rhode Island"/>
|
69
|
+
<outline text="Vermont"/>
|
70
|
+
</outline>
|
71
|
+
<outline text="South">
|
72
|
+
<outline text="Alabama"/>
|
73
|
+
<outline text="Arkansas"/>
|
74
|
+
<outline text="Florida"/>
|
75
|
+
<outline text="Georgia"/>
|
76
|
+
<outline text="Louisiana"/>
|
77
|
+
<outline text="Mississippi"/>
|
78
|
+
<outline text="North Carolina"/>
|
79
|
+
<outline text="South Carolina"/>
|
80
|
+
<outline text="Tennessee"/>
|
81
|
+
<outline text="Virginia"/>
|
82
|
+
</outline>
|
83
|
+
<outline text="Southwest">
|
84
|
+
<outline text="Arizona"/>
|
85
|
+
<outline text="New Mexico"/>
|
86
|
+
<outline text="Texas"/>
|
87
|
+
</outline>
|
88
|
+
</outline>
|
89
|
+
</body>
|
90
|
+
</opml>
|
data/test/test_opml.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
###
|
2
|
+
# to run use
|
3
|
+
# ruby -I ./lib -I ./test test/test_opml.rb
|
4
|
+
|
5
|
+
|
6
|
+
require 'helper'
|
7
|
+
|
8
|
+
|
9
|
+
class TestOpml < MiniTest::Test
|
10
|
+
|
11
|
+
def test_samples_opml
|
12
|
+
h = OPML.load_file( './test/outlines/category.opml.xml' )
|
13
|
+
h = OPML.load_file( './test/outlines/places_lived.opml.xml' )
|
14
|
+
h = OPML.load_file( './test/outlines/states.opml.xml' )
|
15
|
+
|
16
|
+
assert_equal "United States", h['outline'][0]['text']
|
17
|
+
assert_equal "Far West", h['outline'][0]['outline'][0]['text']
|
18
|
+
assert_equal "Alaska", h['outline'][0]['outline'][0]['outline'][0]['text']
|
19
|
+
assert_equal "Great Plains", h['outline'][0]['outline'][1]['text']
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_samples_outline
|
23
|
+
o = Outline.read( './test/outlines/category.opml.xml' )
|
24
|
+
o = Outline.read( './test/outlines/places_lived.opml.xml' )
|
25
|
+
o = Outline.read( './test/outlines/states.opml.xml' )
|
26
|
+
|
27
|
+
assert_equal "United States", o[0].text
|
28
|
+
assert_equal "United States", o[0]['text']
|
29
|
+
|
30
|
+
assert_equal "Far West", o[0][0].text
|
31
|
+
assert_equal "Far West", o[0][0]['text']
|
32
|
+
|
33
|
+
assert_equal "Alaska", o[0][0][0].text
|
34
|
+
assert_equal "Alaska", o[0][0][0]['text']
|
35
|
+
|
36
|
+
assert_equal "Great Plains", o[0][1].text
|
37
|
+
assert_equal "Great Plains", o[0][1]['text']
|
38
|
+
|
39
|
+
## check alias_method
|
40
|
+
o = Outline.load_file( './test/outlines/category.opml.xml' )
|
41
|
+
o = Outline.load_file( './test/outlines/places_lived.opml.xml' )
|
42
|
+
o = Outline.load_file( './test/outlines/states.opml.xml' )
|
43
|
+
end
|
44
|
+
end # class TestOpml
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: opmlparser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gerald Bauer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-03-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rdoc
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: hoe
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.16'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.16'
|
41
|
+
description: opmlparser - read / parse outlines (incl. feed subscription lists) in
|
42
|
+
the OPML (Outline Processor Markup Language) format in xml
|
43
|
+
email: wwwmake@googlegroups.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files:
|
47
|
+
- CHANGELOG.md
|
48
|
+
- Manifest.txt
|
49
|
+
- README.md
|
50
|
+
files:
|
51
|
+
- CHANGELOG.md
|
52
|
+
- Manifest.txt
|
53
|
+
- README.md
|
54
|
+
- Rakefile
|
55
|
+
- lib/opmlparser.rb
|
56
|
+
- lib/opmlparser/version.rb
|
57
|
+
- test/helper.rb
|
58
|
+
- test/outlines/category.opml.xml
|
59
|
+
- test/outlines/places_lived.opml.xml
|
60
|
+
- test/outlines/states.opml.xml
|
61
|
+
- test/test_opml.rb
|
62
|
+
homepage: https://github.com/feedreader/pluto
|
63
|
+
licenses:
|
64
|
+
- Public Domain
|
65
|
+
metadata: {}
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options:
|
68
|
+
- "--main"
|
69
|
+
- README.md
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 2.2.2
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 2.5.2
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: opmlparser - read / parse outlines (incl. feed subscription lists) in the
|
88
|
+
OPML (Outline Processor Markup Language) format in xml
|
89
|
+
test_files: []
|