feedtxt 0.2.0 → 1.0.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 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