feedtxt 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Manifest.txt +1 -1
- data/README.md +4 -4
- data/Rakefile +1 -1
- data/lib/feedtxt.rb +13 -0
- data/lib/feedtxt/parser.rb +39 -25
- data/lib/feedtxt/version.rb +1 -1
- data/test/test_scanner.rb +56 -0
- data/test/test_yaml.rb +4 -13
- metadata +7 -7
- data/test/test_version.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e298ca3389877938c8ded1a08b327480ebbf79f4
|
4
|
+
data.tar.gz: 1fbea9a04efc18cf21d6286092bb113e616ae20b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f103a0b967f89c60a589622c899e03c9b17d05f4e7f726cba66d2712a82cbea07ee39c5319419f093bb8a6f321bbe8920669464c904623d145251917edc2293e
|
7
|
+
data.tar.gz: 4cdd5559ea35fe6b85e28d27fe461c884bd9e2689778b756ffc9b099bc15d6215648e329d3d862e876f976a4bad731639bfa334b374f58b89182bb748423c695
|
data/Manifest.txt
CHANGED
data/README.md
CHANGED
@@ -10,8 +10,8 @@
|
|
10
10
|
|
11
11
|
## Usage
|
12
12
|
|
13
|
-
Use `Feedtxt
|
14
|
-
format.
|
13
|
+
Use `Feedtxt.parse` to read / parse feeds in text using the Feed.TXT
|
14
|
+
format also known as RSS (Really Simple Sharing) 5.0 ;-).
|
15
15
|
The parse method will return an array:
|
16
16
|
|
17
17
|
```
|
@@ -52,7 +52,7 @@ Hello, world!
|
|
52
52
|
<<<|
|
53
53
|
TXT
|
54
54
|
|
55
|
-
feed = Feedtxt
|
55
|
+
feed = Feedtxt.parse( text )
|
56
56
|
pp feed
|
57
57
|
```
|
58
58
|
|
@@ -148,7 +148,7 @@ He lives on [Bainbridge Island][3], a quick ferry ride from Seattle.
|
|
148
148
|
<<<|
|
149
149
|
TXT
|
150
150
|
|
151
|
-
feed = Feedtxt
|
151
|
+
feed = Feedtxt.parse( text )
|
152
152
|
pp feed
|
153
153
|
```
|
154
154
|
|
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ Hoe.spec 'feedtxt' do
|
|
5
5
|
|
6
6
|
self.version = Feedtxt::VERSION
|
7
7
|
|
8
|
-
self.summary = "feedtxt - reads Feed.TXT - feeds in text (unicode) - publish & share posts, articles, podcasts, 'n' more"
|
8
|
+
self.summary = "feedtxt - reads Feed.TXT a.k.a. RSS (Really Simple Sharing) 5.0 ;-) - feeds in text (unicode) - publish & share posts, articles, podcasts, 'n' more"
|
9
9
|
self.description = summary
|
10
10
|
|
11
11
|
self.urls = ['https://github.com/feedtxt/feedtxt']
|
data/lib/feedtxt.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
# core and stdlibs
|
5
5
|
|
6
|
+
require 'strscan' ## StringScanner
|
6
7
|
require 'json'
|
7
8
|
require 'yaml'
|
8
9
|
require 'date'
|
@@ -10,6 +11,7 @@ require 'time'
|
|
10
11
|
require 'pp'
|
11
12
|
|
12
13
|
|
14
|
+
|
13
15
|
# 3rd party gems/libs
|
14
16
|
require 'logutils'
|
15
17
|
|
@@ -21,5 +23,16 @@ require 'feedtxt/parser'
|
|
21
23
|
|
22
24
|
|
23
25
|
|
26
|
+
## add shortcut / alias e.g.
|
27
|
+
## lets you use:
|
28
|
+
## Feedtxt.parse instead of Feedtxt::Parser.parse
|
29
|
+
module Feedtxt
|
30
|
+
def self.parse( text, opts={} )
|
31
|
+
Parser.parse( text, )
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
|
24
37
|
# say hello
|
25
38
|
puts Feedtxt.banner if $DEBUG || (defined?($RUBYLIBS_DEBUG) && $RUBYLIBS_DEBUG)
|
data/lib/feedtxt/parser.rb
CHANGED
@@ -20,47 +20,56 @@ class Parser
|
|
20
20
|
|
21
21
|
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
+
|
27
36
|
|
28
37
|
|
29
38
|
def parse
|
30
39
|
|
31
40
|
## find start marker e.g. |>>>
|
32
|
-
##
|
33
|
-
##
|
41
|
+
## use regex - allow three or more >>>>>> or <<<<<<
|
42
|
+
## allow spaces before and after
|
34
43
|
|
44
|
+
s = StringScanner.new( @text )
|
35
45
|
|
36
|
-
|
37
|
-
##
|
38
|
-
## regex is not fixed length/width; we need to know the length
|
39
|
-
## check what is the best way? use regex match or something???
|
46
|
+
prolog = s.scan_until( /(?=#{FEED_BEGIN})/ )
|
47
|
+
## pp prolog
|
40
48
|
|
41
|
-
|
42
|
-
if
|
49
|
+
feed_begin = s.scan( /#{FEED_BEGIN}/ )
|
50
|
+
if feed_begin.empty? ## use blank? why? why not??
|
43
51
|
## nothing found return empty array for now; return nil - why? why not?
|
44
52
|
puts "warn !!! no begin marker found e.g. |>>>"
|
45
53
|
return []
|
46
54
|
end
|
47
55
|
|
48
|
-
|
49
|
-
|
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??
|
50
62
|
## nothing found return empty array for now; return nil - why? why not?
|
51
63
|
puts "warn !!! no end marker found e.g. <<<|"
|
52
64
|
return []
|
53
65
|
end
|
54
66
|
|
55
|
-
## cutoff - get text between begin and end marker
|
56
|
-
buf = @text[ posbeg+4...posend ].strip
|
57
|
-
## pp buf
|
58
67
|
|
59
68
|
####
|
60
69
|
## pass 1: split blocks by </>
|
61
|
-
###
|
70
|
+
### note: allows <<<</>>>>
|
62
71
|
|
63
|
-
blocks = buf.split(
|
72
|
+
blocks = buf.split( /#{FEED_NEXT}/ )
|
64
73
|
## pp blocks
|
65
74
|
|
66
75
|
## 1st block is feed meta data
|
@@ -72,13 +81,17 @@ class Parser
|
|
72
81
|
### note: do NOT use split e.g.--- is used by markdown
|
73
82
|
## only search for first --- to split (all others get ignored)
|
74
83
|
## todo: make three dashes --- (3) not hard-coded (allow more)
|
75
|
-
posmeta = block.index( FEED_META_RX )
|
76
|
-
item = []
|
77
|
-
item[0] = block[0...posmeta].strip
|
78
|
-
item[1] = block[posmeta+3..-1].strip
|
79
84
|
|
80
|
-
|
81
|
-
|
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
|
82
95
|
|
83
96
|
feed_items << [item_metadata, item_content]
|
84
97
|
end
|
@@ -88,4 +101,5 @@ class Parser
|
|
88
101
|
|
89
102
|
|
90
103
|
end # class Parser
|
104
|
+
|
91
105
|
end # module Feedtxt
|
data/lib/feedtxt/version.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
###
|
2
|
+
# to run use
|
3
|
+
# ruby -I ./lib -I ./test test/test_scanner.rb
|
4
|
+
# or better
|
5
|
+
# rake test
|
6
|
+
|
7
|
+
require 'helper'
|
8
|
+
|
9
|
+
|
10
|
+
class TestScanner < MiniTest::Test
|
11
|
+
|
12
|
+
## note:
|
13
|
+
## regex excape pipe: | to \|
|
14
|
+
## note: \\ needs to get escaped twice e.g. (\\ becomes \)
|
15
|
+
FEED_BEGIN = %{^[ ]*\\|>>>+[ ]*$}
|
16
|
+
FEED_END = %{^[ ]*<<<+\\|[ ]*$}
|
17
|
+
|
18
|
+
def test_scan
|
19
|
+
|
20
|
+
text =<<TXT
|
21
|
+
bla bla bla
|
22
|
+
|>>>
|
23
|
+
title: "My Example Feed"
|
24
|
+
home_page_url: "https://example.org/"
|
25
|
+
feed_url: "https://example.org/feed.txt"
|
26
|
+
</>
|
27
|
+
id: "2"
|
28
|
+
url: "https://example.org/second-item"
|
29
|
+
---
|
30
|
+
This is a second item.
|
31
|
+
</>
|
32
|
+
id: "1"
|
33
|
+
url: "https://example.org/initial-post"
|
34
|
+
---
|
35
|
+
Hello, world!
|
36
|
+
<<<|
|
37
|
+
TXT
|
38
|
+
|
39
|
+
s = StringScanner.new( text )
|
40
|
+
|
41
|
+
prolog = s.scan_until( /(?=#{FEED_BEGIN})/ )
|
42
|
+
pp prolog
|
43
|
+
|
44
|
+
feed_begin = s.scan( /#{FEED_BEGIN}/ )
|
45
|
+
assert_equal '|>>>', feed_begin
|
46
|
+
|
47
|
+
body = s.scan_until( /(?=#{FEED_END})/ )
|
48
|
+
pp body
|
49
|
+
|
50
|
+
feed_end = s.scan( /#{FEED_END}/ )
|
51
|
+
assert_equal '<<<|', feed_end
|
52
|
+
|
53
|
+
assert true
|
54
|
+
end
|
55
|
+
|
56
|
+
end # class TestScanner
|
data/test/test_yaml.rb
CHANGED
@@ -14,11 +14,6 @@ class TestYaml < MiniTest::Test
|
|
14
14
|
text = read_text( 'spec/example.yaml' )
|
15
15
|
pp text
|
16
16
|
|
17
|
-
feed = Feedtxt::Parser.parse( text )
|
18
|
-
pp feed
|
19
|
-
|
20
|
-
## pp feed.to_json
|
21
|
-
|
22
17
|
exp = [
|
23
18
|
{"title"=>"My Example Feed",
|
24
19
|
"home_page_url"=>"https://example.org/",
|
@@ -32,8 +27,8 @@ class TestYaml < MiniTest::Test
|
|
32
27
|
"Hello, world!"
|
33
28
|
]]]
|
34
29
|
|
35
|
-
|
36
|
-
assert_equal exp,
|
30
|
+
assert_equal exp, Feedtxt::Parser.parse( text )
|
31
|
+
assert_equal exp, Feedtxt.parse( text ) ## try shortcut alias too
|
37
32
|
end
|
38
33
|
|
39
34
|
def test_podcast
|
@@ -41,11 +36,6 @@ class TestYaml < MiniTest::Test
|
|
41
36
|
text = read_text( 'spec/podcast.yaml' )
|
42
37
|
pp text
|
43
38
|
|
44
|
-
feed = Feedtxt::Parser.parse( text )
|
45
|
-
pp feed
|
46
|
-
|
47
|
-
## pp feed.to_json
|
48
|
-
|
49
39
|
exp =[{"comment"=>
|
50
40
|
"This is a podcast feed. You can add this feed to your podcast client using the following URL: http://therecord.co/feed.json",
|
51
41
|
"title"=>"The Record",
|
@@ -65,7 +55,8 @@ class TestYaml < MiniTest::Test
|
|
65
55
|
"duration_in_seconds"=>6629}]},
|
66
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/"]]]
|
67
57
|
|
68
|
-
assert_equal exp,
|
58
|
+
assert_equal exp, Feedtxt::Parser.parse( text )
|
59
|
+
assert_equal exp, Feedtxt.parse( text ) ## try shortcut alias too
|
69
60
|
end
|
70
61
|
|
71
62
|
|
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.
|
4
|
+
version: 0.2.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-
|
11
|
+
date: 2017-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rdoc
|
@@ -38,8 +38,8 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3.15'
|
41
|
-
description: feedtxt - reads Feed.TXT
|
42
|
-
posts, articles, podcasts, 'n' more
|
41
|
+
description: feedtxt - reads Feed.TXT a.k.a. RSS (Really Simple Sharing) 5.0 ;-) -
|
42
|
+
feeds in text (unicode) - publish & share posts, articles, podcasts, 'n' more
|
43
43
|
email: wwwmake@googlegroups.com
|
44
44
|
executables: []
|
45
45
|
extensions: []
|
@@ -58,7 +58,7 @@ files:
|
|
58
58
|
- test/feeds/spec/example.yaml.txt
|
59
59
|
- test/feeds/spec/podcast.yaml.txt
|
60
60
|
- test/helper.rb
|
61
|
-
- test/
|
61
|
+
- test/test_scanner.rb
|
62
62
|
- test/test_yaml.rb
|
63
63
|
homepage: https://github.com/feedtxt/feedtxt
|
64
64
|
licenses:
|
@@ -85,6 +85,6 @@ rubyforge_project:
|
|
85
85
|
rubygems_version: 2.6.7
|
86
86
|
signing_key:
|
87
87
|
specification_version: 4
|
88
|
-
summary: feedtxt - reads Feed.TXT
|
89
|
-
articles, podcasts, 'n' more
|
88
|
+
summary: feedtxt - reads Feed.TXT a.k.a. RSS (Really Simple Sharing) 5.0 ;-) - feeds
|
89
|
+
in text (unicode) - publish & share posts, articles, podcasts, 'n' more
|
90
90
|
test_files: []
|
data/test/test_version.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
###
|
2
|
-
# to run use
|
3
|
-
# ruby -I ./lib -I ./test test/test_version.rb
|
4
|
-
# or better
|
5
|
-
# rake test
|
6
|
-
|
7
|
-
require 'helper'
|
8
|
-
|
9
|
-
|
10
|
-
class TestVersion < MiniTest::Test
|
11
|
-
|
12
|
-
def test_version
|
13
|
-
|
14
|
-
puts "Feedtxt: #{Feedtxt::VERSION}"
|
15
|
-
|
16
|
-
assert true
|
17
|
-
end
|
18
|
-
|
19
|
-
end # class TestVersion
|