feedtxt 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e298ca3389877938c8ded1a08b327480ebbf79f4
4
- data.tar.gz: 1fbea9a04efc18cf21d6286092bb113e616ae20b
3
+ metadata.gz: a63195357fa98e1b02d6513762ae80282a69fda1
4
+ data.tar.gz: 6d95a5daca55ba51b167689c19cad486259ca9ca
5
5
  SHA512:
6
- metadata.gz: f103a0b967f89c60a589622c899e03c9b17d05f4e7f726cba66d2712a82cbea07ee39c5319419f093bb8a6f321bbe8920669464c904623d145251917edc2293e
7
- data.tar.gz: 4cdd5559ea35fe6b85e28d27fe461c884bd9e2689778b756ffc9b099bc15d6215648e329d3d862e876f976a4bad731639bfa334b374f58b89182bb748423c695
6
+ metadata.gz: e261cd043984b29ff7ed8532939a972f9e1738142477c5ab025017a13cc96f799a0f96f942d1d9a9a815c1332066ec6ef6f0b263028066f717415b785d085b62
7
+ data.tar.gz: c3bed556bd29fd1379ecd703422b1d7f427e6c57723f0b87f755331dfd1580a0d71cc44cefc4b11595c266c1b68db8513c44d36440ceb3eff42c74514bd736eb
@@ -4,9 +4,18 @@ README.md
4
4
  Rakefile
5
5
  lib/feedtxt.rb
6
6
  lib/feedtxt/parser.rb
7
+ lib/feedtxt/parser/ini.rb
8
+ lib/feedtxt/parser/json.rb
9
+ lib/feedtxt/parser/yaml.rb
7
10
  lib/feedtxt/version.rb
11
+ test/feeds/spec/example.ini.txt
12
+ test/feeds/spec/example.json.txt
8
13
  test/feeds/spec/example.yaml.txt
14
+ test/feeds/spec/podcast.ini.txt
15
+ test/feeds/spec/podcast.json.txt
9
16
  test/feeds/spec/podcast.yaml.txt
10
17
  test/helper.rb
18
+ test/test_ini.rb
19
+ test/test_json.rb
11
20
  test/test_scanner.rb
12
21
  test/test_yaml.rb
data/README.md CHANGED
@@ -202,6 +202,69 @@ item_content
202
202
  ...
203
203
  ```
204
204
 
205
+ ## Alternative Meta Data Formats
206
+
207
+ Note: Feed.TXT supports alternative formats / styles for meta data blocks.
208
+ For now YAML, JSON and INI style
209
+ are built-in and shipping with the `feedtxt` gem.
210
+
211
+
212
+ ### JSON Example
213
+
214
+ ```
215
+ |{
216
+ "title": "My Example Feed",
217
+ "home_page_url": "https://example.org/",
218
+ "feed_url": "https://example.org/feed.txt"
219
+ }/{
220
+ "id": "2",
221
+ "url": "https://example.org/second-item"
222
+ }-{
223
+ This is a second item.
224
+ }/{
225
+ "id": "1",
226
+ "url": "https://example.org/initial-post"
227
+ }-{
228
+ Hello, world!
229
+ }|
230
+ ```
231
+
232
+ Note: Use `|{` and `}|` to begin and end your Feed.TXT.
233
+ Use `}/{` for first or next item
234
+ and `}-{` for meta blocks inside items.
235
+
236
+
237
+ (Source: [`feeds/spec/example.json.txt`](https://github.com/feedtxt/feedtxt/blob/master/test/feeds/spec/example.json.txt))
238
+
239
+
240
+ ### INI Example
241
+
242
+ ```
243
+ [>>>
244
+ title = My Example Feed
245
+ home_page_url = https://example.org/
246
+ feed_url = https://example.org/feed.txt
247
+ </>
248
+ id = 2
249
+ url = https://example.org/second-item
250
+ ---
251
+ This is a second item.
252
+ </>
253
+ id = 1
254
+ url = https://example.org/initial-post
255
+ ---
256
+ Hello, world!
257
+ <<<]
258
+ ```
259
+
260
+ (Source: [`feeds/spec/example.ini.txt`](https://github.com/feedtxt/feedtxt/blob/master/test/feeds/spec/example.ini.txt))
261
+
262
+
263
+ Note: Use `[>>>` and `<<<]` to begin and end your Feed.TXT.
264
+ Use `</>` for first or next item
265
+ and `---` for meta blocks inside items.
266
+
267
+
205
268
 
206
269
  ## License
207
270
 
data/Rakefile CHANGED
@@ -19,6 +19,10 @@ Hoe.spec 'feedtxt' do
19
19
 
20
20
  self.licenses = ['Public Domain']
21
21
 
22
+ ### todo
23
+ ## add deps e.g. props gem for INI.load
24
+
25
+
22
26
  self.spec_extras = {
23
27
  required_ruby_version: '>= 1.9.2'
24
28
  }
@@ -14,12 +14,15 @@ require 'pp'
14
14
 
15
15
  # 3rd party gems/libs
16
16
  require 'logutils'
17
+ require 'props' ## used for IniFile.parse
17
18
 
18
19
 
19
20
  # our own code
20
21
  require 'feedtxt/version' # let it always go first
21
22
  require 'feedtxt/parser'
22
-
23
+ require 'feedtxt/parser/json'
24
+ require 'feedtxt/parser/yaml'
25
+ require 'feedtxt/parser/ini'
23
26
 
24
27
 
25
28
 
@@ -19,87 +19,35 @@ class Parser
19
19
  end
20
20
 
21
21
 
22
-
23
- ## note:
24
- ## regex excape pipe: | to \|
25
- ## \\ needs to get escaped twice e.g. (\\ becomes \)
26
- ## e.g. |>>> or |>>>>>
27
- FEED_BEGIN = %{^[ ]*\\|>>>+[ ]*$} ## note: allow leading n trailing spaces; allow 3 or more brackets
28
- ## e.g. <<<| or <<<<<<|
29
- FEED_END = %{^[ ]*<<<+\\|[ ]*$} ## note: allow leading n trailing spaces; allow 3 or more brackets
30
-
31
- ## e.g.</> or <<</>>>
32
- FEED_NEXT = %{^[ ]*<+/>+[ ]*$} ## pass 1: split/break up blocks
33
- ## e.g. --- or -----
34
- FEED_META = %{^[ ]*---+[ ]*$} ## pass 2: break up item into metadata and content block
35
-
36
-
37
-
38
22
  def parse
23
+ ## auto-detect format
24
+ ## use "best" matching format (e.g. first match by pos(ition))
39
25
 
40
- ## find start marker e.g. |>>>
41
- ## use regex - allow three or more >>>>>> or <<<<<<
42
- ## allow spaces before and after
26
+ klass = YamlParser ## default to yamlparser for now
27
+ pos = 9999999 ## todo:use MAX INTEGER or something!!
43
28
 
44
- s = StringScanner.new( @text )
45
-
46
- prolog = s.scan_until( /(?=#{FEED_BEGIN})/ )
47
- ## pp prolog
48
-
49
- feed_begin = s.scan( /#{FEED_BEGIN}/ )
50
- if feed_begin.empty? ## use blank? why? why not??
51
- ## nothing found return empty array for now; return nil - why? why not?
52
- puts "warn !!! no begin marker found e.g. |>>>"
53
- return []
29
+ json = @text.index( /#{JsonParser::FEED_BEGIN}/ )
30
+ if json # found e.g. not nil? incl. 0
31
+ pos = json
32
+ klass = JsonParser
54
33
  end
55
34
 
56
-
57
- buf = s.scan_until( /(?=#{FEED_END})/ )
58
- buf = buf.strip # remove leading and trailing whitespace
59
-
60
- feed_end = s.scan( /#{FEED_END}/ )
61
- if feed_end.empty? ## use blank? why? why not??
62
- ## nothing found return empty array for now; return nil - why? why not?
63
- puts "warn !!! no end marker found e.g. <<<|"
64
- return []
35
+ ini = @text.index( /#{IniParser::FEED_BEGIN}/ )
36
+ if ini && ini < pos # found e.g. not nil? and match before last?
37
+ pos = ini
38
+ klass = IniParser
65
39
  end
66
40
 
67
-
68
- ####
69
- ## pass 1: split blocks by </>
70
- ### note: allows <<<</>>>>
71
-
72
- blocks = buf.split( /#{FEED_NEXT}/ )
73
- ## pp blocks
74
-
75
- ## 1st block is feed meta data
76
- block1st = blocks.shift ## get/remove 1st block from blocks
77
- feed_metadata = YAML.load( block1st.strip )
78
-
79
- feed_items = []
80
- blocks.each do |block|
81
- ### note: do NOT use split e.g.--- is used by markdown
82
- ## only search for first --- to split (all others get ignored)
83
- ## todo: make three dashes --- (3) not hard-coded (allow more)
84
-
85
- s2 = StringScanner.new( block )
86
-
87
- item_metadata = s2.scan_until( /(?=#{FEED_META})/ )
88
- item_metadata = item_metadata.strip # remove leading and trailing whitespace
89
- item_metadata = YAML.load( item_metadata ) ## convert to hash with yaml
90
-
91
- feed_meta = s2.scan( /#{FEED_META}/ )
92
-
93
- item_content = s2.rest
94
- item_content = item_content.strip # remove leading and trailing whitespace
95
-
96
- feed_items << [item_metadata, item_content]
41
+ yaml = @text.index( /#{YamlParser::FEED_BEGIN}/ )
42
+ if yaml && yaml < pos # found e.g. not nil? and match before last?
43
+ pos = yaml
44
+ klass = YamlParser
97
45
  end
98
46
 
99
- [ feed_metadata, feed_items ]
47
+ feed = klass.parse( @text )
48
+ feed
100
49
  end # method parse
101
50
 
102
-
103
51
  end # class Parser
104
52
 
105
53
  end # module Feedtxt
@@ -0,0 +1,106 @@
1
+ # encoding: utf-8
2
+
3
+ module Feedtxt
4
+
5
+
6
+ class IniParser
7
+
8
+ include LogUtils::Logging
9
+
10
+
11
+ ### convenience class/factory method
12
+ def self.parse( text, opts={} )
13
+ self.new( text ).parse
14
+ end
15
+
16
+ ### Note: lets keep/use same API as RSS::Parser for now
17
+ def initialize( text )
18
+ @text = text
19
+ end
20
+
21
+
22
+
23
+ ## note:
24
+ ## regex excape bracket: [ to \[
25
+ ## \\ needs to get escaped twice e.g. (\\ becomes \)
26
+ ## e.g. [>>> or [>>>>>
27
+ FEED_BEGIN = "^[ ]*\\[>>>+[ ]*$" ## note: allow leading n trailing spaces; allow 3 or more brackets
28
+ ## e.g. <<<] or <<<<<<]
29
+ FEED_END = "^[ ]*<<<+\\][ ]*$" ## note: allow leading n trailing spaces; allow 3 or more brackets
30
+
31
+ ## e.g.</> or <<</>>>
32
+ FEED_NEXT = "^[ ]*<+/>+[ ]*$" ## pass 1: split/break up blocks
33
+ ## e.g. --- or -----
34
+ FEED_META = "^[ ]*---+[ ]*$" ## pass 2: break up item into metadata and content block
35
+
36
+
37
+
38
+ def parse
39
+
40
+ ## find start marker e.g. [>>>
41
+ ## use regex - allow three or more >>>>>> or <<<<<<
42
+ ## allow spaces before and after
43
+
44
+ s = StringScanner.new( @text )
45
+
46
+ prolog = s.scan_until( /(?=#{FEED_BEGIN})/ )
47
+ ## pp prolog
48
+
49
+ feed_begin = s.scan( /#{FEED_BEGIN}/ )
50
+ if feed_begin.empty? ## use blank? why? why not??
51
+ ## nothing found return empty array for now; return nil - why? why not?
52
+ puts "warn !!! no begin marker found e.g. |>>>"
53
+ return []
54
+ end
55
+
56
+
57
+ buf = s.scan_until( /(?=#{FEED_END})/ )
58
+ buf = buf.strip # remove leading and trailing whitespace
59
+
60
+ feed_end = s.scan( /#{FEED_END}/ )
61
+ if feed_end.empty? ## use blank? why? why not??
62
+ ## nothing found return empty array for now; return nil - why? why not?
63
+ puts "warn !!! no end marker found e.g. <<<|"
64
+ return []
65
+ end
66
+
67
+
68
+ ####
69
+ ## pass 1: split blocks by </>
70
+ ### note: allows <<<</>>>>
71
+
72
+ blocks = buf.split( /#{FEED_NEXT}/ )
73
+ ## pp blocks
74
+
75
+ ## 1st block is feed meta data
76
+ block1st = blocks.shift ## get/remove 1st block from blocks
77
+ block1st = block1st.strip ## strip leading and trailing whitespace
78
+ feed_metadata = INI.load( block1st )
79
+
80
+ feed_items = []
81
+ blocks.each do |block|
82
+ ### note: do NOT use split e.g.--- is used by markdown
83
+ ## only search for first --- to split (all others get ignored)
84
+ ## todo: make three dashes --- (3) not hard-coded (allow more)
85
+
86
+ s2 = StringScanner.new( block )
87
+
88
+ item_metadata = s2.scan_until( /(?=#{FEED_META})/ )
89
+ item_metadata = item_metadata.strip # remove leading and trailing whitespace
90
+ item_metadata = INI.load( item_metadata ) ## convert to hash with inifile parser
91
+
92
+ feed_meta = s2.scan( /#{FEED_META}/ )
93
+
94
+ item_content = s2.rest
95
+ item_content = item_content.strip # remove leading and trailing whitespace
96
+
97
+ feed_items << [item_metadata, item_content]
98
+ end
99
+
100
+ [ feed_metadata, feed_items ]
101
+ end # method parse
102
+
103
+
104
+ end # class IniParser
105
+
106
+ end # module Feedtxt
@@ -0,0 +1,110 @@
1
+ # encoding: utf-8
2
+
3
+ module Feedtxt
4
+
5
+
6
+ class JsonParser
7
+
8
+ include LogUtils::Logging
9
+
10
+
11
+ ### convenience class/factory method
12
+ def self.parse( text, opts={} )
13
+ self.new( text ).parse
14
+ end
15
+
16
+ ### Note: lets keep/use same API as RSS::Parser for now
17
+ def initialize( text )
18
+ @text = text
19
+ end
20
+
21
+
22
+
23
+ ## note:
24
+ ## regex excape pipe: | to \|
25
+ ## \\ needs to get escaped twice e.g. (\\ becomes \)
26
+ ## e.g. |{ or |{{{
27
+ FEED_BEGIN = "^[ ]*\\|{+[ ]*$" ## note: allow leading n trailing spaces; allow 3 or more brackets
28
+ ## e.g. }| or }}}|
29
+ FEED_END = "^[ ]*}+\\|[ ]*$" ## note: allow leading n trailing spaces; allow 3 or more brackets
30
+
31
+ ## e.g.}/{ or }}}/{{{
32
+ ## todo/check: also allow }///{ or } /// { why,why not?
33
+ FEED_NEXT = "^[ ]*}+/{+[ ]*$" ## pass 1: split/break up blocks
34
+
35
+ ## e.g. }---{ or }}}---{{{ or }-{
36
+ ## todo/check: also allow }.{ with dot why? why not?
37
+ ## also allow } - { or } ---- { why? why not?
38
+ FEED_META = "^[ ]*}+-+{+[ ]*$" ## pass 2: break up item into metadata and content block
39
+
40
+
41
+
42
+ def parse
43
+
44
+ ## find start marker e.g. |>>>
45
+ ## use regex - allow three or more >>>>>> or <<<<<<
46
+ ## allow spaces before and after
47
+
48
+ s = StringScanner.new( @text )
49
+
50
+ prolog = s.scan_until( /(?=#{FEED_BEGIN})/ )
51
+ ## pp prolog
52
+
53
+ feed_begin = s.scan( /#{FEED_BEGIN}/ )
54
+ if feed_begin.empty? ## use blank? why? why not??
55
+ ## nothing found return empty array for now; return nil - why? why not?
56
+ puts "warn !!! no begin marker found e.g. |>>>"
57
+ return []
58
+ end
59
+
60
+
61
+ buf = s.scan_until( /(?=#{FEED_END})/ )
62
+ buf = buf.strip # remove leading and trailing whitespace
63
+
64
+ feed_end = s.scan( /#{FEED_END}/ )
65
+ if feed_end.empty? ## use blank? why? why not??
66
+ ## nothing found return empty array for now; return nil - why? why not?
67
+ puts "warn !!! no end marker found e.g. <<<|"
68
+ return []
69
+ end
70
+
71
+
72
+ ####
73
+ ## pass 1: split blocks by }/{
74
+ ### note: allows }}}/{{{
75
+
76
+ blocks = buf.split( /#{FEED_NEXT}/ )
77
+ ## pp blocks
78
+
79
+ ## 1st block is feed meta data
80
+ block1st = blocks.shift ## get/remove 1st block from blocks
81
+ block1st = block1st.strip # remove leading and trailing whitespaces
82
+ feed_metadata = JSON.parse( "{ #{block1st} }" )
83
+
84
+ feed_items = []
85
+ blocks.each do |block|
86
+ ### note: do NOT use split e.g.--- is used by markdown
87
+ ## only search for first --- to split (all others get ignored)
88
+ ## todo: make three dashes --- (3) not hard-coded (allow more)
89
+
90
+ s2 = StringScanner.new( block )
91
+
92
+ item_metadata = s2.scan_until( /(?=#{FEED_META})/ )
93
+ item_metadata = item_metadata.strip # remove leading and trailing whitespace
94
+ item_metadata = JSON.parse( "{ #{item_metadata} }" ) ## convert to hash with yaml
95
+
96
+ feed_meta = s2.scan( /#{FEED_META}/ )
97
+
98
+ item_content = s2.rest
99
+ item_content = item_content.strip # remove leading and trailing whitespace
100
+
101
+ feed_items << [item_metadata, item_content]
102
+ end
103
+
104
+ [ feed_metadata, feed_items ]
105
+ end # method parse
106
+
107
+
108
+ end # class JsonParser
109
+
110
+ end # module Feedtxt
@@ -0,0 +1,106 @@
1
+ # encoding: utf-8
2
+
3
+ module Feedtxt
4
+
5
+
6
+ class YamlParser
7
+
8
+ include LogUtils::Logging
9
+
10
+
11
+ ### convenience class/factory method
12
+ def self.parse( text, opts={} )
13
+ self.new( text ).parse
14
+ end
15
+
16
+ ### Note: lets keep/use same API as RSS::Parser for now
17
+ def initialize( text )
18
+ @text = text
19
+ end
20
+
21
+
22
+
23
+ ## note:
24
+ ## regex excape pipe: | to \|
25
+ ## \\ needs to get escaped twice e.g. (\\ becomes \)
26
+ ## e.g. |>>> or |>>>>>
27
+ FEED_BEGIN = "^[ ]*\\|>>>+[ ]*$" ## note: allow leading n trailing spaces; allow 3 or more brackets
28
+ ## e.g. <<<| or <<<<<<|
29
+ FEED_END = "^[ ]*<<<+\\|[ ]*$" ## note: allow leading n trailing spaces; allow 3 or more brackets
30
+
31
+ ## e.g.</> or <<</>>>
32
+ FEED_NEXT = "^[ ]*<+/>+[ ]*$" ## pass 1: split/break up blocks
33
+ ## e.g. --- or -----
34
+ FEED_META = "^[ ]*---+[ ]*$" ## pass 2: break up item into metadata and content block
35
+
36
+
37
+
38
+ def parse
39
+
40
+ ## find start marker e.g. |>>>
41
+ ## use regex - allow three or more >>>>>> or <<<<<<
42
+ ## allow spaces before and after
43
+
44
+ s = StringScanner.new( @text )
45
+
46
+ prolog = s.scan_until( /(?=#{FEED_BEGIN})/ )
47
+ ## pp prolog
48
+
49
+ feed_begin = s.scan( /#{FEED_BEGIN}/ )
50
+ if feed_begin.empty? ## use blank? why? why not??
51
+ ## nothing found return empty array for now; return nil - why? why not?
52
+ puts "warn !!! no begin marker found e.g. |>>>"
53
+ return []
54
+ end
55
+
56
+
57
+ buf = s.scan_until( /(?=#{FEED_END})/ )
58
+ buf = buf.strip # remove leading and trailing whitespace
59
+
60
+ feed_end = s.scan( /#{FEED_END}/ )
61
+ if feed_end.empty? ## use blank? why? why not??
62
+ ## nothing found return empty array for now; return nil - why? why not?
63
+ puts "warn !!! no end marker found e.g. <<<|"
64
+ return []
65
+ end
66
+
67
+
68
+ ####
69
+ ## pass 1: split blocks by </>
70
+ ### note: allows <<<</>>>>
71
+
72
+ blocks = buf.split( /#{FEED_NEXT}/ )
73
+ ## pp blocks
74
+
75
+ ## 1st block is feed meta data
76
+ block1st = blocks.shift ## get/remove 1st block from blocks
77
+ block1st = block1st.strip ## strip leading and trailing whitespace
78
+ feed_metadata = YAML.load( block1st )
79
+
80
+ feed_items = []
81
+ blocks.each do |block|
82
+ ### note: do NOT use split e.g.--- is used by markdown
83
+ ## only search for first --- to split (all others get ignored)
84
+ ## todo: make three dashes --- (3) not hard-coded (allow more)
85
+
86
+ s2 = StringScanner.new( block )
87
+
88
+ item_metadata = s2.scan_until( /(?=#{FEED_META})/ )
89
+ item_metadata = item_metadata.strip # remove leading and trailing whitespace
90
+ item_metadata = YAML.load( item_metadata ) ## convert to hash with yaml
91
+
92
+ feed_meta = s2.scan( /#{FEED_META}/ )
93
+
94
+ item_content = s2.rest
95
+ item_content = item_content.strip # remove leading and trailing whitespace
96
+
97
+ feed_items << [item_metadata, item_content]
98
+ end
99
+
100
+ [ feed_metadata, feed_items ]
101
+ end # method parse
102
+
103
+
104
+ end # class YamlParser
105
+
106
+ end # module Feedtxt
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Feedtxt
4
4
 
5
- MAJOR = 0
6
- MINOR = 2
5
+ MAJOR = 1
6
+ MINOR = 0
7
7
  PATCH = 0
8
8
  VERSION = [MAJOR,MINOR,PATCH].join('.')
9
9
 
@@ -0,0 +1,15 @@
1
+ [>>>
2
+ title = My Example Feed
3
+ home_page_url = https://example.org/
4
+ feed_url = https://example.org/feed.txt
5
+ </>
6
+ id = 2
7
+ url = https://example.org/second-item
8
+ ---
9
+ This is a second item.
10
+ </>
11
+ id = 1
12
+ url = https://example.org/initial-post
13
+ ---
14
+ Hello, world!
15
+ <<<]
@@ -0,0 +1,15 @@
1
+ |{
2
+ "title": "My Example Feed",
3
+ "home_page_url": "https://example.org/",
4
+ "feed_url": "https://example.org/feed.txt"
5
+ }/{
6
+ "id": "2",
7
+ "url": "https://example.org/second-item"
8
+ }-{
9
+ This is a second item.
10
+ }/{
11
+ "id": "1",
12
+ "url": "https://example.org/initial-post"
13
+ }-{
14
+ Hello, world!
15
+ }|
@@ -0,0 +1,26 @@
1
+ [>>>
2
+ comment = This is a podcast feed. You can add this feed to your podcast client using the following URL: http://therecord.co/feed.json
3
+ title = The Record
4
+ home_page_url = http://therecord.co/
5
+ feed_url = http://therecord.co/feed.txt
6
+ </>
7
+ id = http://therecord.co/chris-parrish
8
+ title = Special #1 - Chris Parrish
9
+ url = http://therecord.co/chris-parrish
10
+ summary = Brent interviews Chris Parrish, co-host of The Record and one-half of Aged & Distilled.
11
+ published = 2014-05-09T14:04:00-07:00
12
+ [attachments]
13
+ url = http://therecord.co/downloads/The-Record-sp1e1-ChrisParrish.m4a
14
+ mime_type = audio/x-m4a
15
+ size_in_bytes = 89970236
16
+ duration_in_seconds = 6629
17
+ ---
18
+ Chris has worked at [Adobe][1] and as a founder of Rogue Sheep, which won an Apple Design Award for Postage.
19
+ Chris's new company is Aged & Distilled with Guy English - which shipped [Napkin](2),
20
+ a Mac app for visual collaboration. Chris is also the co-host of The Record.
21
+ He lives on [Bainbridge Island][3], a quick ferry ride from Seattle.
22
+
23
+ [1]: http://adobe.com/
24
+ [2]: http://aged-and-distilled.com/napkin/
25
+ [3]: http://www.ci.bainbridge-isl.wa.us/
26
+ <<<]
@@ -0,0 +1,29 @@
1
+ |{
2
+ "comment": "This is a podcast feed. You can add this feed to your podcast client using the following URL: http://therecord.co/feed.json",
3
+ "title": "The Record",
4
+ "home_page_url": "http://therecord.co/",
5
+ "feed_url": "http://therecord.co/feed.txt"
6
+ }/{
7
+ "id": "http://therecord.co/chris-parrish",
8
+ "title": "Special #1 - Chris Parrish",
9
+ "url": "http://therecord.co/chris-parrish",
10
+ "summary": "Brent interviews Chris Parrish, co-host of The Record and one-half of Aged & Distilled.",
11
+ "published": "2014-05-09T14:04:00-07:00",
12
+ "attachments": [
13
+ {
14
+ "url": "http://therecord.co/downloads/The-Record-sp1e1-ChrisParrish.m4a",
15
+ "mime_type": "audio/x-m4a",
16
+ "size_in_bytes": 89970236,
17
+ "duration_in_seconds": 6629
18
+ }
19
+ ]
20
+ }-{
21
+ Chris has worked at [Adobe][1] and as a founder of Rogue Sheep, which won an Apple Design Award for Postage.
22
+ Chris's new company is Aged & Distilled with Guy English - which shipped [Napkin](2),
23
+ a Mac app for visual collaboration. Chris is also the co-host of The Record.
24
+ He lives on [Bainbridge Island][3], a quick ferry ride from Seattle.
25
+
26
+ [1]: http://adobe.com/
27
+ [2]: http://aged-and-distilled.com/napkin/
28
+ [3]: http://www.ci.bainbridge-isl.wa.us/
29
+ }|
@@ -0,0 +1,62 @@
1
+ ###
2
+ # to run use
3
+ # ruby -I ./lib -I ./test test/test_ini.rb
4
+ # or better
5
+ # rake test
6
+
7
+ require 'helper'
8
+
9
+
10
+ class TestIni < MiniTest::Test
11
+
12
+ def test_example
13
+
14
+ text = read_text( 'spec/example.ini' )
15
+ pp text
16
+
17
+ exp = [
18
+ {"title"=>"My Example Feed",
19
+ "home_page_url"=>"https://example.org/",
20
+ "feed_url"=>"https://example.org/feed.txt"},
21
+ [[
22
+ {"id"=>"2", "url"=>"https://example.org/second-item"},
23
+ "This is a second item."
24
+ ],
25
+ [
26
+ {"id"=>"1", "url"=>"https://example.org/initial-post"},
27
+ "Hello, world!"
28
+ ]]]
29
+
30
+ assert_equal exp, Feedtxt::IniParser.parse( text )
31
+ assert_equal exp, Feedtxt.parse( text ) ## try shortcut alias too
32
+ end
33
+
34
+ def test_podcast
35
+
36
+ text = read_text( 'spec/podcast.ini' )
37
+ pp text
38
+
39
+ exp = [{"comment"=>
40
+ "This is a podcast feed. You can add this feed to your podcast client using the following URL: http://therecord.co/feed.json",
41
+ "title"=>"The Record",
42
+ "home_page_url"=>"http://therecord.co/",
43
+ "feed_url"=>"http://therecord.co/feed.txt"},
44
+ [[{"id"=>"http://therecord.co/chris-parrish",
45
+ "title"=>"Special",
46
+ "url"=>"http://therecord.co/chris-parrish",
47
+ "summary"=>
48
+ "Brent interviews Chris Parrish, co-host of The Record and one-half of Aged & Distilled.",
49
+ "published"=>"2014-05-09T14:04:00-07:00",
50
+ "attachments"=>
51
+ {"url"=>"http://therecord.co/downloads/The-Record-sp1e1-ChrisParrish.m4a",
52
+ "mime_type"=>"audio/x-m4a",
53
+ "size_in_bytes"=>"89970236",
54
+ "duration_in_seconds"=>"6629"}},
55
+ "Chris has worked at [Adobe][1] and as a founder of Rogue Sheep, which won an Apple Design Award for Postage.\nChris's new company is Aged & Distilled with Guy English - which shipped [Napkin](2),\na Mac app for visual collaboration. Chris is also the co-host of The Record.\nHe lives on [Bainbridge Island][3], a quick ferry ride from Seattle.\n\n[1]: http://adobe.com/\n[2]: http://aged-and-distilled.com/napkin/\n[3]: http://www.ci.bainbridge-isl.wa.us/"]]]
56
+
57
+ assert_equal exp, Feedtxt::IniParser.parse( text )
58
+ assert_equal exp, Feedtxt.parse( text ) ## try shortcut alias too
59
+ end
60
+
61
+
62
+ end # class TestIni
@@ -0,0 +1,63 @@
1
+ ###
2
+ # to run use
3
+ # ruby -I ./lib -I ./test test/test_json.rb
4
+ # or better
5
+ # rake test
6
+
7
+ require 'helper'
8
+
9
+
10
+ class TestJson < MiniTest::Test
11
+
12
+ def test_example
13
+
14
+ text = read_text( 'spec/example.json' )
15
+ pp text
16
+
17
+ exp = [
18
+ {"title"=>"My Example Feed",
19
+ "home_page_url"=>"https://example.org/",
20
+ "feed_url"=>"https://example.org/feed.txt"},
21
+ [[
22
+ {"id"=>"2", "url"=>"https://example.org/second-item"},
23
+ "This is a second item."
24
+ ],
25
+ [
26
+ {"id"=>"1", "url"=>"https://example.org/initial-post"},
27
+ "Hello, world!"
28
+ ]]]
29
+
30
+ assert_equal exp, Feedtxt::JsonParser.parse( text )
31
+ assert_equal exp, Feedtxt.parse( text ) ## try shortcut alias too
32
+ end
33
+
34
+ def test_podcast
35
+
36
+ text = read_text( 'spec/podcast.json' )
37
+ pp text
38
+
39
+ exp =[{"comment"=>
40
+ "This is a podcast feed. You can add this feed to your podcast client using the following URL: http://therecord.co/feed.json",
41
+ "title"=>"The Record",
42
+ "home_page_url"=>"http://therecord.co/",
43
+ "feed_url"=>"http://therecord.co/feed.txt"},
44
+ [[{"id"=>"http://therecord.co/chris-parrish",
45
+ "title"=>"Special #1 - Chris Parrish",
46
+ "url"=>"http://therecord.co/chris-parrish",
47
+ "summary"=>
48
+ "Brent interviews Chris Parrish, co-host of The Record and one-half of Aged & Distilled.",
49
+ "published"=> "2014-05-09T14:04:00-07:00",
50
+ "attachments"=>
51
+ [{"url"=>
52
+ "http://therecord.co/downloads/The-Record-sp1e1-ChrisParrish.m4a",
53
+ "mime_type"=>"audio/x-m4a",
54
+ "size_in_bytes"=>89970236,
55
+ "duration_in_seconds"=>6629}]},
56
+ "Chris has worked at [Adobe][1] and as a founder of Rogue Sheep, which won an Apple Design Award for Postage.\nChris's new company is Aged & Distilled with Guy English - which shipped [Napkin](2),\na Mac app for visual collaboration. Chris is also the co-host of The Record.\nHe lives on [Bainbridge Island][3], a quick ferry ride from Seattle.\n\n[1]: http://adobe.com/\n[2]: http://aged-and-distilled.com/napkin/\n[3]: http://www.ci.bainbridge-isl.wa.us/"]]]
57
+
58
+ assert_equal exp, Feedtxt::JsonParser.parse( text )
59
+ assert_equal exp, Feedtxt.parse( text ) ## try shortcut alias too
60
+ end
61
+
62
+
63
+ end # class TestYaml
@@ -27,7 +27,7 @@ class TestYaml < MiniTest::Test
27
27
  "Hello, world!"
28
28
  ]]]
29
29
 
30
- assert_equal exp, Feedtxt::Parser.parse( text )
30
+ assert_equal exp, Feedtxt::YamlParser.parse( text )
31
31
  assert_equal exp, Feedtxt.parse( text ) ## try shortcut alias too
32
32
  end
33
33
 
@@ -55,7 +55,7 @@ class TestYaml < MiniTest::Test
55
55
  "duration_in_seconds"=>6629}]},
56
56
  "Chris has worked at [Adobe][1] and as a founder of Rogue Sheep, which won an Apple Design Award for Postage.\nChris's new company is Aged & Distilled with Guy English - which shipped [Napkin](2),\na Mac app for visual collaboration. Chris is also the co-host of The Record.\nHe lives on [Bainbridge Island][3], a quick ferry ride from Seattle.\n\n[1]: http://adobe.com/\n[2]: http://aged-and-distilled.com/napkin/\n[3]: http://www.ci.bainbridge-isl.wa.us/"]]]
57
57
 
58
- assert_equal exp, Feedtxt::Parser.parse( text )
58
+ assert_equal exp, Feedtxt::YamlParser.parse( text )
59
59
  assert_equal exp, Feedtxt.parse( text ) ## try shortcut alias too
60
60
  end
61
61
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: feedtxt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-12 00:00:00.000000000 Z
11
+ date: 2017-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdoc
@@ -54,10 +54,19 @@ files:
54
54
  - Rakefile
55
55
  - lib/feedtxt.rb
56
56
  - lib/feedtxt/parser.rb
57
+ - lib/feedtxt/parser/ini.rb
58
+ - lib/feedtxt/parser/json.rb
59
+ - lib/feedtxt/parser/yaml.rb
57
60
  - lib/feedtxt/version.rb
61
+ - test/feeds/spec/example.ini.txt
62
+ - test/feeds/spec/example.json.txt
58
63
  - test/feeds/spec/example.yaml.txt
64
+ - test/feeds/spec/podcast.ini.txt
65
+ - test/feeds/spec/podcast.json.txt
59
66
  - test/feeds/spec/podcast.yaml.txt
60
67
  - test/helper.rb
68
+ - test/test_ini.rb
69
+ - test/test_json.rb
61
70
  - test/test_scanner.rb
62
71
  - test/test_yaml.rb
63
72
  homepage: https://github.com/feedtxt/feedtxt