fronde 0.5.0 → 0.6.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.
- checksums.yaml +4 -4
- data/lib/ext/nil_time.rb +3 -6
- data/lib/ext/time.rb +11 -8
- data/lib/ext/time_no_time.rb +12 -8
- data/lib/fronde/cli/commands.rb +7 -7
- data/lib/fronde/cli/data/fish_completion +20 -0
- data/lib/fronde/cli/helpers.rb +0 -2
- data/lib/fronde/cli/opt_parse.rb +11 -11
- data/lib/fronde/cli/throbber.rb +13 -7
- data/lib/fronde/cli.rb +1 -1
- data/lib/fronde/config/data/ox-fronde.el +44 -36
- data/lib/fronde/config/helpers.rb +1 -1
- data/lib/fronde/config/lisp.rb +1 -4
- data/lib/fronde/config.rb +9 -7
- data/lib/fronde/emacs.rb +22 -8
- data/lib/fronde/index/atom_generator.rb +1 -1
- data/lib/fronde/index/org_generator.rb +8 -6
- data/lib/fronde/index.rb +8 -3
- data/lib/fronde/org/file.rb +33 -13
- data/lib/fronde/org/file_extracter.rb +8 -0
- data/lib/fronde/org.rb +3 -3
- data/lib/fronde/source/gemini.rb +4 -4
- data/lib/fronde/source/html.rb +4 -4
- data/lib/fronde/source.rb +4 -4
- data/lib/fronde/sync/neocities.rb +13 -13
- data/lib/fronde/sync/rsync.rb +3 -3
- data/lib/fronde/sync.rb +2 -2
- data/lib/fronde/templater.rb +22 -45
- data/lib/fronde/version.rb +1 -1
- data/lib/tasks/cli.rake +45 -13
- data/lib/tasks/org.rake +19 -19
- data/lib/tasks/site.rake +57 -32
- data/lib/tasks/sync.rake +6 -14
- data/locales/en.yml +143 -82
- data/locales/fr.yml +153 -90
- metadata +18 -18
- data/lib/ext/r18n.rb +0 -37
data/lib/fronde/org/file.rb
CHANGED
@@ -109,6 +109,21 @@ module Fronde
|
|
109
109
|
@data[:date].strftime('%Y%m%d%H%M%S')
|
110
110
|
end
|
111
111
|
|
112
|
+
# Returns the path to the published version of this document.
|
113
|
+
#
|
114
|
+
# By default, this method returns the relative path to the published
|
115
|
+
# file. If the ~absolute~ argument is true, it will return the absolute
|
116
|
+
# path to the published file.
|
117
|
+
#
|
118
|
+
# @param absolute [Boolean] whether to display absolute or relative
|
119
|
+
# published file path (default false)
|
120
|
+
# @return [String] the document key
|
121
|
+
def pub_file(absolute: false)
|
122
|
+
return @data[:pub_file] unless absolute
|
123
|
+
|
124
|
+
"#{@project['folder']}#{@data[:pub_file]}"
|
125
|
+
end
|
126
|
+
|
112
127
|
# Formats given ~string~ with values of the current Org::File.
|
113
128
|
#
|
114
129
|
# This method expects to find percent-tags in the given ~string~
|
@@ -151,6 +166,7 @@ module Fronde
|
|
151
166
|
# org_file.format("Article written by %a the %d")
|
152
167
|
# => "Article written by Alice Smith the Wednesday 3rd July"
|
153
168
|
#
|
169
|
+
# @param string [String] the template text to edit
|
154
170
|
# @return [String] the given ~string~ after replacement occurs
|
155
171
|
# rubocop:disable Layout/LineLength
|
156
172
|
def format(string)
|
@@ -159,13 +175,18 @@ module Fronde
|
|
159
175
|
# %a (author), %c (creator), %C (input-file), %d (date),
|
160
176
|
# %e (email), %s (subtitle), %t (title), %T (timestamp),
|
161
177
|
# %v (html validation link)
|
178
|
+
localized_dates = I18n.with_locale(@data[:lang]) do
|
179
|
+
{ short: @data[:date].l18n_short_date_string,
|
180
|
+
short_html: @data[:date].l18n_short_date_html,
|
181
|
+
long_html: @data[:date].l18n_long_date_html }
|
182
|
+
end
|
162
183
|
string.gsub('%a', @data[:author])
|
163
184
|
.gsub('%A', "<span class=\"author\">#{@data[:author]}</span>")
|
164
|
-
.gsub('%d',
|
165
|
-
.gsub('%D',
|
185
|
+
.gsub('%d', localized_dates[:short_html])
|
186
|
+
.gsub('%D', localized_dates[:long_html])
|
166
187
|
.gsub('%F', project_data['atom_feed'] || '')
|
167
188
|
.gsub('%h', project_data['domain'] || '')
|
168
|
-
.gsub('%i',
|
189
|
+
.gsub('%i', localized_dates[:short])
|
169
190
|
.gsub('%I', @data[:date].xmlschema)
|
170
191
|
.gsub('%k', @data[:keywords].join(', '))
|
171
192
|
.gsub('%K', keywords_to_html)
|
@@ -191,18 +212,17 @@ module Fronde
|
|
191
212
|
def write
|
192
213
|
if ::File.directory? @file
|
193
214
|
if @data[:title] == ''
|
194
|
-
raise
|
215
|
+
raise I18n.t('fronde.error.org_file.no_file_or_title')
|
195
216
|
end
|
196
217
|
|
197
218
|
@file = ::File.join @file, "#{Slug.slug(@data[:title])}.org"
|
198
219
|
else
|
199
|
-
|
200
|
-
FileUtils.mkdir_p file_dir
|
220
|
+
FileUtils.mkdir_p ::File.dirname(@file)
|
201
221
|
end
|
202
222
|
::File.write @file, @data[:content]
|
203
223
|
end
|
204
224
|
|
205
|
-
def method_missing(method_name, *args, &
|
225
|
+
def method_missing(method_name, *args, &)
|
206
226
|
reader_method = method_name.to_s.delete_suffix('=').to_sym
|
207
227
|
if @data.has_key? reader_method
|
208
228
|
return @data[reader_method] if reader_method == method_name
|
@@ -222,11 +242,13 @@ module Fronde
|
|
222
242
|
end
|
223
243
|
|
224
244
|
def to_h
|
225
|
-
fields = %w[author excerpt keywords timekey title url]
|
245
|
+
fields = %w[author excerpt keywords lang timekey title url]
|
226
246
|
data = fields.to_h { |key| [key, send(key)] }
|
227
247
|
data['published_body'] = extract_published_body
|
228
248
|
pub_date = @data[:date]
|
229
|
-
data['published'] =
|
249
|
+
data['published'] = I18n.with_locale(@data[:lang]) do
|
250
|
+
pub_date.l18n_long_date_no_year_string
|
251
|
+
end
|
230
252
|
data['published_gemini_index'] = pub_date.strftime('%Y-%m-%d')
|
231
253
|
data['published_xml'] = pub_date.xmlschema
|
232
254
|
data['updated_xml'] = @data[:updated]&.xmlschema
|
@@ -244,13 +266,11 @@ module Fronde
|
|
244
266
|
return source if source
|
245
267
|
|
246
268
|
short_file = @file.sub(/^#{Dir.pwd}/, '.')
|
247
|
-
warn
|
269
|
+
warn I18n.t('fronde.error.org_file.no_project', file: short_file)
|
248
270
|
end
|
249
271
|
|
250
272
|
def find_source_for_org_file
|
251
|
-
Fronde::CONFIG.sources.find
|
252
|
-
project.source_for? @file
|
253
|
-
end
|
273
|
+
Fronde::CONFIG.sources.find { _1.source_for? @file }
|
254
274
|
end
|
255
275
|
|
256
276
|
def find_source_for_publication_file
|
@@ -20,11 +20,19 @@ module Fronde
|
|
20
20
|
end
|
21
21
|
return unless @project
|
22
22
|
|
23
|
+
warn_if_dangerous_code_block
|
23
24
|
@data[:updated] = ::File.mtime(@file)
|
24
25
|
@data[:pub_file] = @project.target_for @file
|
25
26
|
@data[:url] = Fronde::CONFIG.get('domain') + @data[:pub_file]
|
26
27
|
end
|
27
28
|
|
29
|
+
def warn_if_dangerous_code_block
|
30
|
+
code_block_rx = /^#\+begin_src.+:exports (?:results|both).*$/i
|
31
|
+
return unless code_block_rx.match?(@data[:content])
|
32
|
+
|
33
|
+
warn I18n.t('fronde.error.org_file.dangerous_code_block', file: @file)
|
34
|
+
end
|
35
|
+
|
28
36
|
def extract_date
|
29
37
|
timerx = '([0-9:]{5})(?::([0-9]{2}))?'
|
30
38
|
daterx = /^#\+date: *<([0-9-]{10}) [\w.]+(?: #{timerx})?> *$/i
|
data/lib/fronde/org.rb
CHANGED
@@ -10,7 +10,7 @@ module Fronde
|
|
10
10
|
class << self
|
11
11
|
def current_version
|
12
12
|
# Do not crash if Org is not yet installed (and thus return nil)
|
13
|
-
Dir
|
13
|
+
Dir.glob('lib/org-*').first&.delete_prefix('lib/org-')
|
14
14
|
end
|
15
15
|
|
16
16
|
# Fetch and return the last published version of Org.
|
@@ -97,8 +97,8 @@ module Fronde
|
|
97
97
|
FileUtils.mv "org-mode-release_#{version}", target
|
98
98
|
# Fix a weird unknown package version
|
99
99
|
::File.write("#{target}/mk/version.mk", "ORGVERSION ?= #{version}")
|
100
|
-
system(*make_org_cmd(target, 'compile', verbose:
|
101
|
-
system(*make_org_cmd(target, 'autoloads', verbose:
|
100
|
+
system(*make_org_cmd(target, 'compile', verbose:))
|
101
|
+
system(*make_org_cmd(target, 'autoloads', verbose:))
|
102
102
|
end
|
103
103
|
end
|
104
104
|
end
|
data/lib/fronde/source/gemini.rb
CHANGED
@@ -8,9 +8,9 @@ module Fronde
|
|
8
8
|
def org_default_postamble
|
9
9
|
format(
|
10
10
|
"📅 %<date>s\n📝 %<author>s %<creator>s",
|
11
|
-
author:
|
12
|
-
creator:
|
13
|
-
date:
|
11
|
+
author: I18n.t('fronde.org.postamble.written_by'),
|
12
|
+
creator: I18n.t('fronde.org.postamble.with_emacs'),
|
13
|
+
date: I18n.t('fronde.org.postamble.last_modification')
|
14
14
|
)
|
15
15
|
end
|
16
16
|
end
|
@@ -20,7 +20,7 @@ module Fronde
|
|
20
20
|
def fill_in_specific_config
|
21
21
|
@config.merge!(
|
22
22
|
'type' => 'gemini', 'ext' => '.gmi', 'mime_type' => 'text/gemini',
|
23
|
-
'folder' => CONFIG.get('gemini_public_folder')
|
23
|
+
'folder' => File.expand_path(CONFIG.get('gemini_public_folder'))
|
24
24
|
)
|
25
25
|
end
|
26
26
|
|
data/lib/fronde/source/html.rb
CHANGED
@@ -13,9 +13,9 @@ module Fronde
|
|
13
13
|
class << self
|
14
14
|
def org_default_postamble
|
15
15
|
<<~POSTAMBLE
|
16
|
-
<p><span class="author">#{
|
17
|
-
#{
|
18
|
-
<p class="date">#{
|
16
|
+
<p><span class="author">#{I18n.t('fronde.org.postamble.written_by')}</span>
|
17
|
+
#{I18n.t('fronde.org.postamble.with_emacs_html')}</p>
|
18
|
+
<p class="date">#{I18n.t('fronde.org.postamble.last_modification')}</p>
|
19
19
|
<p class="validation">%v</p>
|
20
20
|
POSTAMBLE
|
21
21
|
end
|
@@ -26,7 +26,7 @@ module Fronde
|
|
26
26
|
def fill_in_specific_config
|
27
27
|
@config.merge!(
|
28
28
|
'type' => 'html', 'ext' => '.html', 'mime_type' => 'text/html',
|
29
|
-
'folder' => CONFIG.get('html_public_folder')
|
29
|
+
'folder' => File.expand_path(CONFIG.get('html_public_folder'))
|
30
30
|
)
|
31
31
|
end
|
32
32
|
|
data/lib/fronde/source.rb
CHANGED
@@ -58,11 +58,11 @@ module Fronde
|
|
58
58
|
def source_for(file_name)
|
59
59
|
relative_file_path = file_name.delete_prefix "#{publication_path}/"
|
60
60
|
# file_name does not begin with source path.
|
61
|
-
return
|
61
|
+
return if relative_file_path == file_name
|
62
62
|
|
63
63
|
# Looks like a file at a deeper level, but current source is not
|
64
64
|
# recursive.
|
65
|
-
return
|
65
|
+
return if relative_file_path.include?('/') && !recursive?
|
66
66
|
|
67
67
|
# Looks like a match. But does a source file for this one actually
|
68
68
|
# exists?
|
@@ -70,7 +70,7 @@ module Fronde
|
|
70
70
|
/#{@config['ext']}\z/, '.org'
|
71
71
|
)
|
72
72
|
source_path = File.join(@config['path'], relative_source_path)
|
73
|
-
return
|
73
|
+
return unless File.file?(source_path)
|
74
74
|
|
75
75
|
source_path
|
76
76
|
end
|
@@ -111,7 +111,7 @@ module Fronde
|
|
111
111
|
def publication_path
|
112
112
|
return @config['publication_path'] if @config['publication_path']
|
113
113
|
|
114
|
-
publish_in = [
|
114
|
+
publish_in = [@config['folder'], @config['target']]
|
115
115
|
@config['publication_path'] = publish_in.join('/').delete_suffix('/')
|
116
116
|
end
|
117
117
|
|
@@ -35,7 +35,7 @@ module Fronde
|
|
35
35
|
|
36
36
|
def local_list
|
37
37
|
Dir.chdir(@public_folder) do
|
38
|
-
Dir
|
38
|
+
Dir.glob('**/*').map { |file| neocities_stat(file) }
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -52,19 +52,19 @@ module Fronde
|
|
52
52
|
file_list = remote_list
|
53
53
|
finish
|
54
54
|
orphans = select_orphans(file_list, local_list) do |path|
|
55
|
-
|
55
|
+
puts I18n.t('fronde.neocities.deleting', path:) if @verbose
|
56
56
|
|
57
57
|
"#{@public_folder}/#{path}"
|
58
58
|
end
|
59
59
|
File.unlink(*orphans) unless test
|
60
|
-
download_all
|
60
|
+
download_all(file_list, test:)
|
61
61
|
nil # Mute this method
|
62
62
|
end
|
63
63
|
|
64
64
|
def push(test: false)
|
65
65
|
file_list = local_list
|
66
|
-
remove_remote_orphans
|
67
|
-
upload_all
|
66
|
+
remove_remote_orphans(file_list, test:)
|
67
|
+
upload_all(file_list, test:)
|
68
68
|
finish
|
69
69
|
end
|
70
70
|
|
@@ -84,10 +84,10 @@ module Fronde
|
|
84
84
|
data
|
85
85
|
end
|
86
86
|
|
87
|
-
def select_orphans(to_apply, current_list, &
|
87
|
+
def select_orphans(to_apply, current_list, &)
|
88
88
|
paths_to_apply = to_apply.map { _1['path'] }
|
89
89
|
current_paths = current_list.map { _1['path'] }
|
90
|
-
(current_paths - paths_to_apply).filter_map(&
|
90
|
+
(current_paths - paths_to_apply).filter_map(&)
|
91
91
|
end
|
92
92
|
|
93
93
|
def remove_remote_orphans(file_list, test: false)
|
@@ -98,7 +98,7 @@ module Fronde
|
|
98
98
|
# the index.html file to be removed.
|
99
99
|
next if PROTECTED_FILES.include? path
|
100
100
|
|
101
|
-
|
101
|
+
puts I18n.t('fronde.neocities.deleting', path:) if @verbose
|
102
102
|
path
|
103
103
|
end
|
104
104
|
request.form_data = { 'filenames[]' => orphan_paths }
|
@@ -114,7 +114,7 @@ module Fronde
|
|
114
114
|
file_list.each do |file_data|
|
115
115
|
path = file_data['path']
|
116
116
|
file_data['uri'] = "https://#{publish_domain}/#{path}"
|
117
|
-
download_file http, file_data, test:
|
117
|
+
download_file http, file_data, test:
|
118
118
|
end
|
119
119
|
end
|
120
120
|
end
|
@@ -123,12 +123,12 @@ module Fronde
|
|
123
123
|
def download_file(http, file_data, test: false)
|
124
124
|
path = file_data['path']
|
125
125
|
if file_data['is_directory']
|
126
|
-
|
126
|
+
puts "#{path}/" if @verbose
|
127
127
|
FileUtils.mkdir_p path unless test
|
128
128
|
return
|
129
129
|
end
|
130
130
|
|
131
|
-
|
131
|
+
puts path if @verbose
|
132
132
|
|
133
133
|
content = fetch_file_content(
|
134
134
|
http, file_data['uri'], file_data['sha1_hash']
|
@@ -146,7 +146,7 @@ module Fronde
|
|
146
146
|
check = Digest::SHA1.hexdigest content
|
147
147
|
return content if check == sha1sum
|
148
148
|
|
149
|
-
warn
|
149
|
+
warn I18n.t('fronde.neocities.sha1_differ', uri:)
|
150
150
|
end
|
151
151
|
|
152
152
|
def save_file(path, content, updated_at)
|
@@ -163,7 +163,7 @@ module Fronde
|
|
163
163
|
next if file_data['is_directory']
|
164
164
|
|
165
165
|
path = file_data['path']
|
166
|
-
|
166
|
+
puts path if @verbose
|
167
167
|
[path, File.new(path)]
|
168
168
|
end
|
169
169
|
end
|
data/lib/fronde/sync/rsync.rb
CHANGED
@@ -13,17 +13,17 @@ module Fronde
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def pull(test: false)
|
16
|
-
run command(test:
|
16
|
+
run command(test:) + [@remote_path, @local_path]
|
17
17
|
end
|
18
18
|
|
19
19
|
def push(test: false)
|
20
|
-
run command(test:
|
20
|
+
run command(test:) + [@local_path, @remote_path]
|
21
21
|
end
|
22
22
|
|
23
23
|
private
|
24
24
|
|
25
25
|
def run(cmd)
|
26
|
-
|
26
|
+
puts cmd.join(' ') if @verbose
|
27
27
|
# Be precise about Kernel to allow mock in rspec
|
28
28
|
Kernel.system(*cmd)
|
29
29
|
end
|
data/lib/fronde/sync.rb
CHANGED
@@ -25,8 +25,8 @@ module Fronde
|
|
25
25
|
method, remote_path = extract_method_and_remote type
|
26
26
|
public_folder = Fronde::CONFIG.get("#{type}_public_folder")
|
27
27
|
klass = Kernel.const_get("::Fronde::Sync::#{method.capitalize}")
|
28
|
-
syncer = klass.new(remote_path, public_folder, verbose:
|
29
|
-
Thread.new { syncer.send(direction, test:
|
28
|
+
syncer = klass.new(remote_path, public_folder, verbose:)
|
29
|
+
Thread.new { syncer.send(direction, test:) }
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
data/lib/fronde/templater.rb
CHANGED
@@ -5,8 +5,6 @@ require 'digest/md5'
|
|
5
5
|
require_relative 'org/file'
|
6
6
|
|
7
7
|
module Fronde
|
8
|
-
class NoHeadError < ::StandardError; end
|
9
|
-
|
10
8
|
# Insert custom part inside generated HTML files.
|
11
9
|
class Templater
|
12
10
|
def initialize(source, dom, config = {})
|
@@ -19,74 +17,55 @@ module Fronde
|
|
19
17
|
|
20
18
|
def apply
|
21
19
|
# Flag the file for this template
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
head.prepend_child("<!--#{@config['check_line']}-->")
|
20
|
+
html = @dom.xpath('//html').first
|
21
|
+
html.add_child("<!--#{@config['check_line']}-->\n")
|
26
22
|
content = @org_file.format extract_content
|
27
23
|
# Remove source element if necessary to avoid doubling it during
|
28
24
|
# the insert action
|
29
25
|
@config['source'].unlink if @config.has_key? 'source'
|
30
26
|
# Insert new content
|
31
|
-
@dom.css(@config['selector']).
|
27
|
+
@dom.css(@config['selector']).map do |element|
|
32
28
|
insert_new_node_at element, content
|
33
29
|
end
|
34
30
|
end
|
35
31
|
|
36
|
-
def
|
37
|
-
@dom.xpath('//
|
32
|
+
def applied?
|
33
|
+
@dom.xpath('//html').children.any? do |child|
|
38
34
|
next false unless child.comment?
|
39
35
|
|
40
36
|
child.text == @config['check_line']
|
41
37
|
end
|
42
38
|
end
|
43
39
|
|
44
|
-
def valid?
|
40
|
+
def valid?
|
45
41
|
return false unless @config.has_key?('selector')
|
46
42
|
|
47
43
|
unless @config.has_key?('content') || @config.has_key?('source')
|
48
44
|
return false
|
49
45
|
end
|
50
46
|
|
51
|
-
check_path
|
47
|
+
check_path
|
52
48
|
end
|
53
49
|
|
54
50
|
class << self
|
55
51
|
def customize_output(file_name)
|
56
|
-
source = Fronde::Org::File.new
|
52
|
+
source = Fronde::Org::File.new file_name
|
57
53
|
# Return if no org file found for this published file
|
58
|
-
return
|
54
|
+
return unless source.pub_file
|
59
55
|
|
60
|
-
|
61
|
-
updated = apply_templates(source, dom, file_name)
|
62
|
-
write_dom(file_name, dom) if updated
|
56
|
+
apply_templates source
|
63
57
|
end
|
64
58
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
Fronde::CONFIG.get('templates', []).map do |config|
|
59
|
+
def apply_templates(source)
|
60
|
+
public_file = source.pub_file absolute: true
|
61
|
+
dom = File.open(public_file, 'r') { Nokogiri::HTML _1 }
|
62
|
+
changes = Fronde::CONFIG.get('templates', []).map do |config|
|
69
63
|
template = Fronde::Templater.new(source, dom, config)
|
70
|
-
next if !template.valid?
|
64
|
+
next if !template.valid? || template.applied?
|
71
65
|
|
72
66
|
template.apply
|
73
|
-
true
|
74
|
-
rescue NoHeadError
|
75
|
-
warn R18n.t.fronde.error.templater.no_head_element(file: file_name)
|
76
|
-
next
|
77
|
-
end.any?
|
78
|
-
end
|
79
|
-
|
80
|
-
def open_dom(file_name)
|
81
|
-
File.open(file_name, 'r') do |file|
|
82
|
-
Nokogiri::HTML file
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def write_dom(file_name, dom)
|
87
|
-
File.open(file_name, 'w') do |file|
|
88
|
-
dom.write_to file
|
89
67
|
end
|
68
|
+
File.open(public_file, 'w') { dom.write_to _1 } if changes.any?
|
90
69
|
end
|
91
70
|
end
|
92
71
|
|
@@ -104,12 +83,11 @@ module Fronde
|
|
104
83
|
end
|
105
84
|
|
106
85
|
def warn_no_element(source)
|
107
|
-
|
108
|
-
/^#{Dir.pwd}/, '.'
|
109
|
-
)
|
86
|
+
public_file = @org_file.pub_file(absolute: true)
|
110
87
|
warn(
|
111
|
-
|
112
|
-
|
88
|
+
I18n.t(
|
89
|
+
'fronde.error.templater.no_element_found',
|
90
|
+
source: source, file: public_file.sub(/^#{Dir.pwd}/, '.')
|
113
91
|
)
|
114
92
|
)
|
115
93
|
'' # Return empty string
|
@@ -133,15 +111,14 @@ module Fronde
|
|
133
111
|
warn_no_element source
|
134
112
|
end
|
135
113
|
|
136
|
-
def check_path
|
114
|
+
def check_path
|
137
115
|
paths = @config['path']
|
138
116
|
return true unless paths
|
139
117
|
|
140
118
|
paths = [paths] unless paths.is_a? Array
|
141
119
|
|
142
|
-
pub_folder = Fronde::CONFIG.get('html_public_folder')
|
143
120
|
paths.any? do |template_path|
|
144
|
-
File.fnmatch?(
|
121
|
+
File.fnmatch?(template_path, @org_file.pub_file)
|
145
122
|
end
|
146
123
|
end
|
147
124
|
end
|
data/lib/fronde/version.rb
CHANGED
data/lib/tasks/cli.rake
CHANGED
@@ -2,6 +2,24 @@
|
|
2
2
|
|
3
3
|
require_relative '../fronde/cli/opt_parse'
|
4
4
|
|
5
|
+
def comp_opt_to_liquid(option, command)
|
6
|
+
opt_config = Fronde::CLI::OptParse::FRONDE_OPTIONS[option]
|
7
|
+
keyword = nil
|
8
|
+
unless opt_config[:boolean]
|
9
|
+
keyword = opt_config[:keyword] || opt_config[:long].upcase
|
10
|
+
end
|
11
|
+
{
|
12
|
+
'command' => command,
|
13
|
+
'short' => option,
|
14
|
+
'short_no_dash' => option.delete_prefix('-'),
|
15
|
+
'long' => "--#{opt_config[:long]}",
|
16
|
+
'long_no_dash' => opt_config[:long],
|
17
|
+
'keyword' => keyword,
|
18
|
+
'choices' => opt_config[:choices],
|
19
|
+
'help' => opt_config[:help]
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
5
23
|
namespace :cli do
|
6
24
|
desc 'Generate an autocomplete file for zsh'
|
7
25
|
task :zsh_complete do
|
@@ -10,24 +28,38 @@ namespace :cli do
|
|
10
28
|
data['commands'] = all_commands.filter_map do |command, options|
|
11
29
|
next if options[:alias] || command == 'basic'
|
12
30
|
|
13
|
-
opts = (options[:opts] || []).map
|
14
|
-
opt_config = Fronde::CLI::OptParse::FRONDE_OPTIONS[opt]
|
15
|
-
keyword = nil
|
16
|
-
unless opt_config[:boolean]
|
17
|
-
keyword = opt_config[:keyword] || opt_config[:long].upcase
|
18
|
-
end
|
19
|
-
{ 'short' => opt,
|
20
|
-
'long' => "--#{opt_config[:long]}",
|
21
|
-
'keyword' => keyword }
|
22
|
-
end
|
23
|
-
|
24
|
-
translation = R18n.t.fronde.bin.commands[command].tr("'", '’')
|
31
|
+
opts = (options[:opts] || []).map { comp_opt_to_liquid(_1, command) }
|
25
32
|
{ 'name' => command,
|
26
|
-
'translation' =>
|
33
|
+
'translation' => I18n.t("fronde.bin.commands.#{command}"),
|
27
34
|
'options' => opts }
|
28
35
|
end
|
29
36
|
source = File.expand_path '../fronde/cli/data/zsh_completion', __dir__
|
30
37
|
template = Liquid::Template.parse(File.read(source))
|
31
38
|
puts template.render(data)
|
32
39
|
end
|
40
|
+
|
41
|
+
desc 'Generate an autocomplete file for fish'
|
42
|
+
task :fish_complete do
|
43
|
+
data = { 'commands' => [], 'details' => [] }
|
44
|
+
all_commands = []
|
45
|
+
Fronde::CLI::OptParse::FRONDE_COMMANDS.each do |command, options|
|
46
|
+
next if options[:alias]
|
47
|
+
|
48
|
+
data['details'] += (options[:opts] || []).map do |opt|
|
49
|
+
comp_opt_to_liquid opt, command
|
50
|
+
end
|
51
|
+
next if command == 'basic'
|
52
|
+
|
53
|
+
data['commands'] << command
|
54
|
+
|
55
|
+
help = I18n.t("fronde.bin.commands.#{command}")
|
56
|
+
all_commands << "#{command}\\t'#{help}'"
|
57
|
+
end
|
58
|
+
|
59
|
+
data['comcomp'] = all_commands.join('\n')
|
60
|
+
|
61
|
+
source = File.expand_path '../fronde/cli/data/fish_completion', __dir__
|
62
|
+
template = Liquid::Template.parse(File.read(source))
|
63
|
+
puts template.render(data)
|
64
|
+
end
|
33
65
|
end
|
data/lib/tasks/org.rake
CHANGED
@@ -11,6 +11,9 @@ CLOBBER.push(
|
|
11
11
|
'var/lib/org-config.el', 'lib/htmlize.el'
|
12
12
|
)
|
13
13
|
|
14
|
+
HTMLIZE_TAG = 'release/1.58'
|
15
|
+
OX_GMI_TAG = 'v0.2'
|
16
|
+
|
14
17
|
namespace :org do
|
15
18
|
directory 'var/tmp'
|
16
19
|
|
@@ -19,37 +22,34 @@ namespace :org do
|
|
19
22
|
# Weird Rake issue, still executing the task even if the file exists
|
20
23
|
next if File.exist? 'var/tmp/org.tar.gz'
|
21
24
|
|
22
|
-
download = Thread.new
|
23
|
-
|
24
|
-
|
25
|
-
else
|
26
|
-
Fronde::CLI::Throbber.run(download, R18n.t.fronde.tasks.org.downloading)
|
25
|
+
download = Thread.new do
|
26
|
+
version = Fronde::Org.download
|
27
|
+
puts I18n.t('fronde.tasks.org.downloaded', version:) if verbose
|
27
28
|
end
|
29
|
+
Fronde::CLI::Throbber.run(
|
30
|
+
download, I18n.t('fronde.tasks.org.downloading'), verbose
|
31
|
+
)
|
28
32
|
rescue RuntimeError, Interrupt
|
29
|
-
warn
|
33
|
+
warn I18n.t('fronde.tasks.org.no_download') if verbose
|
30
34
|
end
|
31
35
|
|
32
36
|
desc 'Compile Org'
|
33
37
|
multitask compile: ['var/tmp/org.tar.gz', 'lib'] do |task|
|
34
38
|
# No need to force fetch last version as it is only interesting as
|
35
39
|
# part of the upgrade task
|
36
|
-
|
40
|
+
version = Fronde::Org.last_version
|
37
41
|
|
38
|
-
org_dir = "lib/org-#{
|
42
|
+
org_dir = "lib/org-#{version}"
|
39
43
|
next if Dir.exist?("#{org_dir}/lisp")
|
40
44
|
|
41
45
|
build = Thread.new do
|
42
|
-
Fronde::Org.compile(
|
43
|
-
task.prerequisites[0], org_version, org_dir, verbose: verbose
|
44
|
-
)
|
46
|
+
Fronde::Org.compile(task.prerequisites[0], version, org_dir, verbose:)
|
45
47
|
Dir.glob('lib/org-[0-9.]*').each { rm_r _1 unless _1 == org_dir }
|
48
|
+
puts I18n.t('fronde.tasks.org.installed', version:) if verbose
|
46
49
|
end
|
47
|
-
|
48
|
-
build.
|
49
|
-
|
50
|
-
else
|
51
|
-
Fronde::CLI::Throbber.run(build, R18n.t.fronde.tasks.org.installing)
|
52
|
-
end
|
50
|
+
Fronde::CLI::Throbber.run(
|
51
|
+
build, I18n.t('fronde.tasks.org.installing'), verbose
|
52
|
+
)
|
53
53
|
rescue RuntimeError, Interrupt
|
54
54
|
next
|
55
55
|
end
|
@@ -58,14 +58,14 @@ namespace :org do
|
|
58
58
|
|
59
59
|
file 'lib/htmlize.el' => 'lib' do
|
60
60
|
htmlize = URI(
|
61
|
-
|
61
|
+
"https://raw.githubusercontent.com/hniksic/emacs-htmlize/refs/tags/#{HTMLIZE_TAG}/htmlize.el"
|
62
62
|
).open.read
|
63
63
|
File.write 'lib/htmlize.el', htmlize
|
64
64
|
end
|
65
65
|
|
66
66
|
file 'lib/ox-gmi.el' => 'lib' do
|
67
67
|
ox_gmi = URI(
|
68
|
-
|
68
|
+
"https://git.umaneti.net/ox-gmi/plain/ox-gmi.el?h=#{OX_GMI_TAG}"
|
69
69
|
).open.read
|
70
70
|
File.write 'lib/ox-gmi.el', ox_gmi
|
71
71
|
end
|