fronde 0.3.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) 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 +37 -0
  5. data/lib/ext/time.rb +39 -0
  6. data/lib/ext/time_no_time.rb +23 -0
  7. data/lib/fronde/cli/commands.rb +97 -104
  8. data/lib/fronde/cli/data/Rakefile +8 -0
  9. data/lib/fronde/cli/data/config.yml +13 -0
  10. data/lib/fronde/cli/data/gitignore +6 -0
  11. data/lib/fronde/cli/data/zsh_completion +37 -0
  12. data/lib/fronde/cli/helpers.rb +55 -0
  13. data/lib/fronde/cli/opt_parse.rb +140 -0
  14. data/lib/fronde/cli/throbber.rb +110 -0
  15. data/lib/fronde/cli.rb +42 -42
  16. data/lib/fronde/config/data/org-config.el +25 -0
  17. data/lib/fronde/config/data/ox-fronde.el +158 -0
  18. data/lib/fronde/config/data/themes/umaneti/css/htmlize.css +364 -0
  19. data/lib/fronde/config/data/themes/umaneti/css/style.css +250 -0
  20. data/lib/fronde/config/data/themes/umaneti/img/bottom.png +0 -0
  21. data/lib/fronde/config/data/themes/umaneti/img/content.png +0 -0
  22. data/lib/fronde/config/data/themes/umaneti/img/tic.png +0 -0
  23. data/lib/fronde/config/data/themes/umaneti/img/top.png +0 -0
  24. data/lib/fronde/config/helpers.rb +62 -0
  25. data/lib/fronde/config/lisp.rb +80 -0
  26. data/lib/fronde/config.rb +148 -98
  27. data/lib/fronde/emacs.rb +23 -20
  28. data/lib/fronde/index/atom_generator.rb +55 -66
  29. data/lib/fronde/index/data/all_tags.org +19 -0
  30. data/lib/fronde/index/data/template.org +26 -0
  31. data/lib/fronde/index/data/template.xml +37 -0
  32. data/lib/fronde/index/org_generator.rb +72 -88
  33. data/lib/fronde/index.rb +57 -86
  34. data/lib/fronde/org/file.rb +299 -0
  35. data/lib/fronde/org/file_extracter.rb +101 -0
  36. data/lib/fronde/org.rb +105 -0
  37. data/lib/fronde/preview.rb +43 -39
  38. data/lib/fronde/slug.rb +54 -0
  39. data/lib/fronde/source/gemini.rb +34 -0
  40. data/lib/fronde/source/html.rb +67 -0
  41. data/lib/fronde/source.rb +209 -0
  42. data/lib/fronde/sync/neocities.rb +220 -0
  43. data/lib/fronde/sync/rsync.rb +46 -0
  44. data/lib/fronde/sync.rb +32 -0
  45. data/lib/fronde/templater.rb +101 -71
  46. data/lib/fronde/version.rb +1 -1
  47. data/lib/tasks/cli.rake +33 -0
  48. data/lib/tasks/org.rake +58 -43
  49. data/lib/tasks/site.rake +66 -31
  50. data/lib/tasks/sync.rake +37 -40
  51. data/lib/tasks/tags.rake +11 -7
  52. data/locales/en.yml +61 -14
  53. data/locales/fr.yml +69 -14
  54. metadata +77 -95
  55. data/lib/fronde/config/lisp_config.rb +0 -340
  56. data/lib/fronde/config/org-config.el +0 -19
  57. data/lib/fronde/config/ox-fronde.el +0 -121
  58. data/lib/fronde/org_file/class_methods.rb +0 -72
  59. data/lib/fronde/org_file/extracter.rb +0 -72
  60. data/lib/fronde/org_file/htmlizer.rb +0 -43
  61. data/lib/fronde/org_file.rb +0 -298
  62. 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: 8691e788789cb725772213237a67731dc67ae77eeecc8d1d409e6779d94a22c8
4
+ data.tar.gz: d2f67191b421f902e1b41d7845fc07026843e227cfd3f70cdeff0f4d87e36b8e
5
5
  SHA512:
6
- metadata.gz: de60c2c6254acbe48846e3af209106aeb1f7058a604491e27bbeef1bf32b2c78d1d17e320d47168f086b046ad368b888a5b6933eddf56b7f4471c824c6acaa14
7
- data.tar.gz: 62f6c65db410960e4395bcbbff9bb1918886dfdb9a1c0b9c8f8871f61c285160c1a3edca901619b674b93bce80ba1cc45ce2de6ce74195c4c0f5a72292db1d70
6
+ metadata.gz: b8d3fa0a8bbfbcdecbf7a65ffc93b420876ddb27acf574a5a1a066b988ce2e039ff780b0a71bd6056f3a75b52072f4c37489135a6ead712e0a728f8385453de2
7
+ data.tar.gz: d2bd28e4fa15b156a83c61b79426f74e3e48534cfe483f92a03dd3d9a4a0675252843bb991bbb114f45421865b52e6b7f6f7dd500261cc0d8236063838f7baf4
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,37 @@
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
+
17
+ # Returns the given Time instance as a localized long string.
18
+ #
19
+ # @param time [Time] the Time instance to format
20
+ # @param with_year [Boolean] whether or not the string must contain
21
+ # the year
22
+ # @param with_time [Boolean] whether or not the string must contain
23
+ # the time
24
+ # @return [String] the localized Time string representation
25
+ def long_date_string(time, with_year: true, with_time: true)
26
+ long_fmt = fronde.index.full_date_format(
27
+ date: @locale.format_date_full(time, year: with_year)
28
+ )
29
+ if with_time
30
+ long_fmt = fronde.index.full_date_with_time_format(
31
+ date: long_fmt, time: @locale.time_format.delete('_').strip
32
+ )
33
+ end
34
+ @locale.strftime(time, long_fmt)
35
+ end
36
+ end
37
+ end
data/lib/ext/time.rb ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'r18n'
4
+ using R18nPatch
5
+
6
+ # Monkey patch to add some helpers
7
+ module TimePatch
8
+ refine Time do
9
+ # Returns the current Time instance as a localized short string.
10
+ #
11
+ # @return [String] the localized Time string representation
12
+ def l18n_short_date_string
13
+ R18n.l to_date
14
+ end
15
+
16
+ # Format the current Time as a HTML `time` tag showing a short date.
17
+ #
18
+ # @return [String] the HTML `time` tag
19
+ def l18n_short_date_html
20
+ "<time datetime=\"#{xmlschema}\">#{l18n_short_date_string}</time>"
21
+ end
22
+
23
+ # Returns the current Time instance as a localized long string.
24
+ #
25
+ # @param with_year [Boolean] whether or not the string must contain
26
+ # the year
27
+ # @return [String] the localized Time string representation
28
+ def l18n_long_date_string(with_year: true)
29
+ R18n.t.long_date_string(self, with_year: with_year)
30
+ end
31
+
32
+ # Format the current Time as a HTML `time` tag showing a long date.
33
+ #
34
+ # @return [String] the HTML `time` tag
35
+ def l18n_long_date_html
36
+ "<time datetime=\"#{xmlschema}\">#{l18n_long_date_string}</time>"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'r18n'
4
+ using R18nPatch
5
+
6
+ using TimePatch
7
+
8
+ # A time emulator to keep the fact that the time information was
9
+ # missing, even if it behaves as a Time object for the given date.
10
+ class TimeNoTime < Time
11
+ # Returns the current Time instance as a localized long string.
12
+ #
13
+ # @param with_year [Boolean] wether or not the string must contain the
14
+ # year
15
+ # @return [String] the localized Time string representation
16
+ def l18n_long_date_string(with_year: true)
17
+ R18n.t.long_date_string(self, with_year: with_year, with_time: false)
18
+ end
19
+
20
+ def self.parse_no_time(string)
21
+ strptime("#{string} 00:00:00", '%Y-%m-%d %H:%M:%S')
22
+ end
23
+ end
@@ -1,125 +1,118 @@
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
12
-
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
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
21
24
 
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
25
+ def fronde_update
26
+ Helpers.init_rakefile
27
+ init_rake
28
+ @rake.options.build_all = true
29
+ @rake['org:upgrade'].invoke
30
+ true
31
+ end
28
32
 
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
33
+ def fronde_build
34
+ @rake.options.build_all = true
35
+ @rake['site:build'].invoke @options[:force]
36
+ true
37
+ end
38
+
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
+ true
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)
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
+ true
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
+ output = [format_label(R18n.t.fronde.bin.usage(label))]
75
+ cmd = cmd_opt[:name] || @command
76
+ output << format_label(R18n.t.fronde.bin.commands[cmd])
77
+ output << OptParse.help_command_body(cmd)
78
+ warn output.join
79
+ true
74
80
  end
75
- warn help_command_body(cmd).join("\n")
76
- exit 1 if error
77
- exit
78
- end
79
81
 
80
- private
82
+ private
81
83
 
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
84
+ def format_label(label)
85
+ return '' if label == '' || label.is_a?(R18n::Untranslated)
88
86
 
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
87
+ format("%<label>s\n\n", label: label)
88
+ end
89
+
90
+ def file_name_from_title
91
+ title = @options[:title] || R18n.t.fronde.bin.options.default_title
92
+ # No title, nor a reliable file_path? Better abort
93
+ raise R18n.t.fronde.error.bin.no_file if title == ''
100
94
 
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
95
+ "#{Fronde::Slug.slug(title)}.org"
106
96
  end
107
- FileUtils.mkdir_p File.dirname(filename)
108
- Fronde::OrgFile.new(filename, @options).write
109
- filename
110
- end
111
97
 
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
- ]
98
+ def new_file_name(file_path)
99
+ file_path = File.expand_path(file_path)
100
+
101
+ if file_path[-4..] == '.org' && !File.directory?(file_path)
102
+ return file_path
103
+ end
104
+
105
+ # file_path seems to be a dir path. Thus we have to create the new
106
+ # filename from its title
107
+ File.join file_path, file_name_from_title
108
+ end
109
+
110
+ def create_new_file(file_path)
111
+ filename = new_file_name(file_path)
112
+ FileUtils.mkdir_p File.dirname(filename)
113
+ Fronde::Org::File.new(filename, @options).write
114
+ filename
115
+ end
123
116
  end
124
117
  end
125
118
  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,6 @@
1
+ .ruby-version
2
+ Rakefile
3
+ lib/
4
+ public_gmi/
5
+ public_html/
6
+ 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