fronde 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/bin/fronde +15 -30
  3. data/lib/ext/nil_time.rb +25 -0
  4. data/lib/ext/r18n.rb +17 -0
  5. data/lib/ext/time.rb +49 -0
  6. data/lib/fronde/cli/commands.rb +92 -103
  7. data/lib/fronde/cli/data/Rakefile +8 -0
  8. data/lib/fronde/cli/data/config.yml +13 -0
  9. data/lib/fronde/cli/data/gitignore +7 -0
  10. data/lib/fronde/cli/data/zsh_completion +37 -0
  11. data/lib/fronde/cli/helpers.rb +55 -0
  12. data/lib/fronde/cli/opt_parse.rb +143 -0
  13. data/lib/fronde/cli/throbber.rb +99 -0
  14. data/lib/fronde/cli.rb +41 -42
  15. data/lib/fronde/config/data/org-config.el +24 -0
  16. data/lib/fronde/config/{ox-fronde.el → data/ox-fronde.el} +1 -1
  17. data/lib/fronde/config/helpers.rb +80 -0
  18. data/lib/fronde/config/lisp.rb +70 -0
  19. data/lib/fronde/config.rb +135 -99
  20. data/lib/fronde/emacs.rb +23 -20
  21. data/lib/fronde/index/atom_generator.rb +55 -66
  22. data/lib/fronde/index/data/all_tags.org +14 -0
  23. data/lib/fronde/index/data/template.org +22 -0
  24. data/lib/fronde/index/data/template.xml +37 -0
  25. data/lib/fronde/index/org_generator.rb +70 -88
  26. data/lib/fronde/index.rb +56 -82
  27. data/lib/fronde/org/file.rb +287 -0
  28. data/lib/fronde/org/file_extracter.rb +98 -0
  29. data/lib/fronde/org.rb +103 -0
  30. data/lib/fronde/preview.rb +43 -39
  31. data/lib/fronde/slug.rb +27 -0
  32. data/lib/fronde/source/gemini.rb +39 -0
  33. data/lib/fronde/source/html.rb +67 -0
  34. data/lib/fronde/source.rb +204 -0
  35. data/lib/fronde/templater.rb +94 -71
  36. data/lib/fronde/version.rb +1 -1
  37. data/lib/tasks/cli.rake +33 -0
  38. data/lib/tasks/org.rake +62 -42
  39. data/lib/tasks/site.rake +68 -30
  40. data/lib/tasks/sync.rake +41 -21
  41. data/lib/tasks/tags.rake +11 -7
  42. data/locales/en.yml +60 -14
  43. data/locales/fr.yml +68 -14
  44. metadata +53 -110
  45. data/lib/fronde/config/lisp_config.rb +0 -340
  46. data/lib/fronde/config/org-config.el +0 -19
  47. data/lib/fronde/org_file/class_methods.rb +0 -72
  48. data/lib/fronde/org_file/extracter.rb +0 -72
  49. data/lib/fronde/org_file/htmlizer.rb +0 -43
  50. data/lib/fronde/org_file.rb +0 -298
  51. data/lib/fronde/utils.rb +0 -229
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 59daab21a7ef37010f30971994ebda28af2c212528205e43c2dae18abe6c510f
4
- data.tar.gz: 89fda0a99813459bdbd2291c91aebe44d3a6c2fb3a6faf4742b7e7036191e5e8
3
+ metadata.gz: 31ed851cf895abccd33ec85ab91459e4310c9716631d096efd89d18fd16bf190
4
+ data.tar.gz: 901e11daea515cff4336f05a13a67604a5d73ca9fc020efb8250b34fbdb72450
5
5
  SHA512:
6
- metadata.gz: de60c2c6254acbe48846e3af209106aeb1f7058a604491e27bbeef1bf32b2c78d1d17e320d47168f086b046ad368b888a5b6933eddf56b7f4471c824c6acaa14
7
- data.tar.gz: 62f6c65db410960e4395bcbbff9bb1918886dfdb9a1c0b9c8f8871f61c285160c1a3edca901619b674b93bce80ba1cc45ce2de6ce74195c4c0f5a72292db1d70
6
+ metadata.gz: 1190105b49652d3bf177602a9ca37906f9a4659416f821734b17b5a49269825726019a6b69ad47b312937d75b362e658b93026003ffc42cd92859b601c9c8e96
7
+ data.tar.gz: 4e34d65345c82cc39237521c2e79365bbe4c23572fa4c4fa7d65e2d5aa7119d095a2956ec569e03c6cb459e7f1f37fe933aac3d2b0fdcefafb69f1cea8ef695b
data/bin/fronde CHANGED
@@ -1,45 +1,30 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'optparse'
5
- require 'r18n-core'
6
- require 'fronde/utils'
7
- require 'fronde/version'
8
- require 'fronde/cli'
9
-
10
- R18n.default_places = File.expand_path('../locales', __dir__)
11
- R18n.set Fronde::Config.get('lang')
4
+ require_relative '../lib/fronde/config'
5
+ require_relative '../lib/fronde/version'
6
+ require_relative '../lib/fronde/cli'
12
7
 
8
+ require 'optparse'
13
9
  optparser = OptionParser.new
14
10
  optparser.version = Fronde::VERSION
15
11
 
16
- Fronde::Utils::FRONDE_OPTIONS.each do |k, opt|
17
- optparser.send(opt[:meth] || :on, *Fronde::Utils.decorate_option(k))
12
+ Fronde::CLI::OptParse::FRONDE_OPTIONS.each do |k, opt|
13
+ optparser.send(opt[:method] || :on, *Fronde::CLI::OptParse.decorate_option(k))
18
14
  end
19
15
 
20
- params = {}
21
- optparser.parse!(into: params)
16
+ params = { verbose: false }
17
+ begin
18
+ optparser.parse!(into: params)
19
+ rescue OptionParser::InvalidArgument => e
20
+ warn e.message
21
+ params.merge!(help: true, recover_from_error: true)
22
+ end
22
23
 
23
24
  if params[:version]
24
25
  warn optparser.ver
25
26
  exit
26
27
  end
27
28
 
28
- if ARGV[0] == 'help'
29
- params[:help] = true
30
- ARGV.shift
31
- end
32
- fronde = Fronde::CLI.new(params)
33
- command = "fronde_#{ARGV[0]}".to_sym
34
- cmd_err = !fronde.respond_to?(command)
35
- if params[:help] || cmd_err
36
- cmd_err = false if params[:help] && !ARGV[0]
37
- fronde.fronde_help(ARGV[0], error: cmd_err)
38
- end
39
- ARGV.shift
40
-
41
- init_cmds = [:fronde_init, :fronde_config, :fronde_update]
42
- unless File.exist?('config.yml') || init_cmds.include?(command)
43
- fronde.fronde_init
44
- end
45
- fronde.send command
29
+ fronde = Fronde::CLI::App.new(params)
30
+ exit fronde.run(ARGV)
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A time emulator to handle cases where no time is available
4
+ class NilTime
5
+ def strftime(*)
6
+ ''
7
+ end
8
+
9
+ def xmlschema(_ = 0)
10
+ ''
11
+ end
12
+
13
+ def l18n_short_date_string
14
+ ''
15
+ end
16
+
17
+ def l18n_long_date_string(*)
18
+ ''
19
+ end
20
+
21
+ def l18n_short_date_html
22
+ '<time></time>'
23
+ end
24
+ alias_method :l18n_long_date_html, :l18n_long_date_string
25
+ end
data/lib/ext/r18n.rb ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Monkey patch to add a little helper
4
+ module R18nPatch
5
+ refine R18n::Translation do
6
+ def full_datetime_format
7
+ date_fmt = fronde.index.full_date_format(
8
+ date: @locale.full_format
9
+ )
10
+ date_fmt = @locale.year_format.sub('_', date_fmt)
11
+ time_fmt = @locale.time_format.delete('_').strip
12
+ fronde.index.full_date_with_time_format(
13
+ date: date_fmt, time: time_fmt
14
+ )
15
+ end
16
+ end
17
+ end
data/lib/ext/time.rb ADDED
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Monkey patch to add some helpers
4
+ module TimePatch
5
+ refine Time do
6
+ # Returns the current Time instance as a localized short string.
7
+ #
8
+ # @return [String] the localized Time string representation
9
+ def l18n_short_date_string
10
+ R18n.l to_date
11
+ end
12
+
13
+ # Format the current Time as a HTML `time` tag showing a short date.
14
+ #
15
+ # @return [String] the HTML `time` tag
16
+ def l18n_short_date_html
17
+ "<time datetime=\"#{xmlschema}\">#{l18n_short_date_string}</time>"
18
+ end
19
+
20
+ def no_time=(value)
21
+ @no_time = value
22
+ end
23
+
24
+ # Returns the current Time instance as a localized long string.
25
+ #
26
+ # @param with_year [Boolean] wether or not the string must contain the
27
+ # year
28
+ # @return [String] the localized Time string representation
29
+ def l18n_long_date_string(with_year: true)
30
+ locale = R18n.get.locale
31
+ long_fmt = R18n.t.fronde.index.full_date_format(
32
+ date: locale.format_date_full(self, year: with_year)
33
+ )
34
+ unless @no_time
35
+ long_fmt = R18n.t.fronde.index.full_date_with_time_format(
36
+ date: long_fmt, time: locale.time_format.delete('_').strip
37
+ )
38
+ end
39
+ locale.strftime(self, long_fmt)
40
+ end
41
+
42
+ # Format the current Time as a HTML `time` tag showing a long date.
43
+ #
44
+ # @return [String] the HTML `time` tag
45
+ def l18n_long_date_html
46
+ "<time datetime=\"#{xmlschema}\">#{l18n_long_date_string}</time>"
47
+ end
48
+ end
49
+ end
@@ -1,125 +1,114 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'helpers'
4
+ require_relative 'opt_parse'
5
+ require_relative '../slug'
6
+ require_relative '../org/file'
7
+
3
8
  module Fronde
4
- # Fronde commands
5
- module CLICommands
6
- def fronde_update
7
- update_config
8
- @rake.options.build_all = true
9
- @rake.invoke_task('org:upgrade')
10
- end
11
- alias_method :fronde_config, :fronde_update
9
+ module CLI
10
+ # Fronde commands
11
+ module Commands
12
+ def fronde_new
13
+ new_dir = @argv.first || 'my_fronde_website'
14
+ FileUtils.mkdir new_dir
15
+ Dir.chdir new_dir
16
+ Helpers.init_config_file @options
17
+ Fronde::CONFIG.reset # Correctly compute various path
18
+ Helpers.init_rakefile
19
+ init_rake
20
+ @rake['org:install'].invoke
21
+ @argv = ['src/index.org']
22
+ fronde_open
23
+ end
12
24
 
13
- def fronde_init
14
- update_config
15
- @rake.options.build_all = true
16
- @rake.invoke_task('org:install')
17
- return if File.exist? 'src/index.org'
18
- Fronde::OrgFile.new('src/index.org', @options).write
19
- fronde_open 'src/index.org'
20
- end
25
+ def fronde_update
26
+ Helpers.init_rakefile
27
+ init_rake
28
+ @rake.options.build_all = true
29
+ @rake['org:upgrade'].invoke
30
+ 0
31
+ end
21
32
 
22
- def fronde_build
23
- @rake.options.build_all = true
24
- task = 'site:build'
25
- task = "#{task}[true]" if @options[:force]
26
- @rake.invoke_task task
27
- end
33
+ def fronde_build
34
+ @rake.options.build_all = true
35
+ @rake['site:build'].invoke @options[:force]
36
+ 0
37
+ end
28
38
 
29
- def fronde_preview
30
- Thread.new do
31
- sleep 1
32
- port = Fronde::Config.get(['preview', 'server_port'], 5000)
33
- uri = "http://127.0.0.1:#{port}/"
34
- current_os = Fronde::Utils.current_os
35
- case current_os
36
- when 'windows'
37
- system 'start', uri
38
- when 'apple'
39
- system 'open', uri
40
- else
41
- system 'gio', 'open', uri
39
+ def fronde_preview
40
+ Thread.new do
41
+ sleep 1
42
+ port = Fronde::CONFIG.get(%w[preview server_port], 5000)
43
+ Helpers.launch_app_for_uri "http://127.0.0.1:#{port}/"
42
44
  end
45
+ @rake['site:preview'].invoke
46
+ 0
43
47
  end
44
- @rake.invoke_task('site:preview')
45
- end
46
48
 
47
- def fronde_open(file_path = ARGV[0])
48
- editor = ENV['EDITOR'] || ENV['VISUAL'] || 'emacs'
49
- cmd = [editor]
50
- if file_path.nil? || !File.file?(file_path)
51
- # file_path may be updated with title given in options
52
- file_path = create_new_file(file_path)
53
- # Only move to the end of file for new file. Let the editor handle
54
- # the best position for already existing files
55
- cmd << '+6'
49
+ def fronde_open
50
+ editor = ENV['EDITOR'] || ENV['VISUAL'] || 'emacs'
51
+ cmd = [editor]
52
+ file_path = @argv.first || Dir.pwd
53
+ unless File.file?(file_path)
54
+ # file_path may be updated with title given in options
55
+ file_path = create_new_file(file_path)
56
+ # Only move to the end of file for new file. Let the editor handle
57
+ # the best position for already existing files
58
+ cmd << '+6'
59
+ end
60
+ cmd << file_path
61
+ (system(*cmd) && 0) || 1
56
62
  end
57
- cmd << file_path
58
- system(*cmd)
59
- end
60
- alias_method :fronde_edit, :fronde_open
61
63
 
62
- def fronde_publish
63
- @rake.invoke_task('sync:push')
64
- end
64
+ def fronde_publish
65
+ @rake['sync:push'].invoke
66
+ 0
67
+ end
65
68
 
66
- def fronde_help(command = 'basic', error: false)
67
- warn R18n.t.fronde.bin.error.no_command if error
68
- cmd_opt = Fronde::Utils.command_options(command)
69
- label = cmd_opt[:label] || command
70
- warn format("%<label>s\n\n", label: R18n.t.fronde.bin.usage(label))
71
- cmd = cmd_opt[:name] || command
72
- if R18n.t.fronde.bin.commands[cmd].translated?
73
- warn format("%<label>s\n\n", label: R18n.t.fronde.bin.commands[cmd])
69
+ def fronde_help
70
+ # Try to find command in next argv, otherwise fallback again.
71
+ @command = @argv.shift || 'basic' if @command == 'help'
72
+ cmd_opt = OptParse.command_options(@command)
73
+ label = cmd_opt[:label] || @command
74
+ warn format("%<label>s\n\n", label: R18n.t.fronde.bin.usage(label))
75
+ cmd = cmd_opt[:name] || @command
76
+ if R18n.t.fronde.bin.commands[cmd].translated?
77
+ warn format("%<label>s\n\n", label: R18n.t.fronde.bin.commands[cmd])
78
+ end
79
+ body = OptParse.help_command_body(cmd)
80
+ warn body unless body == ''
81
+ 0
74
82
  end
75
- warn help_command_body(cmd).join("\n")
76
- exit 1 if error
77
- exit
78
- end
79
83
 
80
- private
84
+ private
81
85
 
82
- def update_config
83
- cnf = @options.merge
84
- cnf.delete(:verbose)
85
- cnf.transform_keys!(&:to_s)
86
- Fronde::Config.save(Fronde::Config.settings.merge(cnf))
87
- end
86
+ def file_name_from_title
87
+ title = @options[:title] || R18n.t.fronde.bin.options.default_title
88
+ # No title, nor a reliable file_path? Better abort
89
+ raise R18n.t.fronde.error.bin.no_file if title == ''
88
90
 
89
- def new_file_name(file_path)
90
- file_path = File.expand_path(file_path || '')
91
- return file_path if file_path[-4..] == '.org'
92
- # file_path seems to be a dir path. Thus we have to create the new
93
- # filename from its title
94
- title = @options[:title]
95
- # No title, nor a reliable file_path? Better abort
96
- return nil if title.nil? || title == ''
97
- filename = "#{Fronde::OrgFile.slug(title)}.org"
98
- File.join file_path, filename
99
- end
91
+ "#{Fronde::Slug.slug(title)}.org"
92
+ end
100
93
 
101
- def create_new_file(file_path)
102
- filename = new_file_name(file_path)
103
- if filename.nil?
104
- warn R18n.t.fronde.bin.error.no_file
105
- exit 1
94
+ def new_file_name(file_path)
95
+ file_path = File.expand_path(file_path)
96
+
97
+ if file_path[-4..] == '.org' && !File.directory?(file_path)
98
+ return file_path
99
+ end
100
+
101
+ # file_path seems to be a dir path. Thus we have to create the new
102
+ # filename from its title
103
+ File.join file_path, file_name_from_title
106
104
  end
107
- FileUtils.mkdir_p File.dirname(filename)
108
- Fronde::OrgFile.new(filename, @options).write
109
- filename
110
- end
111
105
 
112
- def help_command_body(command)
113
- body = [
114
- R18n.t.fronde.bin.options.cmd_title,
115
- Fronde::Utils.summarize_command(command)
116
- ]
117
- return body unless command == 'basic'
118
- body + [
119
- '',
120
- R18n.t.fronde.bin.commands.cmd_title,
121
- Fronde::Utils.list_commands
122
- ]
106
+ def create_new_file(file_path)
107
+ filename = new_file_name(file_path)
108
+ FileUtils.mkdir_p File.dirname(filename)
109
+ Fronde::Org::File.new(filename, @options).write
110
+ filename
111
+ end
123
112
  end
124
113
  end
125
114
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fronde/config'
4
+
5
+ fronde_spec = Gem::Specification.find_by_name 'fronde'
6
+ Dir.glob("#{fronde_spec.gem_dir}/lib/tasks/*.rake").each { |r| import r }
7
+
8
+ task default: 'site:build'
@@ -0,0 +1,13 @@
1
+ ---
2
+ {%- if author %}
3
+ author: {{ author }}
4
+ {%- endif %}
5
+ {%- if lang %}
6
+ lang: {{ lang }}
7
+ {%- endif %}
8
+ sources:
9
+ - path: src
10
+ target: .
11
+ {%- if output == 'gemini' %}
12
+ type: gemini
13
+ {%- endif %}
@@ -0,0 +1,7 @@
1
+ .dir-locals.el
2
+ .ruby-version
3
+ Rakefile
4
+ lib/
5
+ public_gmi/
6
+ public_html/
7
+ var/
@@ -0,0 +1,37 @@
1
+ #compdef fronde
2
+ #autoload
3
+
4
+ {% for command in commands %}
5
+ {%- for option in command.options %}
6
+ {%- if forloop.first %}
7
+ (( $+functions[__fronde_{{ command.name }}] )) ||
8
+ __fronde_{{ command.name }}(){
9
+ _arguments \
10
+ {%- endif %}
11
+ '({{ option.short }} {{ option.long }})'{{ '{' }}{{ option.short}},{{ option.long }}}
12
+ {%- if option.keyword %}':{{ option.keyword }}:'{% endif %}
13
+ {%- if forloop.last %}
14
+ {%- if command.name == 'open' %} \
15
+ '1:file:_files -g \*.org'
16
+ {%- endif %}
17
+ }
18
+ {% else %} \{% endif %}
19
+ {%- endfor %}{% endfor %}
20
+
21
+ (( $+functions[__fronde_help] )) ||
22
+ __fronde_help(){
23
+ _arguments \
24
+ "1:command:(({% for command in commands %}{{ command.name }}\:'{{ command.translation }}' {% endfor %}))"
25
+ }
26
+
27
+ local state
28
+
29
+ _arguments -C \
30
+ '(-)-h[help]' \
31
+ '(-)-V[version]' \
32
+ "1:command:(({% for command in commands %}{{ command.name }}\:'{{ command.translation }}' {% endfor %}))" \
33
+ '*::arg:->args'
34
+
35
+ if [ "$state" = args ]; then
36
+ _call_function ret __fronde_${words[1]}
37
+ fi
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+ require 'net/http'
5
+ require 'fileutils'
6
+
7
+ module Fronde
8
+ module CLI
9
+ # Various utilitaries methods
10
+ module Helpers
11
+ def self.init_config_file(config)
12
+ return if File.exist? 'config.yml'
13
+
14
+ output = config[:output] || 'html'
15
+ output = 'gemini' if output == 'gmi'
16
+ data = { 'author' => config[:author],
17
+ 'lang' => config[:lang],
18
+ 'output' => output }
19
+ source = File.expand_path './data/config.yml', __dir__
20
+ template = Liquid::Template.parse(File.read(source))
21
+ File.write('config.yml', template.render(data))
22
+ end
23
+
24
+ def self.init_rakefile
25
+ FileUtils.cp(
26
+ File.expand_path('./data/Rakefile', __dir__),
27
+ 'Rakefile'
28
+ )
29
+ end
30
+
31
+ def self.launch_app_for_uri(uri)
32
+ case current_os
33
+ when 'windows'
34
+ system 'start', uri
35
+ when 'apple'
36
+ system 'open', uri
37
+ else
38
+ system 'gio', 'open', uri
39
+ end
40
+ end
41
+
42
+ # Try to discover the current host operating system.
43
+ #
44
+ # @return [String] either apple, windows or linux (default)
45
+ def self.current_os
46
+ if ENV['OS'] == 'Windows_NT' || RUBY_PLATFORM.include?('cygwin')
47
+ return 'windows'
48
+ end
49
+ return 'apple' if RUBY_PLATFORM.include?('darwin')
50
+
51
+ 'linux'
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fronde
4
+ module CLI
5
+ # Helper code to help build the fronde option parser
6
+ module OptParse
7
+ # @return [Hash] the possible ~fronde~ options and their
8
+ # configuration
9
+ FRONDE_OPTIONS = {
10
+ '-a' => { long: 'author' },
11
+ '-f' => { long: 'force', boolean: true },
12
+ '-h' => { long: 'help', boolean: true, method: :on_tail,
13
+ help: R18n.t.fronde.bin.options.help },
14
+ '-l' => { long: 'lang', keyword: 'LOCALE' },
15
+ '-o' => { long: 'output', keyword: 'FORMAT', choices: %w[gemini html] },
16
+ '-t' => { long: 'title' },
17
+ '-v' => { long: 'verbose', boolean: true, method: :on_tail },
18
+ '-V' => { long: 'version', boolean: true, method: :on_tail,
19
+ help: R18n.t.fronde.bin.options.version }
20
+ }.freeze
21
+
22
+ # TODO: jekyll new [path] / jekyll build / jekyll clean / jekyll serve
23
+ # TODO: hugo new site [path] / hugo / hugo new content / hugo server
24
+ # TODO: zola init [path] / zola build --root path_to_project / zola serve
25
+
26
+ # @return [Hash] the possible ~fronde~ subcommands and their
27
+ # configuration
28
+ FRONDE_COMMANDS = {
29
+ 'new' => { opts: ['-a', '-l', '-o', '-t', '-v'], label: 'new <path>' },
30
+ 'init' => { alias: 'new' },
31
+ 'update' => {},
32
+ 'config' => { alias: 'update' },
33
+ 'preview' => {},
34
+ 'open' => { opts: ['-a', '-l', '-t', '-v'], label: 'open <path>' },
35
+ 'edit' => { alias: 'open' },
36
+ 'build' => { opts: ['-f'] },
37
+ 'publish' => {},
38
+ 'help' => {},
39
+ 'basic' => { opts: ['-h', '-V'], label: '<command>' }
40
+ }.freeze
41
+
42
+ class << self
43
+ # Returns the short and long options specification for a given
44
+ # short option.
45
+ #
46
+ # This method use the {Fronde::CLI::OptParse::FRONDE_OPTIONS}
47
+ # Hash to retrieve corresponding values.
48
+ #
49
+ # @example
50
+ # spec = Fronde::CLI::OptParse.decorate_option('-a')
51
+ # => ['-a AUTHOR', '--author AUTHOR']
52
+ #
53
+ # @param short [String] the short option to decorate
54
+ # @return [Array] the short and long specification for an option
55
+ def decorate_option(short)
56
+ opt = FRONDE_OPTIONS[short]
57
+ long = "--#{opt[:long]}"
58
+ if opt[:boolean]
59
+ config = [short, long]
60
+ else
61
+ key = opt[:keyword] || opt[:long].upcase
62
+ config = [short, format('%<long>s %<key>s', long: long, key: key)]
63
+ end
64
+ config << opt[:choices] if opt[:choices]
65
+ config << opt[:help] if opt[:help]
66
+ config
67
+ end
68
+
69
+ # Returns the ~fronde~ help summary for a given command.
70
+ #
71
+ # @param command [String] the command for which a summary
72
+ # should be given
73
+ # @return [String]
74
+ def summarize_command(command)
75
+ (FRONDE_COMMANDS[command][:opts] || []).map do |k|
76
+ short, long = decorate_option(k)
77
+ opt = FRONDE_OPTIONS[k]
78
+ label = [short, long].join(', ')
79
+ line = [format(' %<opt>s', opt: label).ljust(30)]
80
+ help = opt[:help]
81
+ line << help if help
82
+ choices = opt[:choices]
83
+ line << "(#{choices.join(', ')})" if choices
84
+ line.join(' ')
85
+ end.join("\n")
86
+ end
87
+
88
+ def help_command_body(command)
89
+ command_opts_doc = summarize_command(command)
90
+ return '' if command_opts_doc == ''
91
+
92
+ body = [R18n.t.fronde.bin.options.cmd_title, command_opts_doc]
93
+ if command == 'basic'
94
+ body += ['', R18n.t.fronde.bin.commands.cmd_title, list_commands]
95
+ end
96
+ body.join("\n")
97
+ end
98
+
99
+ # Returns a formatted list of available commands for ~fronde~.
100
+ #
101
+ # @return [String]
102
+ def list_commands
103
+ FRONDE_COMMANDS.filter_map do |cmd, opt|
104
+ next if cmd == 'basic'
105
+
106
+ line = [' ', cmd.ljust(10)]
107
+ if opt.has_key? :alias
108
+ line << R18n.t.fronde.bin.commands.alias(opt[:alias])
109
+ else
110
+ line << R18n.t.fronde.bin.commands[cmd]
111
+ end
112
+ line.join(' ')
113
+ end.join("\n")
114
+ end
115
+
116
+ # Returns the real command name for a given command, which may be
117
+ # an alias.
118
+ #
119
+ # @param command [String] the command to resolve
120
+ # @return [String]
121
+ def resolve_possible_alias(command)
122
+ return 'basic' unless FRONDE_COMMANDS.include?(command)
123
+
124
+ cmd_opt = FRONDE_COMMANDS[command]
125
+ return cmd_opt[:alias] if cmd_opt.has_key?(:alias)
126
+
127
+ command
128
+ end
129
+
130
+ # Returns the given command options.
131
+ #
132
+ # This method will first try to resolve command alias, if any.
133
+ #
134
+ # @param command [String] the command, which options should be returned
135
+ # @return [Hash] the command options
136
+ def command_options(command)
137
+ cmd = resolve_possible_alias command
138
+ FRONDE_COMMANDS[cmd].merge(name: cmd)
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end