fronde 0.3.4 → 0.5.0

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.
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