neruda 0.1.0 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/pablo +71 -33
- data/lib/neruda/config.rb +59 -16
- data/lib/neruda/config/lisp_config.rb +140 -79
- data/lib/neruda/config/org-config.el +6 -6
- data/lib/neruda/config/ox-neruda.el +28 -2
- data/lib/neruda/emacs.rb +44 -0
- data/lib/neruda/index.rb +50 -36
- data/lib/neruda/index/atom_generator.rb +16 -16
- data/lib/neruda/index/org_generator.rb +63 -41
- data/lib/neruda/org_file.rb +47 -14
- data/lib/neruda/org_file/class_methods.rb +38 -21
- data/lib/neruda/org_file/extracter.rb +12 -1
- data/lib/neruda/org_file/htmlizer.rb +6 -32
- data/lib/neruda/preview.rb +9 -7
- data/lib/neruda/templater.rb +3 -2
- data/lib/neruda/utils.rb +120 -35
- data/lib/neruda/version.rb +2 -1
- data/lib/tasks/org.rake +48 -26
- data/lib/tasks/site.rake +36 -33
- data/lib/tasks/sync.rake +6 -2
- data/lib/tasks/tags.rake +19 -0
- data/locales/en.yml +20 -1
- data/locales/fr.yml +20 -1
- metadata +57 -30
- data/themes/default/css/style.css +0 -216
- data/themes/default/fonts/Yanone_Kaffeesatz_400.woff +0 -0
- data/themes/default/fonts/Yanone_Kaffeesatz_400.woff2 +0 -0
data/lib/neruda/org_file.rb
CHANGED
@@ -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
|
65
|
-
|
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
|
100
|
-
# @param opts [Hash] optional data to initialize new
|
101
|
-
# @option opts [String] title ('') the title of the new
|
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 =
|
112
|
-
@url =
|
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
|
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
|
-
@lang = Neruda::Config.settings['lang']
|
286
|
+
@lang = @options[:lang] || Neruda::Config.settings['lang']
|
256
287
|
@excerpt = ''
|
257
|
-
|
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
|
7
|
-
|
8
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
40
|
+
"#{pubfolder}/#{target}"
|
23
41
|
end
|
24
42
|
|
25
|
-
def
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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.
|
53
|
+
title.downcase.tr(' ', '-')
|
37
54
|
.encode('ascii', fallback: ->(k) { translit(k) })
|
38
|
-
.gsub(/[^\w-]/, '').
|
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
|
-
|
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,22 +1,19 @@
|
|
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
|
10
|
-
# {Neruda::OrgFile#file @file} is ~nil~.
|
10
|
+
# Publish the current file
|
11
11
|
#
|
12
12
|
# @return [Boolean, nil] the underlying ~system~ method return value
|
13
13
|
def publish
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
emacs_args = ['-f org-publish-current-file']
|
18
|
-
end
|
19
|
-
call_emacs emacs_args
|
14
|
+
Neruda::Emacs.new(
|
15
|
+
file_path: @file, verbose: @options[:verbose]
|
16
|
+
).publish
|
20
17
|
end
|
21
18
|
|
22
19
|
private
|
@@ -40,7 +37,7 @@ module Neruda
|
|
40
37
|
#
|
41
38
|
# @return [String] the HTML `time` tag
|
42
39
|
def date_to_html(dateformat = :full)
|
43
|
-
return '' if @date.nil?
|
40
|
+
return '<time></time>' if @date.nil?
|
44
41
|
"<time datetime=\"#{@date.rfc3339}\">#{datestring(dateformat)}</time>"
|
45
42
|
end
|
46
43
|
|
@@ -49,30 +46,7 @@ module Neruda
|
|
49
46
|
#
|
50
47
|
# @return [String] the author HTML `span`
|
51
48
|
def author_to_html
|
52
|
-
return '' if @author == ''
|
53
49
|
"<span class=\"author\">#{@author}</span>"
|
54
50
|
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)
|
74
|
-
end
|
75
|
-
system command, out: '/dev/null', err: '/dev/null'
|
76
|
-
end
|
77
51
|
end
|
78
52
|
end
|
data/lib/neruda/preview.rb
CHANGED
@@ -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
|
23
|
-
return routes[requested_path] if routes.
|
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 =
|
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:\/\//, '"'
|
38
|
-
.gsub(/"#{domain}/, '"'
|
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
|
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 }) }
|
data/lib/neruda/templater.rb
CHANGED
@@ -99,9 +99,10 @@ module Neruda
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def insert_new_node_at(elem, content)
|
102
|
-
|
102
|
+
case @position
|
103
|
+
when 'before'
|
103
104
|
elem.add_previous_sibling content
|
104
|
-
|
105
|
+
when 'replace'
|
105
106
|
elem.replace content
|
106
107
|
else
|
107
108
|
elem.add_next_sibling content
|
data/lib/neruda/utils.rb
CHANGED
@@ -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,30 +26,27 @@ module Neruda
|
|
23
26
|
# configuration
|
24
27
|
PABLO_OPTIONS = {
|
25
28
|
'-a' => { long: 'author' },
|
29
|
+
'-d' => { long: 'directory', boolean: true },
|
30
|
+
'-f' => { long: 'force', boolean: true },
|
31
|
+
'-h' => { long: 'help', boolean: true, meth: :on_tail },
|
26
32
|
'-l' => { long: 'lang', keyword: 'LOCALE' },
|
33
|
+
'-p' => { long: 'path' },
|
27
34
|
'-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
35
|
'-v' => { long: 'verbose', boolean: true, meth: :on_tail },
|
32
|
-
'-
|
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' }
|
36
|
+
'-V' => { long: 'version', boolean: true, meth: :on_tail }
|
36
37
|
}.freeze
|
37
38
|
|
38
39
|
# @return [Hash] the possible ~pablo~ subcommands and their
|
39
40
|
# configuration
|
40
41
|
PABLO_COMMANDS = {
|
41
|
-
'init' => { opts: ['-a', '-
|
42
|
-
|
43
|
-
|
44
|
-
'
|
45
|
-
|
46
|
-
|
47
|
-
'
|
48
|
-
|
49
|
-
'help' => { opts: ['-h'], desc: 'Alias for the -h switch.' },
|
42
|
+
'init' => { opts: ['-a', '-h', '-l', '-t', '-v'] },
|
43
|
+
'config' => { alias: 'init' },
|
44
|
+
'preview' => { opts: ['-h'] },
|
45
|
+
'open' => { opts: ['-a', '-d', '-h', '-l', '-p', '-t', '-v'] },
|
46
|
+
'edit' => { alias: 'open' },
|
47
|
+
'build' => { opts: ['-f', '-h'] },
|
48
|
+
'publish' => { opts: ['-h'] },
|
49
|
+
'help' => { opts: ['-h'] },
|
50
50
|
'basic' => { opts: ['-h', '-V'], label: '<command>' }
|
51
51
|
}.freeze
|
52
52
|
|
@@ -66,17 +66,16 @@ module Neruda
|
|
66
66
|
# @param message [String] the message to display before the throbber
|
67
67
|
# @return [void]
|
68
68
|
def throbber(thread, message)
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
69
|
+
frames = select_throbber_frames
|
70
|
+
begin
|
71
|
+
run_and_decorate_thread thread, message, frames
|
72
|
+
rescue RuntimeError => e
|
73
|
+
throbber_error message
|
74
|
+
raise e
|
75
|
+
else
|
76
|
+
done = Rainbow('done'.ljust(frames[0].length)).green
|
77
|
+
puts "#{message} #{done}"
|
77
78
|
end
|
78
|
-
done = Rainbow('done'.ljust(frames[0].length)).green
|
79
|
-
puts "#{message} #{done}"
|
80
79
|
end
|
81
80
|
|
82
81
|
# Returns the short and long options specification for a given
|
@@ -95,8 +94,8 @@ module Neruda
|
|
95
94
|
opt = Neruda::Utils::PABLO_OPTIONS[short]
|
96
95
|
long = "--#{opt[:long]}"
|
97
96
|
return [short, long] if opt[:boolean]
|
98
|
-
key =
|
99
|
-
[short + key, long
|
97
|
+
key = opt[:keyword] || opt[:long].upcase
|
98
|
+
[short + key, format('%<long>s %<key>s', long: long, key: key)]
|
100
99
|
end
|
101
100
|
|
102
101
|
# Returns the ~pablo~ help summary for a given command.
|
@@ -108,22 +107,108 @@ module Neruda
|
|
108
107
|
Neruda::Utils::PABLO_COMMANDS[command][:opts].map do |k|
|
109
108
|
short, long = Neruda::Utils.decorate_option(k)
|
110
109
|
opt = Neruda::Utils::PABLO_OPTIONS[k]
|
111
|
-
|
112
|
-
line =
|
113
|
-
|
114
|
-
|
110
|
+
label = [short, long].join(', ')
|
111
|
+
line = [format(' %<opt>s', opt: label).ljust(30)]
|
112
|
+
if R18n.t.pablo.options[opt[:long]].translated?
|
113
|
+
line << R18n.t.pablo.options[opt[:long]]
|
114
|
+
end
|
115
|
+
line.join(' ')
|
116
|
+
end.join("\n")
|
115
117
|
end
|
116
118
|
|
117
119
|
# Returns a formatted list of available commands for ~pablo~.
|
118
120
|
#
|
119
121
|
# @return [String]
|
120
122
|
def list_commands
|
121
|
-
lines =
|
123
|
+
lines = []
|
122
124
|
Neruda::Utils::PABLO_COMMANDS.each do |cmd, opt|
|
123
125
|
next if cmd == 'basic'
|
124
|
-
|
126
|
+
line = [' ', cmd.ljust(10)]
|
127
|
+
if opt.has_key? :alias
|
128
|
+
line << R18n.t.pablo.commands.alias(opt[:alias])
|
129
|
+
else
|
130
|
+
line << R18n.t.pablo.commands[cmd]
|
131
|
+
end
|
132
|
+
lines << line.join(' ')
|
133
|
+
end
|
134
|
+
lines.join("\n")
|
135
|
+
end
|
136
|
+
|
137
|
+
# Returns the real command name for a given command, which may be
|
138
|
+
# an alias.
|
139
|
+
#
|
140
|
+
# @param command [String] the command to resolve
|
141
|
+
# @return [String]
|
142
|
+
def resolve_possible_alias(command)
|
143
|
+
return 'basic' unless Neruda::Utils::PABLO_COMMANDS.include?(command)
|
144
|
+
cmd_opt = Neruda::Utils::PABLO_COMMANDS[command]
|
145
|
+
return cmd_opt[:alias] if cmd_opt.has_key?(:alias)
|
146
|
+
command
|
147
|
+
end
|
148
|
+
|
149
|
+
# Try to discover the current host operating system.
|
150
|
+
#
|
151
|
+
# @return [String] either apple, windows or linux (default)
|
152
|
+
# :nocov:
|
153
|
+
def current_os
|
154
|
+
if ENV['OS'] == 'Windows_NT' || RUBY_PLATFORM.include?('cygwin')
|
155
|
+
return 'windows'
|
156
|
+
end
|
157
|
+
return 'apple' if RUBY_PLATFORM.include?('darwin')
|
158
|
+
'linux'
|
159
|
+
end
|
160
|
+
# :nocov:
|
161
|
+
|
162
|
+
# Download latest org-mode tarball.
|
163
|
+
#
|
164
|
+
# @return [String] the downloaded org-mode version
|
165
|
+
def download_org
|
166
|
+
# :nocov:
|
167
|
+
return if Neruda::Config.org_last_version.nil?
|
168
|
+
# :nocov:
|
169
|
+
tarball = "org-#{Neruda::Config.org_last_version}.tar.gz"
|
170
|
+
# Remove version number in dest file to allow easy rake file
|
171
|
+
# task naming
|
172
|
+
dest_file = 'tmp/org.tar.gz'
|
173
|
+
return if File.exist?(dest_file)
|
174
|
+
uri = URI("https://orgmode.org/#{tarball}")
|
175
|
+
# Will crash on purpose if anything goes wrong
|
176
|
+
Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
|
177
|
+
http.request(Net::HTTP::Get.new(uri)) do |response|
|
178
|
+
File.open(dest_file, 'w') do |io|
|
179
|
+
response.read_body { |chunk| io.write chunk }
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
private
|
186
|
+
|
187
|
+
def throbber_error(message)
|
188
|
+
warn(
|
189
|
+
format(
|
190
|
+
"%<message>s %<label>s\n%<explanation>s",
|
191
|
+
message: message,
|
192
|
+
label: Rainbow(R18n.t.neruda.error.label).bold.red,
|
193
|
+
explanation: Rainbow(R18n.t.neruda.error.explanation).bold
|
194
|
+
)
|
195
|
+
)
|
196
|
+
end
|
197
|
+
|
198
|
+
def select_throbber_frames
|
199
|
+
model = Neruda::Config.settings['throbber'] || 'default'
|
200
|
+
model = 'default' unless Neruda::Utils::THROBBER_FRAMES.has_key?(model)
|
201
|
+
Neruda::Utils::THROBBER_FRAMES[model]
|
202
|
+
end
|
203
|
+
|
204
|
+
def run_and_decorate_thread(thread, message, frames)
|
205
|
+
thread.abort_on_exception = true
|
206
|
+
current = 0
|
207
|
+
while thread.alive?
|
208
|
+
sleep 0.1
|
209
|
+
print "#{message} #{frames[current % frames.length]}\r"
|
210
|
+
current += 1
|
125
211
|
end
|
126
|
-
lines
|
127
212
|
end
|
128
213
|
end
|
129
214
|
end
|