neruda 0.2.4 → 0.2.6

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.
@@ -1,299 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'time'
4
- require 'fileutils'
5
- # neruda/config is required by htmlizer
6
- require 'neruda/org_file/htmlizer'
7
- require 'neruda/org_file/extracter'
8
- require 'neruda/org_file/class_methods'
9
- require 'neruda/index'
10
- require 'neruda/version'
11
-
12
- module Neruda
13
- # Handles org files.
14
- #
15
- # This class is responsible for reading or writing existing or new org
16
- # files, and formating their content to be used on the generated
17
- # website.
18
- class OrgFile
19
- # @return [String] the title of the current org document, taken from
20
- # the ~#+title:~ header.
21
- attr_reader :title
22
-
23
- # @return [String] the subtitle of the current org document, taken
24
- # from the ~#+subtitle:~ header.
25
- attr_reader :subtitle
26
-
27
- # @return [DateTime] the date and time of the current org document,
28
- # taken from the ~#+date:~ header.
29
- attr_reader :date
30
-
31
- # @return [Boolean] wether a time has been extracted from the
32
- # current org document ~#+date:~ header.
33
- attr_reader :notime
34
-
35
- # The author of the current org document, taken from the ~#+author:~
36
- # header.
37
- #
38
- # If the current document doesn't have any authorship information,
39
- # the one from the ~config.yml~ file will be used instead
40
- #
41
- # @return [String] the author name
42
- attr_reader :author
43
-
44
- # @return [Array] the keywords list of the current org document,
45
- # taken from the ~#+keywords:~ header.
46
- attr_reader :keywords
47
-
48
- # @return [String] the description of this org document, taken from
49
- # the ~#+description:~ header.
50
- attr_reader :excerpt
51
-
52
- # The locale of the current org document, taken from the
53
- # ~#+language:~ header.
54
- #
55
- # If the current document doesn't have any language information, the
56
- # one from the ~config.yml~ file will be used instead, or "en" by
57
- # default.
58
- #
59
- # @return [String] the document lang
60
- attr_reader :lang
61
-
62
- # @return [String] the relative path to the source of this document.
63
- attr_reader :file
64
-
65
- # @return [String] the relative path to the generated html file of
66
- # this document.
67
- attr_reader :html_file
68
-
69
- # @return [String] the url of this document, build from the ~domain~
70
- # settings and the above {#html_file @html_file} attribute.
71
- attr_reader :url
72
-
73
- # @return [String] the project owning this document.
74
- attr_reader :project
75
-
76
- extend Neruda::OrgFileClassMethods
77
-
78
- include Neruda::OrgFileExtracter
79
- include Neruda::OrgFileHtmlizer
80
-
81
- # Prepares the file named by ~file_name~ for read and write
82
- # operations.
83
- #
84
- # If the file ~file_name~ does not exist, the new instance may be
85
- # populated by data given in the ~opts~ parameter.
86
- #
87
- # @example
88
- # File.exist? './test.org'
89
- # => true
90
- # o = Neruda::OrgFile.new('./test.org')
91
- # => #<Neruda::OrgFile @file='./test.org'...>
92
- # o.title
93
- # => "This is an existing test file"
94
- # File.exist? '/tmp/does_not_exist.org'
95
- # => false
96
- # o = Neruda::OrgFile.new('/tmp/does_not_exist.org')
97
- # => #<Neruda::OrgFile @file='/tmp/does_not_exist.org'...>
98
- # o.title
99
- # => ""
100
- # File.exist? '/tmp/other.org'
101
- # => false
102
- # o = Neruda::OrgFile.new('/tmp/other.org', title: 'New file')
103
- # => #<Neruda::OrgFile @file='/tmp/other.org'...>
104
- # o.title
105
- # => "New file"
106
- #
107
- # @param file_name [String] path to the corresponding Org file
108
- # @param opts [Hash] optional data to initialize new Org file
109
- # @option opts [String] title ('') the title of the new Org file
110
- # @option opts [String] author (system user or '') the author of the
111
- # document
112
- # @option opts [Boolean] verbose (false) if the
113
- # {Neruda::OrgFileHtmlizer#publish publish} method should output
114
- # emacs process messages
115
- # @option opts [String] project the project owning this file
116
- # must be stored
117
- # @return [Neruda::OrgFile] the new instance of Neruda::OrgFile
118
- def initialize(file_name, opts = {})
119
- file_name = nil if file_name == ''
120
- @file = file_name
121
- @html_file = nil
122
- @url = nil
123
- @project = opts.delete :project
124
- @options = opts
125
- build_html_file_and_url
126
- if @file && File.exist?(@file)
127
- extract_data
128
- else
129
- init_empty_file
130
- end
131
- end
132
-
133
- # Returns a String representation of the document date, which aims
134
- # to be used to sort several OrgFiles.
135
- #
136
- # The format used for the key is ~%Y%m%d%H%M%S~. If the current
137
- # OrgFile instance does not have a date, this mehod return
138
- # ~00000000000000~. If the current OrgFile instance does not have
139
- # time information, the date is padded with zeros.
140
- #
141
- # @example with the org header ~#+date: <2019-07-03 Wed 20:52:49>~
142
- # org_file.date
143
- # => #<DateTime: 2019-07-03T20:52:49+02:00...>
144
- # org_file.timekey
145
- # => "20190703205349"
146
- #
147
- # @example with the org header ~#+date: <2019-07-03 Wed>~
148
- # org_file.date
149
- # => #<DateTime: 2019-07-03T00:00:00+02:00...>
150
- # org_file.timekey
151
- # => "20190703000000"
152
- #
153
- # @example with no date header in the org file
154
- # org_file.date
155
- # => nil
156
- # org_file.timekey
157
- # => "00000000000000"
158
- #
159
- # @return [String] the document key
160
- def timekey
161
- return '00000000000000' if @date.nil?
162
- @date.strftime('%Y%m%d%H%M%S')
163
- end
164
-
165
- # Returns the current OrgFile instance DateTime as a String.
166
- #
167
- # This method accepts three values for the ~dateformat~ parameter:
168
- #
169
- # - ~:full~ (or ~:long~) :: outputs a complete date and time
170
- # representation, localized through R18n;
171
- # - ~:short~ :: outputs a short date representation (without time),
172
- # localized with R18n;
173
- # - ~:rfc3339~ :: outputs the RFC 3339 date and time representation,
174
- # used in atom feed.
175
- #
176
- # @param dateformat [Symbol] the format to use to convert DateTime
177
- # into String
178
- # @param year [Boolean] wether or not the ~:full~ format must
179
- # contain the year
180
- # @return [String] the document DateTime string representation
181
- def datestring(dateformat = :full, year: true)
182
- return '' if @date.nil?
183
- return R18n.l @date.to_date if dateformat == :short
184
- return @date.rfc3339 if dateformat == :rfc3339
185
- locale = R18n.get.locale
186
- long_fmt = R18n.t.neruda.index.full_date_format(
187
- date: locale.format_date_full(@date, year)
188
- )
189
- unless @notime
190
- long_fmt = R18n.t.neruda.index.full_date_with_time_format(
191
- date: long_fmt, time: locale.time_format.delete('_').strip
192
- )
193
- end
194
- locale.strftime(@date, long_fmt)
195
- end
196
-
197
- # Formats given ~string~ with values of the current OrgFile.
198
- #
199
- # This method expects to find percent-tags in the given ~string~ and
200
- # replace them by their corresponding value.
201
- #
202
- # *** Format:
203
- #
204
- # - %a :: the raw author name
205
- # - %A :: the HTML rendering of the author name, equivalent to
206
- # ~<span class="author">%a</span>~
207
- # - %d :: the ~:short~ date HTML representation, equivalent
208
- # to ~<time datetime="%I">%i</time>~
209
- # - %D :: the ~:full~ date and time HTML representation
210
- # - %i :: the raw ~:short~ date and time
211
- # - %I :: the raw ~:rfc3339~ date and time
212
- # - %k :: the keywords separated by a comma
213
- # - %K :: the HTML list rendering of the keywords
214
- # - %l :: the lang of the document
215
- # - %L :: the license information, taken from the
216
- # {Neruda::Config#settings}
217
- # - %n :: the Neruda name and version
218
- # - %N :: the Neruda name and version with a link to the project
219
- # home on the name
220
- # - %s :: the subtitle of the document
221
- # - %t :: the title of the document
222
- # - %u :: the web path to the related published HTML document
223
- # - %x :: the raw description (eXcerpt)
224
- # - %X :: the description, enclosed in an HTML ~p~ tag, equivalent
225
- # to ~<p>%x</p>~
226
- #
227
- # @example
228
- # org_file.format("Article written by %a the %d")
229
- # => "Article written by Alice Smith the Wednesday 3rd July"
230
- #
231
- # @return [String] the given ~string~ after replacement occurs
232
- # rubocop:disable Metrics/MethodLength
233
- # rubocop:disable Layout/LineLength
234
- def format(string)
235
- string.gsub('%a', @author)
236
- .gsub('%A', author_to_html)
237
- .gsub('%d', date_to_html(:short))
238
- .gsub('%D', date_to_html)
239
- .gsub('%i', datestring(:short))
240
- .gsub('%I', datestring(:rfc3339))
241
- .gsub('%k', @keywords.join(', '))
242
- .gsub('%K', keywords_to_html)
243
- .gsub('%l', @lang)
244
- .gsub('%L', (Neruda::Config.settings['license'] || '').gsub(/\s+/, ' ').strip)
245
- .gsub('%n', "Neruda #{Neruda::VERSION}")
246
- .gsub('%N', "<a href=\"https://git.umaneti.net/neruda/about/\">Neruda</a> #{Neruda::VERSION}")
247
- .gsub('%s', @subtitle)
248
- .gsub('%t', @title)
249
- .gsub('%u', @html_file || '')
250
- .gsub('%x', @excerpt)
251
- .gsub('%X', "<p>#{@excerpt}</p>")
252
- end
253
- # rubocop:enable Layout/LineLength
254
- # rubocop:enable Metrics/MethodLength
255
-
256
- # Writes the current OrgFile content to the underlying file.
257
- #
258
- # The intermediate parent folders are created if necessary.
259
- #
260
- # @return [Integer] the length written (as returned by the
261
- # underlying ~IO.write~ method call)
262
- def write
263
- raise TypeError, 'no conversion from nil file name to path.' if @file.nil?
264
- file_dir = File.dirname @file
265
- FileUtils.mkdir_p file_dir unless Dir.exist? file_dir
266
- IO.write @file, @content
267
- end
268
-
269
- private
270
-
271
- def build_html_file_and_url
272
- return if @file.nil?
273
- @html_file = Neruda::OrgFile.target_for_source(
274
- @file, @project, with_public_folder: false
275
- )
276
- @url = "#{Neruda::Config.settings['domain']}/#{@html_file}"
277
- end
278
-
279
- def init_empty_file
280
- @title = @options[:title] || ''
281
- @subtitle = ''
282
- @date = DateTime.now
283
- @notime = false
284
- @author = @options[:author] || Neruda::Config.settings['author']
285
- @keywords = []
286
- @lang = @options[:lang] || Neruda::Config.settings['lang']
287
- @excerpt = ''
288
- body = @options[:content] || ''
289
- @content = @options[:raw_content] || <<~ORG
290
- #+title: #{@title}
291
- #+date: <#{@date.strftime('%Y-%m-%d %a. %H:%M:%S')}>
292
- #+author: #{@author}
293
- #+language: #{@lang}
294
-
295
- #{body}
296
- ORG
297
- end
298
- end
299
- end
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'webrick'
4
- require 'neruda/config'
5
-
6
- module Neruda # rubocop:disable Style/Documentation
7
- # A tiny preview server, which main goal is to replace references to
8
- # the target domain by localhost.
9
- class PreviewServlet < WEBrick::HTTPServlet::AbstractServlet
10
- include WEBrick::HTTPUtils
11
-
12
- def do_GET(request, response) # rubocop:disable Naming/MethodName
13
- file = local_path(request.path)
14
- response.body = parse_body(file, "http://#{request.host}:#{request.port}")
15
- response.status = 200
16
- response.content_type = mime_type(file, DefaultMimeTypes)
17
- end
18
-
19
- private
20
-
21
- def local_path(requested_path)
22
- routes = Neruda::Config.settings.dig('preview', 'routes') || {}
23
- return routes[requested_path] if routes.has_key? requested_path
24
- local_path = Neruda::Config.settings['public_folder'] + requested_path
25
- if File.directory? local_path
26
- local_path = format(
27
- '%<path>s/index.html', path: local_path.delete_suffix('/')
28
- )
29
- end
30
- return local_path if File.exist? local_path
31
- raise WEBrick::HTTPStatus::NotFound, 'Not found.'
32
- end
33
-
34
- def parse_body(local_path, local_host)
35
- body = IO.read local_path
36
- return body unless local_path.match?(/\.(?:ht|x)ml\z/)
37
- domain = Neruda::Config.settings['domain']
38
- return body if domain == ''
39
- body.gsub(/"file:\/\//, format('"%<host>s', host: local_host))
40
- .gsub(/"#{domain}/, format('"%<host>s', host: local_host))
41
- end
42
- end
43
-
44
- class << self
45
- def start_preview
46
- # Inspired by ruby un.rb library, which allows normally to start a
47
- # webrick server in one line: ruby -run -e httpd public_html -p 5000
48
- port = Neruda::Config.settings.dig('preview', 'server_port') || 5000
49
- s = WEBrick::HTTPServer.new(Port: port)
50
- s.mount '/', Neruda::PreviewServlet
51
- ['TERM', 'QUIT', 'INT'].each { |sig| trap(sig, proc { s.shutdown }) }
52
- s.start
53
- end
54
- end
55
- end
@@ -1,118 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'nokogiri'
4
- require 'digest/md5'
5
- require 'neruda/org_file'
6
-
7
- module Neruda
8
- # Insert custom part inside generated HTML files.
9
- class Templater
10
- def initialize(source, dom, opts = {})
11
- @dom = dom
12
- @org_file = source
13
- @position = opts['type'] || 'after'
14
- @content = extract_content opts
15
- @element = @dom.css(opts['selector'])
16
- digest = Digest::MD5.hexdigest(@content)
17
- @check_line = " Neruda Template: #{digest} "
18
- end
19
-
20
- def apply
21
- flag_head
22
- content = @org_file.format(@content)
23
- @element.each do |e|
24
- insert_new_node_at e, content
25
- end
26
- end
27
-
28
- def in_head?
29
- @dom.xpath('//head').children.to_a.filter(&:comment?).each do |c|
30
- return true if c.text == @check_line
31
- end
32
- false
33
- end
34
-
35
- class << self
36
- def customize_output(file_name, source = nil)
37
- templates_to_apply = filter_templates(file_name)
38
- return if templates_to_apply.empty?
39
- if source.nil?
40
- sourcepath = Neruda::OrgFile.source_for_target(file_name)
41
- source = Neruda::OrgFile.new(sourcepath)
42
- end
43
- dom = open_dom(file_name)
44
- templates_to_apply.each do |t|
45
- tpl = Neruda::Templater.new(source, dom, t)
46
- next if tpl.in_head?
47
- tpl.apply
48
- end
49
- write_dom(file_name, dom)
50
- end
51
-
52
- private
53
-
54
- def filter_templates(file_name)
55
- templates = Neruda::Config.settings['templates']
56
- return [] if templates.nil? || templates.empty?
57
- templates.filter { |t| check_required_keys(t, file_name) }
58
- end
59
-
60
- def open_dom(file_name)
61
- file = File.new file_name, 'r'
62
- dom = Nokogiri::HTML file
63
- file.close
64
- dom
65
- end
66
-
67
- def write_dom(file_name, dom)
68
- file = File.new file_name, 'w'
69
- dom.write_to file
70
- file.close
71
- end
72
-
73
- def check_path(file_name, pathes)
74
- pub_folder = Neruda::Config.settings['public_folder']
75
- if pathes.is_a?(Array)
76
- pathes.each do |tp|
77
- return true if File.fnmatch?("#{pub_folder}#{tp}",
78
- file_name, File::FNM_DOTMATCH)
79
- end
80
- return false
81
- end
82
- File.fnmatch?("#{pub_folder}#{pathes}",
83
- file_name, File::FNM_DOTMATCH)
84
- end
85
-
86
- def check_required_keys(opts, file_name)
87
- return false unless opts.has_key?('selector')
88
- return false unless opts.has_key?('content') || opts.has_key?('source')
89
- return check_path(file_name, opts['path']) if opts.has_key?('path')
90
- true
91
- end
92
- end
93
-
94
- private
95
-
96
- def flag_head
97
- @dom.xpath('//head').first.prepend_child("<!--#{@check_line}-->\n")
98
- end
99
-
100
- def insert_new_node_at(elem, content)
101
- case @position
102
- when 'before'
103
- elem.add_previous_sibling content
104
- when 'replace'
105
- elem.replace content
106
- else
107
- elem.add_next_sibling content
108
- end
109
- end
110
-
111
- def extract_content(opts)
112
- return opts['content'] if opts['content']
113
- # If we don't have a content option, then we must have a source
114
- # one.
115
- @dom.css(opts['source']).unlink.to_s
116
- end
117
- end
118
- end
data/lib/neruda/utils.rb DELETED
@@ -1,214 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'uri'
4
- require 'rainbow'
5
- require 'net/http'
6
- require 'r18n-core'
7
- require 'neruda/config'
8
-
9
- module Neruda
10
- # Embeds usefull methods, mainly used in rake tasks.
11
- module Utils
12
- # @return [Hash] the possible throbber themes
13
- THROBBER_FRAMES = {
14
- 'basic' => '-\|/',
15
- 'basicdots' => '⋯⋱⋮⋰',
16
- 'moon' => '🌑🌒🌓🌔🌕🌖🌗🌘',
17
- 'clock' => '🕛🕐🕑🕒🕓🕔🕕🕖🕗🕘🕙🕚',
18
- 'bricks' => '⣷⣯⣟⡿⢿⣻⣽⣾',
19
- 'points' => '·⁘∷⁛∷⁘',
20
- 'quadrant2' => '▙▛▜▟',
21
- 'default' => ['⠁ ⠂ ⠄ ⡀ ⠄ ⠂ ⠁', '⠂ ⠁ ⠂ ⠄ ⡀ ⠄ ⠂', '⠄ ⠂ ⠁ ⠂ ⠄ ⡀ ⠄',
22
- '⡀ ⠄ ⠂ ⠁ ⠂ ⠄ ⡀', '⠄ ⡀ ⠄ ⠂ ⠁ ⠂ ⠄', '⠂ ⠄ ⡀ ⠄ ⠂ ⠁ ⠂']
23
- }.freeze
24
-
25
- # @return [Hash] the possible ~pablo~ options and their
26
- # configuration
27
- PABLO_OPTIONS = {
28
- '-a' => { long: 'author' },
29
- '-f' => { long: 'force', boolean: true },
30
- '-h' => { long: 'help', boolean: true, meth: :on_tail },
31
- '-l' => { long: 'lang', keyword: 'LOCALE' },
32
- '-p' => { long: 'path' },
33
- '-t' => { long: 'title' },
34
- '-v' => { long: 'verbose', boolean: true, meth: :on_tail },
35
- '-V' => { long: 'version', boolean: true, meth: :on_tail }
36
- }.freeze
37
-
38
- # @return [Hash] the possible ~pablo~ subcommands and their
39
- # configuration
40
- PABLO_COMMANDS = {
41
- 'init' => { opts: ['-a', '-h', '-l', '-t', '-v'] },
42
- 'config' => { alias: 'init' },
43
- 'preview' => { opts: ['-h'] },
44
- 'open' => { opts: ['-a', '-h', '-l', '-p', '-t', '-v'] },
45
- 'edit' => { alias: 'open' },
46
- 'build' => { opts: ['-f', '-h'] },
47
- 'publish' => { opts: ['-h'] },
48
- 'help' => { opts: ['-h'] },
49
- 'basic' => { opts: ['-h', '-V'], label: '<command>' }
50
- }.freeze
51
-
52
- class << self
53
- # Animates strings in the user console to alert him that something
54
- # is running in the background.
55
- #
56
- # The animation is chosen among a bunch of themes, with the
57
- # configuration option ~throbber~ (retrieved via
58
- # {Neruda::Config#settings}).
59
- #
60
- # @example
61
- # long_stuff = Thread.new { very_long_operation }
62
- # Neruda::Utils.throbber(long_stuff, 'Computing hard stuff:')
63
- #
64
- # @param thread [Thread] the long-running operation to decorate
65
- # @param message [String] the message to display before the throbber
66
- # @return [void]
67
- def throbber(thread, message)
68
- frames = select_throbber_frames
69
- begin
70
- run_and_decorate_thread thread, message, frames
71
- rescue RuntimeError => e
72
- throbber_error message
73
- raise e
74
- else
75
- done = Rainbow('done'.ljust(frames[0].length)).green
76
- puts "#{message} #{done}"
77
- end
78
- end
79
-
80
- # Returns the short and long options specification for a given
81
- # short option.
82
- #
83
- # This method use the {Neruda::Utils::PABLO_OPTIONS} Hash to
84
- # retrieve corresponding values.
85
- #
86
- # @example
87
- # spec = Neruda::Utils.decorate_option('-a')
88
- # => ['-a AUTHOR', '--author AUTHOR']
89
- #
90
- # @param short [String] the short option to decorate
91
- # @return [Array] the short and long specification for an option
92
- def decorate_option(short)
93
- opt = Neruda::Utils::PABLO_OPTIONS[short]
94
- long = "--#{opt[:long]}"
95
- return [short, long] if opt[:boolean]
96
- key = opt[:keyword] || opt[:long].upcase
97
- [short + key, format('%<long>s %<key>s', long: long, key: key)]
98
- end
99
-
100
- # Returns the ~pablo~ help summary for a given command.
101
- #
102
- # @param command [String] the command for which a summary
103
- # should be given
104
- # @return [String]
105
- def summarize_command(command)
106
- Neruda::Utils::PABLO_COMMANDS[command][:opts].map do |k|
107
- short, long = Neruda::Utils.decorate_option(k)
108
- opt = Neruda::Utils::PABLO_OPTIONS[k]
109
- label = [short, long].join(', ')
110
- line = [format(' %<opt>s', opt: label).ljust(30)]
111
- if R18n.t.pablo.options[opt[:long]].translated?
112
- line << R18n.t.pablo.options[opt[:long]]
113
- end
114
- line.join(' ')
115
- end.join("\n")
116
- end
117
-
118
- # Returns a formatted list of available commands for ~pablo~.
119
- #
120
- # @return [String]
121
- def list_commands
122
- lines = []
123
- Neruda::Utils::PABLO_COMMANDS.each do |cmd, opt|
124
- next if cmd == 'basic'
125
- line = [' ', cmd.ljust(10)]
126
- if opt.has_key? :alias
127
- line << R18n.t.pablo.commands.alias(opt[:alias])
128
- else
129
- line << R18n.t.pablo.commands[cmd]
130
- end
131
- lines << line.join(' ')
132
- end
133
- lines.join("\n")
134
- end
135
-
136
- # Returns the real command name for a given command, which may be
137
- # an alias.
138
- #
139
- # @param command [String] the command to resolve
140
- # @return [String]
141
- def resolve_possible_alias(command)
142
- return 'basic' unless Neruda::Utils::PABLO_COMMANDS.include?(command)
143
- cmd_opt = Neruda::Utils::PABLO_COMMANDS[command]
144
- return cmd_opt[:alias] if cmd_opt.has_key?(:alias)
145
- command
146
- end
147
-
148
- # Try to discover the current host operating system.
149
- #
150
- # @return [String] either apple, windows or linux (default)
151
- # :nocov:
152
- def current_os
153
- if ENV['OS'] == 'Windows_NT' || RUBY_PLATFORM.include?('cygwin')
154
- return 'windows'
155
- end
156
- return 'apple' if RUBY_PLATFORM.include?('darwin')
157
- 'linux'
158
- end
159
- # :nocov:
160
-
161
- # Download latest org-mode tarball.
162
- #
163
- # @return [String] the downloaded org-mode version
164
- def download_org
165
- # :nocov:
166
- return if Neruda::Config.org_last_version.nil?
167
- # :nocov:
168
- tarball = "org-#{Neruda::Config.org_last_version}.tar.gz"
169
- # Remove version number in dest file to allow easy rake file
170
- # task naming
171
- dest_file = 'tmp/org.tar.gz'
172
- return if File.exist?(dest_file)
173
- uri = URI("https://orgmode.org/#{tarball}")
174
- # Will crash on purpose if anything goes wrong
175
- Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
176
- http.request(Net::HTTP::Get.new(uri)) do |response|
177
- File.open(dest_file, 'w') do |io|
178
- response.read_body { |chunk| io.write chunk }
179
- end
180
- end
181
- end
182
- end
183
-
184
- private
185
-
186
- def throbber_error(message)
187
- warn(
188
- format(
189
- "%<message>s %<label>s\n%<explanation>s",
190
- message: message,
191
- label: Rainbow(R18n.t.neruda.error.label).bold.red,
192
- explanation: Rainbow(R18n.t.neruda.error.explanation).bold
193
- )
194
- )
195
- end
196
-
197
- def select_throbber_frames
198
- model = Neruda::Config.settings['throbber'] || 'default'
199
- model = 'default' unless Neruda::Utils::THROBBER_FRAMES.has_key?(model)
200
- Neruda::Utils::THROBBER_FRAMES[model]
201
- end
202
-
203
- def run_and_decorate_thread(thread, message, frames)
204
- thread.abort_on_exception = true
205
- current = 0
206
- while thread.alive?
207
- sleep 0.1
208
- print "#{message} #{frames[current % frames.length]}\r"
209
- current += 1
210
- end
211
- end
212
- end
213
- end
214
- end