neruda 0.1.2 → 0.2.4

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.
@@ -7,6 +7,7 @@ require 'neruda/org_file/htmlizer'
7
7
  require 'neruda/org_file/extracter'
8
8
  require 'neruda/org_file/class_methods'
9
9
  require 'neruda/index'
10
+ require 'neruda/version'
10
11
 
11
12
  module Neruda
12
13
  # Handles org files.
@@ -19,6 +20,10 @@ module Neruda
19
20
  # the ~#+title:~ header.
20
21
  attr_reader :title
21
22
 
23
+ # @return [String] the subtitle of the current org document, taken
24
+ # from the ~#+subtitle:~ header.
25
+ attr_reader :subtitle
26
+
22
27
  # @return [DateTime] the date and time of the current org document,
23
28
  # taken from the ~#+date:~ header.
24
29
  attr_reader :date
@@ -40,6 +45,10 @@ module Neruda
40
45
  # taken from the ~#+keywords:~ header.
41
46
  attr_reader :keywords
42
47
 
48
+ # @return [String] the description of this org document, taken from
49
+ # the ~#+description:~ header.
50
+ attr_reader :excerpt
51
+
43
52
  # The locale of the current org document, taken from the
44
53
  # ~#+language:~ header.
45
54
  #
@@ -61,9 +70,8 @@ module Neruda
61
70
  # settings and the above {#html_file @html_file} attribute.
62
71
  attr_reader :url
63
72
 
64
- # @return [String] the description of this org document, taken from
65
- # the ~#+description:~ header.
66
- attr_reader :excerpt
73
+ # @return [String] the project owning this document.
74
+ attr_reader :project
67
75
 
68
76
  extend Neruda::OrgFileClassMethods
69
77
 
@@ -96,21 +104,25 @@ module Neruda
96
104
  # o.title
97
105
  # => "New file"
98
106
  #
99
- # @param file_name [String] path to the corresponding org mode file
100
- # @param opts [Hash] optional data to initialize new org file
101
- # @option opts [String] title ('') the title of the new org file
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
102
110
  # @option opts [String] author (system user or '') the author of the
103
111
  # document
104
112
  # @option opts [Boolean] verbose (false) if the
105
113
  # {Neruda::OrgFileHtmlizer#publish publish} method should output
106
114
  # emacs process messages
115
+ # @option opts [String] project the project owning this file
116
+ # must be stored
107
117
  # @return [Neruda::OrgFile] the new instance of Neruda::OrgFile
108
118
  def initialize(file_name, opts = {})
109
119
  file_name = nil if file_name == ''
110
120
  @file = file_name
111
- @html_file = Neruda::OrgFile.html_file @file
112
- @url = Neruda::OrgFile.html_file_with_domain @file
121
+ @html_file = nil
122
+ @url = nil
123
+ @project = opts.delete :project
113
124
  @options = opts
125
+ build_html_file_and_url
114
126
  if @file && File.exist?(@file)
115
127
  extract_data
116
128
  else
@@ -166,7 +178,7 @@ module Neruda
166
178
  # @param year [Boolean] wether or not the ~:full~ format must
167
179
  # contain the year
168
180
  # @return [String] the document DateTime string representation
169
- def datestring(dateformat = :full, year = true)
181
+ def datestring(dateformat = :full, year: true)
170
182
  return '' if @date.nil?
171
183
  return R18n.l @date.to_date if dateformat == :short
172
184
  return @date.rfc3339 if dateformat == :rfc3339
@@ -202,6 +214,10 @@ module Neruda
202
214
  # - %l :: the lang of the document
203
215
  # - %L :: the license information, taken from the
204
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
205
221
  # - %t :: the title of the document
206
222
  # - %u :: the web path to the related published HTML document
207
223
  # - %x :: the raw description (eXcerpt)
@@ -213,8 +229,9 @@ module Neruda
213
229
  # => "Article written by Alice Smith the Wednesday 3rd July"
214
230
  #
215
231
  # @return [String] the given ~string~ after replacement occurs
232
+ # rubocop:disable Metrics/MethodLength
233
+ # rubocop:disable Layout/LineLength
216
234
  def format(string)
217
- license = Neruda::Config.settings['license'] || ''
218
235
  string.gsub('%a', @author)
219
236
  .gsub('%A', author_to_html)
220
237
  .gsub('%d', date_to_html(:short))
@@ -224,12 +241,17 @@ module Neruda
224
241
  .gsub('%k', @keywords.join(', '))
225
242
  .gsub('%K', keywords_to_html)
226
243
  .gsub('%l', @lang)
227
- .gsub('%L', license.gsub(/\s+/, ' ').strip)
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)
228
248
  .gsub('%t', @title)
229
- .gsub('%u', @html_file)
249
+ .gsub('%u', @html_file || '')
230
250
  .gsub('%x', @excerpt)
231
251
  .gsub('%X', "<p>#{@excerpt}</p>")
232
252
  end
253
+ # rubocop:enable Layout/LineLength
254
+ # rubocop:enable Metrics/MethodLength
233
255
 
234
256
  # Writes the current OrgFile content to the underlying file.
235
257
  #
@@ -246,20 +268,31 @@ module Neruda
246
268
 
247
269
  private
248
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
+
249
279
  def init_empty_file
250
280
  @title = @options[:title] || ''
281
+ @subtitle = ''
251
282
  @date = DateTime.now
252
283
  @notime = false
253
284
  @author = @options[:author] || Neruda::Config.settings['author']
254
285
  @keywords = []
255
286
  @lang = @options[:lang] || Neruda::Config.settings['lang']
256
287
  @excerpt = ''
257
- @content = @options[:content] || <<~ORG
288
+ body = @options[:content] || ''
289
+ @content = @options[:raw_content] || <<~ORG
258
290
  #+title: #{@title}
259
291
  #+date: <#{@date.strftime('%Y-%m-%d %a. %H:%M:%S')}>
260
292
  #+author: #{@author}
261
293
  #+language: #{@lang}
262
294
 
295
+ #{body}
263
296
  ORG
264
297
  end
265
298
  end
@@ -3,39 +3,56 @@
3
3
  module Neruda
4
4
  # This module holds class methods for the {Neruda::OrgFile} class.
5
5
  module OrgFileClassMethods
6
- def html_file(file_name)
7
- return nil if file_name.nil?
8
- path = Neruda::OrgFile.target_for_source(file_name)
6
+ def source_for_target(file_name)
7
+ # file_name may be frozen...
8
+ src = file_name.sub(/\.html\z/, '.org')
9
9
  pubfolder = Neruda::Config.settings['public_folder']
10
- path.sub(/^#{pubfolder}\//, '/')
10
+ src.sub!(/^#{pubfolder}\//, '')
11
+ # Look for match in each possible sources. The first found wins.
12
+ Neruda::Config.sources.each do |project|
13
+ if project['target'] == '.'
14
+ origin = File.join(project['path'], src)
15
+ else
16
+ origin = File.join(
17
+ project['path'], src.sub(/^#{project['target']}\//, '')
18
+ )
19
+ end
20
+ return origin if File.exist?(origin)
21
+ end
22
+ nil
11
23
  end
12
24
 
13
- def html_file_with_domain(file_name)
25
+ def target_for_source(file_name, project, with_public_folder: true)
14
26
  return nil if file_name.nil?
15
- Neruda::Config.settings['domain'] + html_file(file_name)
16
- end
17
-
18
- def source_for_target(file_name)
19
27
  # file_name may be frozen...
20
- src = file_name.sub(/\.html$/, '.org')
28
+ target = file_name.sub(/\.org\z/, '.html').sub(/^#{Dir.pwd}\//, '')
29
+ if project.nil?
30
+ subfolder = File.basename(File.dirname(target))
31
+ target = File.basename(target)
32
+ target = "#{subfolder}/#{target}" if subfolder != '.'
33
+ else
34
+ project_relative_path = project['path'].sub(/^#{Dir.pwd}\//, '')
35
+ target.sub!(/^#{project_relative_path}\//, '')
36
+ target = "#{project['target']}/#{target}" if project['target'] != '.'
37
+ end
38
+ return target unless with_public_folder
21
39
  pubfolder = Neruda::Config.settings['public_folder']
22
- src.sub(/^#{pubfolder}\//, 'src/')
40
+ "#{pubfolder}/#{target}"
23
41
  end
24
42
 
25
- def target_for_source(file_name)
26
- # file_name may be frozen...
27
- target = file_name.sub(/\.org$/, '.html')
28
- pubfolder = Neruda::Config.settings['public_folder']
29
- return target.sub(/^src\//, "#{pubfolder}/") if /^src\//.match?(target)
30
- subfolder = File.basename(File.dirname(target))
31
- leaf = File.basename(target)
32
- "#{pubfolder}/#{subfolder}/#{leaf}"
43
+ def project_for_source(file_name)
44
+ # Look for match in each possible sources. The first found wins.
45
+ Neruda::Config.sources.each do |project|
46
+ project_relative_path = project['path'].sub(/^#{Dir.pwd}\//, '')
47
+ return project if file_name.match?(/^#{project_relative_path}\//)
48
+ end
49
+ nil
33
50
  end
34
51
 
35
52
  def slug(title)
36
- title.downcase.gsub(' ', '-')
53
+ title.downcase.tr(' ', '-')
37
54
  .encode('ascii', fallback: ->(k) { translit(k) })
38
- .gsub(/[^\w-]/, '').gsub(/-$/, '')
55
+ .gsub(/[^\w-]/, '').delete_suffix('-')
39
56
  end
40
57
 
41
58
  private
@@ -10,6 +10,7 @@ module Neruda
10
10
  def extract_data
11
11
  @content = IO.read @file
12
12
  @title = extract_title
13
+ @subtitle = extract_subtitle
13
14
  @date = extract_date
14
15
  @author = extract_author
15
16
  @keywords = extract_keywords
@@ -32,7 +33,17 @@ module Neruda
32
33
 
33
34
  def extract_title
34
35
  m = /^#\+title:(.+)$/i.match(@content)
35
- return @file if m.nil?
36
+ if m.nil?
37
+ # Avoid to leak absolute path
38
+ project_relative_path = @file.sub(/^#{Dir.pwd}\//, '')
39
+ return project_relative_path
40
+ end
41
+ m[1].strip
42
+ end
43
+
44
+ def extract_subtitle
45
+ m = /^#\+subtitle:(.+)$/i.match(@content)
46
+ return '' if m.nil?
36
47
  m[1].strip
37
48
  end
38
49
 
@@ -1,24 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'neruda/config'
4
+ require 'neruda/emacs'
4
5
 
5
6
  module Neruda
6
7
  # This module holds HTML formatter methods for the {Neruda::OrgFile}
7
8
  # class.
8
9
  module OrgFileHtmlizer
9
- # Publish the current file or the entire project if
10
- # {Neruda::OrgFile#file @file} is ~nil~.
11
- #
12
- # @return [Boolean, nil] the underlying ~system~ method return value
13
- def publish
14
- if @file.nil?
15
- emacs_args = ['--eval \'(org-publish "website")\'']
16
- else
17
- emacs_args = ['-f org-publish-current-file']
18
- end
19
- call_emacs emacs_args
20
- end
21
-
22
10
  private
23
11
 
24
12
  # Format {Neruda::OrgFile#keywords} list in an HTML listing.
@@ -40,7 +28,7 @@ module Neruda
40
28
  #
41
29
  # @return [String] the HTML `time` tag
42
30
  def date_to_html(dateformat = :full)
43
- return '' if @date.nil?
31
+ return '<time></time>' if @date.nil?
44
32
  "<time datetime=\"#{@date.rfc3339}\">#{datestring(dateformat)}</time>"
45
33
  end
46
34
 
@@ -49,30 +37,7 @@ module Neruda
49
37
  #
50
38
  # @return [String] the author HTML `span`
51
39
  def author_to_html
52
- return '' if @author == ''
53
40
  "<span class=\"author\">#{@author}</span>"
54
41
  end
55
-
56
- def emacs_command(arguments = [])
57
- default_emacs = Neruda::Config.settings['emacs']
58
- emacs_cmd = [default_emacs || 'emacs -Q --batch -nw']
59
- emacs_cmd << '--eval \'(setq enable-dir-local-variables nil)\''
60
- unless @options[:verbose]
61
- emacs_cmd << '--eval \'(setq inhibit-message t)\''
62
- end
63
- emacs_cmd << '-l ./org-config.el'
64
- emacs_cmd << "--eval '(find-file \"#{@file}\")'" unless @file.nil?
65
- emacs_cmd.concat(arguments)
66
- emacs_cmd.join(' ')
67
- end
68
-
69
- def call_emacs(arguments = [])
70
- command = emacs_command arguments
71
- if @options[:verbose]
72
- warn command
73
- return system(command, exception: true)
74
- end
75
- system command, out: '/dev/null', err: '/dev/null', exception: true
76
- end
77
42
  end
78
43
  end
@@ -19,11 +19,13 @@ module Neruda # rubocop:disable Style/Documentation
19
19
  private
20
20
 
21
21
  def local_path(requested_path)
22
- routes = Neruda::Config.settings['routes'] || {}
23
- return routes[requested_path] if routes.keys.include? requested_path
22
+ routes = Neruda::Config.settings.dig('preview', 'routes') || {}
23
+ return routes[requested_path] if routes.has_key? requested_path
24
24
  local_path = Neruda::Config.settings['public_folder'] + requested_path
25
25
  if File.directory? local_path
26
- local_path = local_path.delete_suffix('/') + '/index.html'
26
+ local_path = format(
27
+ '%<path>s/index.html', path: local_path.delete_suffix('/')
28
+ )
27
29
  end
28
30
  return local_path if File.exist? local_path
29
31
  raise WEBrick::HTTPStatus::NotFound, 'Not found.'
@@ -31,11 +33,11 @@ module Neruda # rubocop:disable Style/Documentation
31
33
 
32
34
  def parse_body(local_path, local_host)
33
35
  body = IO.read local_path
34
- return body unless local_path.match?(/\.(?:ht|x)ml$/)
36
+ return body unless local_path.match?(/\.(?:ht|x)ml\z/)
35
37
  domain = Neruda::Config.settings['domain']
36
38
  return body if domain == ''
37
- body.gsub(/"file:\/\//, '"' + local_host)
38
- .gsub(/"#{domain}/, '"' + local_host)
39
+ body.gsub(/"file:\/\//, format('"%<host>s', host: local_host))
40
+ .gsub(/"#{domain}/, format('"%<host>s', host: local_host))
39
41
  end
40
42
  end
41
43
 
@@ -43,7 +45,7 @@ module Neruda # rubocop:disable Style/Documentation
43
45
  def start_preview
44
46
  # Inspired by ruby un.rb library, which allows normally to start a
45
47
  # webrick server in one line: ruby -run -e httpd public_html -p 5000
46
- port = Neruda::Config.settings['server_port'] || 5000
48
+ port = Neruda::Config.settings.dig('preview', 'server_port') || 5000
47
49
  s = WEBrick::HTTPServer.new(Port: port)
48
50
  s.mount '/', Neruda::PreviewServlet
49
51
  ['TERM', 'QUIT', 'INT'].each { |sig| trap(sig, proc { s.shutdown }) }
@@ -11,7 +11,7 @@ module Neruda
11
11
  @dom = dom
12
12
  @org_file = source
13
13
  @position = opts['type'] || 'after'
14
- @content = opts['content']
14
+ @content = extract_content opts
15
15
  @element = @dom.css(opts['selector'])
16
16
  digest = Digest::MD5.hexdigest(@content)
17
17
  @check_line = " Neruda Template: #{digest} "
@@ -54,15 +54,7 @@ module Neruda
54
54
  def filter_templates(file_name)
55
55
  templates = Neruda::Config.settings['templates']
56
56
  return [] if templates.nil? || templates.empty?
57
- templates.filter do |t|
58
- if !t.has_key?('selector') || !t.has_key?('content')
59
- false
60
- elsif t.has_key?('path') && !check_path(file_name, t['path'])
61
- false
62
- else
63
- true
64
- end
65
- end
57
+ templates.filter { |t| check_required_keys(t, file_name) }
66
58
  end
67
59
 
68
60
  def open_dom(file_name)
@@ -90,6 +82,13 @@ module Neruda
90
82
  File.fnmatch?("#{pub_folder}#{pathes}",
91
83
  file_name, File::FNM_DOTMATCH)
92
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
93
92
  end
94
93
 
95
94
  private
@@ -99,13 +98,21 @@ module Neruda
99
98
  end
100
99
 
101
100
  def insert_new_node_at(elem, content)
102
- if @position == 'before'
101
+ case @position
102
+ when 'before'
103
103
  elem.add_previous_sibling content
104
- elsif @position == 'replace'
104
+ when 'replace'
105
105
  elem.replace content
106
106
  else
107
107
  elem.add_next_sibling content
108
108
  end
109
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
110
117
  end
111
118
  end
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'uri'
3
4
  require 'rainbow'
5
+ require 'net/http'
6
+ require 'r18n-core'
4
7
  require 'neruda/config'
5
8
 
6
9
  module Neruda
@@ -23,35 +26,26 @@ module Neruda
23
26
  # configuration
24
27
  PABLO_OPTIONS = {
25
28
  '-a' => { long: 'author' },
29
+ '-f' => { long: 'force', boolean: true },
30
+ '-h' => { long: 'help', boolean: true, meth: :on_tail },
26
31
  '-l' => { long: 'lang', keyword: 'LOCALE' },
32
+ '-p' => { long: 'path' },
27
33
  '-t' => { long: 'title' },
28
- '-p' => { long: 'path', desc: 'Path to the new file' },
29
- '-d' => { long: 'directory', boolean: true,
30
- desc: 'Wrap the new org file in a named folder' },
31
34
  '-v' => { long: 'verbose', boolean: true, meth: :on_tail },
32
- '-h' => { long: 'help', boolean: true, meth: :on_tail,
33
- desc: 'Display help for a command and exit' },
34
- '-V' => { long: 'version', boolean: true, meth: :on_tail,
35
- desc: 'Display Neruda version and exit' }
35
+ '-V' => { long: 'version', boolean: true, meth: :on_tail }
36
36
  }.freeze
37
37
 
38
38
  # @return [Hash] the possible ~pablo~ subcommands and their
39
39
  # configuration
40
40
  PABLO_COMMANDS = {
41
- 'init' => { opts: ['-a', '-l', '-t', '-v', '-h'],
42
- desc: 'Initialize your Neruda instance ' \
43
- '(you just need to do it once).' },
41
+ 'init' => { opts: ['-a', '-h', '-l', '-t', '-v'] },
44
42
  'config' => { alias: 'init' },
45
- 'preview' => { opts: ['-h'],
46
- desc: 'Start a test webserver to preview ' \
47
- 'your website on http://127.0.0.1:5000' },
48
- 'open' => { opts: ['-a', '-l', '-t', '-d', '-p', '-v', '-h'],
49
- desc: 'Open or create an org file for edition.' },
43
+ 'preview' => { opts: ['-h'] },
44
+ 'open' => { opts: ['-a', '-h', '-l', '-p', '-t', '-v'] },
50
45
  'edit' => { alias: 'open' },
51
- 'publish' => { opts: ['-h'],
52
- desc: 'Push local changes to your public ' \
53
- 'server online.' },
54
- 'help' => { opts: ['-h'], desc: 'Alias for the -h switch.' },
46
+ 'build' => { opts: ['-f', '-h'] },
47
+ 'publish' => { opts: ['-h'] },
48
+ 'help' => { opts: ['-h'] },
55
49
  'basic' => { opts: ['-h', '-V'], label: '<command>' }
56
50
  }.freeze
57
51
 
@@ -75,10 +69,7 @@ module Neruda
75
69
  begin
76
70
  run_and_decorate_thread thread, message, frames
77
71
  rescue RuntimeError => e
78
- done = Rainbow('An error occured.').bold.red + "\n"
79
- done += Rainbow('To see it, run again your command with more ' \
80
- 'verbosity, i.e. pablo build -v').bold
81
- warn "#{message} #{done}"
72
+ throbber_error message
82
73
  raise e
83
74
  else
84
75
  done = Rainbow('done'.ljust(frames[0].length)).green
@@ -103,7 +94,7 @@ module Neruda
103
94
  long = "--#{opt[:long]}"
104
95
  return [short, long] if opt[:boolean]
105
96
  key = opt[:keyword] || opt[:long].upcase
106
- [short + key, long + ' ' + key]
97
+ [short + key, format('%<long>s %<key>s', long: long, key: key)]
107
98
  end
108
99
 
109
100
  # Returns the ~pablo~ help summary for a given command.
@@ -115,22 +106,31 @@ module Neruda
115
106
  Neruda::Utils::PABLO_COMMANDS[command][:opts].map do |k|
116
107
  short, long = Neruda::Utils.decorate_option(k)
117
108
  opt = Neruda::Utils::PABLO_OPTIONS[k]
118
- line = ' ' + [short, long].join(', ')
119
- line = line.ljust(34) + " #{opt[:desc]}" if opt.has_key?(:desc)
120
- line + "\n"
121
- end.join
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")
122
116
  end
123
117
 
124
118
  # Returns a formatted list of available commands for ~pablo~.
125
119
  #
126
120
  # @return [String]
127
121
  def list_commands
128
- lines = ''
122
+ lines = []
129
123
  Neruda::Utils::PABLO_COMMANDS.each do |cmd, opt|
130
124
  next if cmd == 'basic'
131
- lines += " #{cmd.ljust(10)} #{opt[:desc]}\n"
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
132
  end
133
- lines
133
+ lines.join("\n")
134
134
  end
135
135
 
136
136
  # Returns the real command name for a given command, which may be
@@ -148,16 +148,52 @@ module Neruda
148
148
  # Try to discover the current host operating system.
149
149
  #
150
150
  # @return [String] either apple, windows or linux (default)
151
+ # :nocov:
151
152
  def current_os
152
- if ENV['OS'] == 'Windows_NT' || RUBY_PLATFORM =~ /cygwin/
153
+ if ENV['OS'] == 'Windows_NT' || RUBY_PLATFORM.include?('cygwin')
153
154
  return 'windows'
154
155
  end
155
- return 'apple' if RUBY_PLATFORM =~ /darwin/
156
+ return 'apple' if RUBY_PLATFORM.include?('darwin')
156
157
  'linux'
157
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
158
183
 
159
184
  private
160
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
+
161
197
  def select_throbber_frames
162
198
  model = Neruda::Config.settings['throbber'] || 'default'
163
199
  model = 'default' unless Neruda::Utils::THROBBER_FRAMES.has_key?(model)