rfc-reader 1.1.1 → 1.2.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
  SHA256:
3
- metadata.gz: cc7f0a4142e7e5cb5b1ed4b8a5ecda4728177df15e6f9c8d7e84dcc557b660e4
4
- data.tar.gz: 89e7ac7472c84e84d87feed86e66f35f14dbc65a7af39e6a55fe65e158b78e89
3
+ metadata.gz: 9d0a782273a9c8f8accd5e24f7b526c7e12e03f870dec176fa7a48fc74650259
4
+ data.tar.gz: 7c682de619ec580ab71819c50913c609a422696bfb4b64d52b090688fba6773f
5
5
  SHA512:
6
- metadata.gz: 0b0588ecb6c225fa8d2ef6c1c27506dda70d59ae2af050797f6ed71536a379423848570022223b04f0911ca3d987431d2b28ab4c019c8c74c31ece1fed3e037a
7
- data.tar.gz: 51e9100f05269801e8fcbbe879405181ae0d3910e42593d5a9ad5933d6d8f3f45214cc8a8827d809b75e920029ccfd7584139c707e6a9e3fe0ec12ca750c4f77
6
+ metadata.gz: a543898b48200f9f4f1e99a592ffdb903e83957bde3df0c8b8c91fee92f2690927309259524c4ee1eb126e33a79aa0b18ef0bcb463c4ef448a611b67321e69ff
7
+ data.tar.gz: f3e4c4d6f6ba2c4cd4aa5620c7801753c9e1fe4b29adb595014ee27e639e34b7ca37faea7fd79e8c2dc00c7952d60f224d087a85cdbc9e81e1d574c06ccb4c93
@@ -49,10 +49,11 @@ module RfcReader
49
49
  warn "No search results for: #{term}"
50
50
  return FAILURE
51
51
  end
52
- title = Terminal.choose("Choose an RFC to read:", search_results.keys)
53
- url = search_results.fetch(title)
54
- content = Library.download_document(title: title, url: url)
55
- Terminal.page(content)
52
+ Terminal.choose("Choose an RFC to read:", search_results.keys) do |title|
53
+ url = search_results.fetch(title)
54
+ content = Library.download_document(title: title, url: url)
55
+ Terminal.page(content)
56
+ end
56
57
  SUCCESS
57
58
  end
58
59
 
@@ -70,10 +71,11 @@ module RfcReader
70
71
  warn "Error: Empty recent RFC list from rfc-editor.org RSS feed"
71
72
  return FAILURE
72
73
  end
73
- title = Terminal.choose("Choose an RFC to read:", recent_results.keys)
74
- url = recent_results.fetch(title)
75
- content = Library.download_document(title: title, url: url)
76
- Terminal.page(content)
74
+ Terminal.choose("Choose an RFC to read:", recent_results.keys) do |title|
75
+ url = recent_results.fetch(title)
76
+ content = Library.download_document(title: title, url: url)
77
+ Terminal.page(content)
78
+ end
77
79
  SUCCESS
78
80
  end
79
81
 
@@ -95,10 +97,11 @@ module RfcReader
95
97
  return FAILURE
96
98
  end
97
99
  all_titles = rfc_catalog.map { _1[:title] }
98
- title = Terminal.choose("Choose an RFC to read:", all_titles)
99
- rfc = rfc_catalog.find { _1[:title] == title }
100
- content = Library.load_document(**rfc)
101
- Terminal.page(content)
100
+ Terminal.choose("Choose an RFC to read:", all_titles) do |title|
101
+ rfc = rfc_catalog.find { _1[:title] == title }
102
+ content = Library.load_document(**rfc)
103
+ Terminal.page(content)
104
+ end
102
105
  SUCCESS
103
106
  end
104
107
 
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "net/http"
4
- require "nokogiri"
4
+ require "rss"
5
5
 
6
6
  module RfcReader
7
7
  module Recent
8
- RECENT_RFCS_RSS_URI = URI("https://www.rfc-editor.org/rfcrss.xml").freeze
8
+ RECENT_RFCS_RSS_URI = URI("https://www.rfc-editor.org/rfcatom.xml").freeze
9
9
  private_constant :RECENT_RFCS_RSS_URI
10
10
 
11
11
  # @return [Hash<String, String>] from RFC title to text file url
@@ -39,16 +39,12 @@ module RfcReader
39
39
  # @return [Hash<String, String>] from RFC title to text file url
40
40
  def self.parse(xml)
41
41
  ErrorContext.wrap("Parsing the recent RFCs list") do
42
- Nokogiri::XML(xml).xpath("//item").to_h do |item|
43
- item_hash = item.elements.to_h do |elem|
44
- [elem.name, elem.text.strip]
45
- end
46
-
42
+ RSS::Parser.parse(xml).items.to_h do |item|
47
43
  # The link is to the webpage and not the plaintext document so we must convert it.
48
- file_name = File.basename(item_hash.fetch("link"))
44
+ file_name = File.basename(item.link.href)
49
45
 
50
46
  [
51
- item_hash.fetch("title"),
47
+ item.title.content,
52
48
  "https://www.rfc-editor.org/rfc/#{file_name}.txt",
53
49
  ]
54
50
  end
@@ -10,17 +10,75 @@ module RfcReader
10
10
 
11
11
  # @param prompt [String]
12
12
  # @param choices [Array<String>] where all choices are unique
13
- def self.choose(prompt, choices)
14
- require "tty-prompt"
15
- TTY::Prompt
16
- .new(
13
+ # @yield [String] yields until the user exits the prompt gracefully
14
+ def self.choose(message, choices)
15
+ while (choice = selector.select(message, choices))
16
+ yield choice
17
+ end
18
+ end
19
+
20
+ # @return [Selector]
21
+ def self.selector
22
+ @selector ||= Selector.new
23
+ end
24
+ private_class_method :selector
25
+
26
+ # Wrapper around `TTY::Prompt` that adds Vim keybindings and
27
+ # the ability to gracefully exit the prompt.
28
+ class Selector
29
+ def initialize
30
+ require "tty-prompt"
31
+ @prompt = TTY::Prompt.new(
17
32
  quiet: true,
18
33
  track_history: false,
19
34
  interrupt: :exit,
20
35
  symbols: { marker: ">" },
21
36
  enable_color: !ENV["NO_COLOR"]
22
37
  )
23
- .select(prompt, choices)
38
+
39
+ # Indicate user intention to exit
40
+ @exit = false
41
+
42
+ # vim keybindings
43
+ @prompt.on(:keypress) do |event|
44
+ case event.value
45
+ when "j" # Move down
46
+ @prompt.trigger(:keydown)
47
+ when "k" # Move up
48
+ @prompt.trigger(:keyup)
49
+ when "h" # Move left
50
+ @prompt.trigger(:keyleft)
51
+ when "l" # Move right
52
+ @prompt.trigger(:keyright)
53
+ when "q" # Exit
54
+ @exit = true
55
+ @prompt.trigger(:keyenter)
56
+ end
57
+ end
58
+
59
+ # Exit on escape
60
+ @prompt.on(:keyescape) do
61
+ @exit = true
62
+ @prompt.trigger(:keyenter)
63
+ end
64
+ end
65
+
66
+ # @param prompt [String]
67
+ # @param choices [Array<String>] where all choices are unique
68
+ # @return [String|nil]
69
+ def select(message, choices)
70
+ choice = @prompt.select(
71
+ message,
72
+ choices,
73
+ per_page: 15,
74
+ help: "(Press Enter to select and Escape to leave)",
75
+ show_help: :always
76
+ )
77
+ choice unless @exit
78
+ ensure
79
+ @exit = false
80
+ end
24
81
  end
82
+ private_constant :Selector
25
83
  end
26
84
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RfcReader
4
- VERSION = "1.1.1"
4
+ VERSION = "1.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rfc-reader
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Robell
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-10-06 00:00:00.000000000 Z
10
+ date: 2025-01-20 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: nokogiri
@@ -24,6 +23,20 @@ dependencies:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
25
  version: '1.16'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rss
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '0.3'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.3'
27
40
  - !ruby/object:Gem::Dependency
28
41
  name: thor
29
42
  requirement: !ruby/object:Gem::Requirement
@@ -66,7 +79,6 @@ dependencies:
66
79
  - - "~>"
67
80
  - !ruby/object:Gem::Version
68
81
  version: '0.23'
69
- description:
70
82
  email:
71
83
  - apainintheneck@gmail.com
72
84
  executables:
@@ -91,7 +103,6 @@ metadata:
91
103
  source_code_uri: https://github.com/apainintheneck/rfc-reader/
92
104
  changelog_uri: https://github.com/apainintheneck/rfc-reader/blob/main/CHANELOG.md
93
105
  rubygems_mfa_required: 'true'
94
- post_install_message:
95
106
  rdoc_options: []
96
107
  require_paths:
97
108
  - lib
@@ -106,8 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
117
  - !ruby/object:Gem::Version
107
118
  version: '0'
108
119
  requirements: []
109
- rubygems_version: 3.5.6
110
- signing_key:
120
+ rubygems_version: 3.6.3
111
121
  specification_version: 4
112
122
  summary: Search for and read RFCs at the command line.
113
123
  test_files: []