fronde 0.4.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 +10 -17
- data/lib/ext/time_no_time.rb +27 -0
- data/lib/fronde/cli/commands.rb +18 -14
- data/lib/fronde/cli/data/fish_completion +20 -0
- data/lib/fronde/cli/data/gitignore +0 -1
- data/lib/fronde/cli/helpers.rb +0 -2
- data/lib/fronde/cli/opt_parse.rb +15 -18
- data/lib/fronde/cli/throbber.rb +35 -18
- data/lib/fronde/cli.rb +4 -3
- data/lib/fronde/config/data/org-config.el +3 -2
- data/lib/fronde/config/data/ox-fronde.el +91 -46
- data/lib/fronde/config/data/themes/umaneti/css/htmlize.css +364 -0
- data/lib/fronde/config/data/themes/umaneti/css/style.css +250 -0
- data/lib/fronde/config/data/themes/umaneti/img/bottom.png +0 -0
- data/lib/fronde/config/data/themes/umaneti/img/content.png +0 -0
- data/lib/fronde/config/data/themes/umaneti/img/tic.png +0 -0
- data/lib/fronde/config/data/themes/umaneti/img/top.png +0 -0
- data/lib/fronde/config/helpers.rb +1 -19
- data/lib/fronde/config/lisp.rb +14 -7
- data/lib/fronde/config.rb +47 -31
- data/lib/fronde/emacs.rb +23 -9
- data/lib/fronde/index/atom_generator.rb +1 -1
- data/lib/fronde/index/data/all_tags.org +6 -1
- data/lib/fronde/index/data/template.org +8 -4
- data/lib/fronde/index/org_generator.rb +10 -6
- data/lib/fronde/index.rb +19 -17
- data/lib/fronde/org/file.rb +71 -39
- data/lib/fronde/org/file_extracter.rb +23 -12
- data/lib/fronde/org.rb +14 -12
- data/lib/fronde/slug.rb +39 -12
- data/lib/fronde/source/gemini.rb +4 -9
- data/lib/fronde/source/html.rb +9 -9
- data/lib/fronde/source.rb +17 -12
- data/lib/fronde/sync/neocities.rb +220 -0
- data/lib/fronde/sync/rsync.rb +46 -0
- data/lib/fronde/sync.rb +32 -0
- data/lib/fronde/templater.rb +35 -51
- data/lib/fronde/version.rb +1 -1
- data/lib/tasks/cli.rake +45 -13
- data/lib/tasks/org.rake +30 -35
- data/lib/tasks/site.rake +63 -41
- data/lib/tasks/sync.rake +19 -50
- data/lib/tasks/tags.rake +2 -2
- data/locales/en.yml +143 -81
- data/locales/fr.yml +153 -89
- metadata +56 -17
- data/lib/ext/r18n.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d233f108a209e4d5a02633de060293ce6f4981393555ebf5f53f16a25f6d3d0
|
4
|
+
data.tar.gz: 9efa6cd46fc4d6d33e98bcee3e7cb1dd43a179736bafb552f6ac3e7a8c5bb8ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1c7f18af62f3fbd02be2f025c7d6305a7ea1c3751a35490eee4402de3a4aebf11c211cc3efcc4d57d0b82e99807a439ef920eb67182f0f8313905b20d89fd15
|
7
|
+
data.tar.gz: 315634038a4eb1df1c07f019894a0b86b591649f58068d771811bc0bbb92402cc03f79ada03f716caae0e8219075937d1df63ab3e6453827fadb03763203d4da
|
data/lib/ext/nil_time.rb
CHANGED
@@ -10,12 +10,9 @@ class NilTime
|
|
10
10
|
''
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
def l18n_long_date_string(*)
|
18
|
-
''
|
13
|
+
%i[l18n_short_date_string l18n_long_date_string
|
14
|
+
l18n_long_date_no_year_string].each do |name|
|
15
|
+
define_method(name) { '' }
|
19
16
|
end
|
20
17
|
|
21
18
|
def l18n_short_date_html
|
data/lib/ext/time.rb
CHANGED
@@ -7,7 +7,7 @@ module TimePatch
|
|
7
7
|
#
|
8
8
|
# @return [String] the localized Time string representation
|
9
9
|
def l18n_short_date_string
|
10
|
-
|
10
|
+
I18n.l to_date
|
11
11
|
end
|
12
12
|
|
13
13
|
# Format the current Time as a HTML `time` tag showing a short date.
|
@@ -17,26 +17,19 @@ module TimePatch
|
|
17
17
|
"<time datetime=\"#{xmlschema}\">#{l18n_short_date_string}</time>"
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
# Returns the current Time instance as a localized long string.
|
21
|
+
#
|
22
|
+
# @return [String] the localized Time string representation
|
23
|
+
def l18n_long_date_string
|
24
|
+
I18n.l self, format: :long
|
22
25
|
end
|
23
26
|
|
24
|
-
# Returns the current Time instance as a localized long string
|
27
|
+
# Returns the current Time instance as a localized long string
|
28
|
+
# without year.
|
25
29
|
#
|
26
|
-
# @param with_year [Boolean] wether or not the string must contain the
|
27
|
-
# year
|
28
30
|
# @return [String] the localized Time string representation
|
29
|
-
def
|
30
|
-
|
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)
|
31
|
+
def l18n_long_date_no_year_string
|
32
|
+
I18n.l self, format: :long_no_year
|
40
33
|
end
|
41
34
|
|
42
35
|
# Format the current Time as a HTML `time` tag showing a long date.
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
using TimePatch
|
4
|
+
|
5
|
+
# A time emulator to keep the fact that the time information was
|
6
|
+
# missing, even if it behaves as a Time object for the given date.
|
7
|
+
class TimeNoTime < Time
|
8
|
+
# Returns the current Time instance as a localized long string
|
9
|
+
# without time.
|
10
|
+
#
|
11
|
+
# @return [String] the localized Time string representation
|
12
|
+
def l18n_long_date_string
|
13
|
+
I18n.l self, format: :long_no_time
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the current Time instance as a localized long string
|
17
|
+
# without time nor year.
|
18
|
+
#
|
19
|
+
# @return [String] the localized Time string representation
|
20
|
+
def l18n_long_date_no_year_string
|
21
|
+
I18n.l self, format: :long_no_time_no_year
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.parse_no_time(string)
|
25
|
+
strptime("#{string} 00:00:00", '%Y-%m-%d %H:%M:%S')
|
26
|
+
end
|
27
|
+
end
|
data/lib/fronde/cli/commands.rb
CHANGED
@@ -27,13 +27,13 @@ module Fronde
|
|
27
27
|
init_rake
|
28
28
|
@rake.options.build_all = true
|
29
29
|
@rake['org:upgrade'].invoke
|
30
|
-
|
30
|
+
true
|
31
31
|
end
|
32
32
|
|
33
33
|
def fronde_build
|
34
34
|
@rake.options.build_all = true
|
35
35
|
@rake['site:build'].invoke @options[:force]
|
36
|
-
|
36
|
+
true
|
37
37
|
end
|
38
38
|
|
39
39
|
def fronde_preview
|
@@ -43,7 +43,7 @@ module Fronde
|
|
43
43
|
Helpers.launch_app_for_uri "http://127.0.0.1:#{port}/"
|
44
44
|
end
|
45
45
|
@rake['site:preview'].invoke
|
46
|
-
|
46
|
+
true
|
47
47
|
end
|
48
48
|
|
49
49
|
def fronde_open
|
@@ -58,12 +58,12 @@ module Fronde
|
|
58
58
|
cmd << '+6'
|
59
59
|
end
|
60
60
|
cmd << file_path
|
61
|
-
|
61
|
+
system(*cmd)
|
62
62
|
end
|
63
63
|
|
64
64
|
def fronde_publish
|
65
65
|
@rake['sync:push'].invoke
|
66
|
-
|
66
|
+
true
|
67
67
|
end
|
68
68
|
|
69
69
|
def fronde_help
|
@@ -71,22 +71,26 @@ module Fronde
|
|
71
71
|
@command = @argv.shift || 'basic' if @command == 'help'
|
72
72
|
cmd_opt = OptParse.command_options(@command)
|
73
73
|
label = cmd_opt[:label] || @command
|
74
|
-
|
74
|
+
output = [format_label(I18n.t('fronde.bin.usage', label:))]
|
75
75
|
cmd = cmd_opt[:name] || @command
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
warn body unless body == ''
|
81
|
-
0
|
76
|
+
output << format_label(I18n.t("fronde.bin.commands.#{cmd}"))
|
77
|
+
output << OptParse.help_command_body(cmd)
|
78
|
+
puts output.join
|
79
|
+
true
|
82
80
|
end
|
83
81
|
|
84
82
|
private
|
85
83
|
|
84
|
+
def format_label(label)
|
85
|
+
return '' if label == '' || label.start_with?('Translation missing:')
|
86
|
+
|
87
|
+
format("%<label>s\n\n", label:)
|
88
|
+
end
|
89
|
+
|
86
90
|
def file_name_from_title
|
87
|
-
title = @options[:title] ||
|
91
|
+
title = @options[:title] || I18n.t('fronde.bin.options.default_title')
|
88
92
|
# No title, nor a reliable file_path? Better abort
|
89
|
-
raise
|
93
|
+
raise I18n.t('fronde.error.bin.no_file') if title == ''
|
90
94
|
|
91
95
|
"#{Fronde::Slug.slug(title)}.org"
|
92
96
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
function __fronde_main_commands
|
2
|
+
echo {{ comcomp }}
|
3
|
+
end
|
4
|
+
|
5
|
+
function __fronde_no_command_yet
|
6
|
+
set -f cmd (__fish_print_cmd_args_without_options)
|
7
|
+
{%- for com in commands %}
|
8
|
+
{% unless forloop.first %}and {% endunless %}not contains {{ com }} $cmd
|
9
|
+
{%- endfor %}
|
10
|
+
end
|
11
|
+
|
12
|
+
complete -c fronde -e
|
13
|
+
complete -c fronde -f
|
14
|
+
complete -c fronde -x -n '__fronde_no_command_yet' -a '(__fronde_main_commands)'
|
15
|
+
complete -c fronde -n 'contains help (__fish_print_cmd_args_without_options)' -a '{{ commands | join ' ' }}'
|
16
|
+
complete -c fronde -n 'contains new (__fish_print_cmd_args_without_options)' -F
|
17
|
+
complete -c fronde -n 'contains open (__fish_print_cmd_args_without_options)' -F
|
18
|
+
{%- for compopt in details %}
|
19
|
+
complete -c fronde{% unless compopt.command == 'basic' %} -n 'contains {{ compopt.command }} (__fish_print_cmd_args_without_options)'{% endunless %} -s {{ compopt.short_no_dash }} -l {{ compopt.long_no_dash }}{% if compopt.keyword %} -r{% endif %}{% if compopt.choices %} -a '{{ compopt.choices | join ' ' }}'{% endif %} -d {% if compopt.help %}'{{ compopt.help }}'{% else %}{{ compopt.long_no_dash | capitalize }}{% endif %}
|
20
|
+
{%- endfor %}
|
data/lib/fronde/cli/helpers.rb
CHANGED
data/lib/fronde/cli/opt_parse.rb
CHANGED
@@ -10,13 +10,13 @@ module Fronde
|
|
10
10
|
'-a' => { long: 'author' },
|
11
11
|
'-f' => { long: 'force', boolean: true },
|
12
12
|
'-h' => { long: 'help', boolean: true, method: :on_tail,
|
13
|
-
help:
|
13
|
+
help: I18n.t('fronde.bin.options.help') },
|
14
14
|
'-l' => { long: 'lang', keyword: 'LOCALE' },
|
15
15
|
'-o' => { long: 'output', keyword: 'FORMAT', choices: %w[gemini html] },
|
16
16
|
'-t' => { long: 'title' },
|
17
17
|
'-v' => { long: 'verbose', boolean: true, method: :on_tail },
|
18
18
|
'-V' => { long: 'version', boolean: true, method: :on_tail,
|
19
|
-
help:
|
19
|
+
help: I18n.t('fronde.bin.options.version') }
|
20
20
|
}.freeze
|
21
21
|
|
22
22
|
# TODO: jekyll new [path] / jekyll build / jekyll clean / jekyll serve
|
@@ -28,13 +28,13 @@ module Fronde
|
|
28
28
|
FRONDE_COMMANDS = {
|
29
29
|
'new' => { opts: ['-a', '-l', '-o', '-t', '-v'], label: 'new <path>' },
|
30
30
|
'init' => { alias: 'new' },
|
31
|
-
'update' => {},
|
31
|
+
'update' => { opts: ['-v'] },
|
32
32
|
'config' => { alias: 'update' },
|
33
33
|
'preview' => {},
|
34
|
-
'open' => { opts: ['-a', '-l', '-t'
|
34
|
+
'open' => { opts: ['-a', '-l', '-t'], label: 'open <path>' },
|
35
35
|
'edit' => { alias: 'open' },
|
36
|
-
'build' => { opts: ['-f'] },
|
37
|
-
'publish' => {},
|
36
|
+
'build' => { opts: ['-f', '-v'] },
|
37
|
+
'publish' => { opts: ['-v'] },
|
38
38
|
'help' => {},
|
39
39
|
'basic' => { opts: ['-h', '-V'], label: '<command>' }
|
40
40
|
}.freeze
|
@@ -59,11 +59,10 @@ module Fronde
|
|
59
59
|
config = [short, long]
|
60
60
|
else
|
61
61
|
key = opt[:keyword] || opt[:long].upcase
|
62
|
-
config = [short, format('%<long>s %<key>s', long
|
62
|
+
config = [short, format('%<long>s %<key>s', long:, key:)]
|
63
63
|
end
|
64
|
-
config
|
65
|
-
config
|
66
|
-
config
|
64
|
+
config.push opt[:choices], opt[:help]
|
65
|
+
config.compact
|
67
66
|
end
|
68
67
|
|
69
68
|
# Returns the ~fronde~ help summary for a given command.
|
@@ -76,12 +75,10 @@ module Fronde
|
|
76
75
|
short, long = decorate_option(k)
|
77
76
|
opt = FRONDE_OPTIONS[k]
|
78
77
|
label = [short, long].join(', ')
|
79
|
-
line = [format(' %<opt>s', opt: label).ljust(30)]
|
80
|
-
help = opt[:help]
|
81
|
-
line << help if help
|
78
|
+
line = [format(' %<opt>s', opt: label).ljust(30), opt[:help]]
|
82
79
|
choices = opt[:choices]
|
83
80
|
line << "(#{choices.join(', ')})" if choices
|
84
|
-
line.join(' ')
|
81
|
+
line.compact.join(' ')
|
85
82
|
end.join("\n")
|
86
83
|
end
|
87
84
|
|
@@ -89,9 +86,9 @@ module Fronde
|
|
89
86
|
command_opts_doc = summarize_command(command)
|
90
87
|
return '' if command_opts_doc == ''
|
91
88
|
|
92
|
-
body = [
|
89
|
+
body = [I18n.t('fronde.bin.options.cmd_title'), command_opts_doc]
|
93
90
|
if command == 'basic'
|
94
|
-
body += ['',
|
91
|
+
body += ['', I18n.t('fronde.bin.commands.cmd_title'), list_commands]
|
95
92
|
end
|
96
93
|
body.join("\n")
|
97
94
|
end
|
@@ -105,9 +102,9 @@ module Fronde
|
|
105
102
|
|
106
103
|
line = [' ', cmd.ljust(10)]
|
107
104
|
if opt.has_key? :alias
|
108
|
-
line <<
|
105
|
+
line << I18n.t('fronde.bin.commands.alias', alias: opt[:alias])
|
109
106
|
else
|
110
|
-
line <<
|
107
|
+
line << I18n.t("fronde.bin.commands.#{cmd}")
|
111
108
|
end
|
112
109
|
line.join(' ')
|
113
110
|
end.join("\n")
|
data/lib/fronde/cli/throbber.rb
CHANGED
@@ -21,6 +21,7 @@ module Fronde
|
|
21
21
|
|
22
22
|
def initialize(thread, message)
|
23
23
|
@frames = select_frames
|
24
|
+
@term_width = terminal_width
|
24
25
|
@thread = thread
|
25
26
|
@thread.abort_on_exception = false
|
26
27
|
@thread.report_on_exception = false
|
@@ -28,23 +29,17 @@ module Fronde
|
|
28
29
|
end
|
29
30
|
|
30
31
|
def run
|
31
|
-
|
32
|
-
frames_len = @frames.length
|
33
|
-
current = 0
|
34
|
-
while @thread.alive?
|
35
|
-
sleep 0.1
|
36
|
-
frame = @frames[current % frames_len]
|
37
|
-
message = "#{@message} #{frame}"
|
38
|
-
print "#{message.ljust(term_width)}\r"
|
39
|
-
current += 1
|
40
|
-
end
|
41
|
-
@thread.join # Ensure any inner exception is re-raised
|
32
|
+
thread_loop
|
42
33
|
rescue RuntimeError => e
|
43
34
|
show_error
|
44
35
|
raise e
|
36
|
+
# :nocov: not sure how to emulate a Ctrl+c in rspec
|
37
|
+
rescue Interrupt => e
|
38
|
+
show_message Rainbow(I18n.t('fronde.bin.interrupted')).red, "\n"
|
39
|
+
raise e
|
40
|
+
# :nocov:
|
45
41
|
else
|
46
|
-
|
47
|
-
puts "#{@message} #{done}".ljust(term_width)
|
42
|
+
show_message Rainbow(I18n.t('fronde.bin.done')).green, "\n"
|
48
43
|
end
|
49
44
|
|
50
45
|
class << self
|
@@ -61,15 +56,32 @@ module Fronde
|
|
61
56
|
#
|
62
57
|
# @param thread [Thread] the long-running operation to decorate
|
63
58
|
# @param message [String] the message to display before the throbber
|
59
|
+
# @param verbose [Boolean] whether the decoration should be shown
|
60
|
+
# or skipped
|
64
61
|
# @return [void]
|
65
|
-
def run(thread, message)
|
66
|
-
|
67
|
-
|
62
|
+
def run(thread, message, verbose)
|
63
|
+
if verbose
|
64
|
+
thread.join
|
65
|
+
else
|
66
|
+
throbber = new(thread, message)
|
67
|
+
throbber.run
|
68
|
+
end
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|
71
72
|
private
|
72
73
|
|
74
|
+
def thread_loop
|
75
|
+
frames_len = @frames.length
|
76
|
+
current = 0
|
77
|
+
while @thread.alive?
|
78
|
+
sleep 0.1
|
79
|
+
show_message @frames[current % frames_len]
|
80
|
+
current += 1
|
81
|
+
end
|
82
|
+
@thread.join # Ensure any inner exception is re-raised
|
83
|
+
end
|
84
|
+
|
73
85
|
def terminal_width
|
74
86
|
# Not a tty. Docker?
|
75
87
|
return 0 unless system('test -t 0')
|
@@ -77,13 +89,18 @@ module Fronde
|
|
77
89
|
`stty size`.strip.split[1].to_i - 1
|
78
90
|
end
|
79
91
|
|
92
|
+
def show_message(suffix, end_of_line = "\r")
|
93
|
+
message = "#{@message} #{suffix}".ljust(@term_width)
|
94
|
+
print "#{message}#{end_of_line}"
|
95
|
+
end
|
96
|
+
|
80
97
|
def show_error
|
81
98
|
warn(
|
82
99
|
format(
|
83
100
|
"%<message>s %<label>s\n%<explanation>s",
|
84
101
|
message: @message,
|
85
|
-
label: Rainbow(
|
86
|
-
explanation: Rainbow(
|
102
|
+
label: Rainbow(I18n.t('fronde.error.bin.label')).bold.red,
|
103
|
+
explanation: Rainbow(I18n.t('fronde.error.bin.explanation')).bold
|
87
104
|
)
|
88
105
|
)
|
89
106
|
end
|
data/lib/fronde/cli.rb
CHANGED
@@ -21,12 +21,13 @@ module Fronde
|
|
21
21
|
|
22
22
|
if help_param_given?
|
23
23
|
return 2 if @options[:recover_from_error]
|
24
|
-
|
24
|
+
|
25
|
+
return true
|
25
26
|
end
|
26
27
|
|
27
28
|
init_rake if %w[build preview publish].include?(@command)
|
28
29
|
|
29
|
-
method = "fronde_#{@command}"
|
30
|
+
method = :"fronde_#{@command}"
|
30
31
|
return 2 if method_unknown?(method)
|
31
32
|
|
32
33
|
send method
|
@@ -50,7 +51,7 @@ module Fronde
|
|
50
51
|
def method_unknown?(method)
|
51
52
|
return false if respond_to?(method)
|
52
53
|
|
53
|
-
warn
|
54
|
+
warn I18n.t('fronde.error.bin.no_command')
|
54
55
|
fronde_help
|
55
56
|
true
|
56
57
|
end
|
@@ -4,8 +4,9 @@
|
|
4
4
|
(load-file (expand-file-name "htmlize.el" "{{ work_dir }}/lib"))
|
5
5
|
|
6
6
|
;; Current project options
|
7
|
-
(setq fronde
|
8
|
-
fronde
|
7
|
+
(setq fronde-version "{{ version }}"
|
8
|
+
fronde-current-work-dir "{{ work_dir }}"
|
9
|
+
fronde-domain "{{ domain }}"
|
9
10
|
user-mail-address "{{ author.email }}"
|
10
11
|
user-full-name "{{ author.name }}"
|
11
12
|
org-html-metadata-timestamp-format "{{ long_date_fmt }}"
|
@@ -34,87 +34,132 @@
|
|
34
34
|
|
35
35
|
;;; Function Declarations
|
36
36
|
|
37
|
-
(defvar fronde
|
38
|
-
"Version of the current fronde installation")
|
37
|
+
(defvar fronde-version ""
|
38
|
+
"Version of the current fronde installation.")
|
39
39
|
|
40
|
-
(defvar fronde
|
40
|
+
(defvar fronde-current-work-dir nil
|
41
41
|
"Location of the current fronde website base directory.")
|
42
42
|
|
43
|
-
(defvar fronde
|
44
|
-
"
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
43
|
+
(defvar fronde-domain ""
|
44
|
+
"Target domain with scheme of the current fronde installation.")
|
45
|
+
|
46
|
+
(defvar fronde-org-temp-dir nil
|
47
|
+
"Location of the local Org temporary directory.
|
48
|
+
This is where to place org timestamps and id locations.")
|
49
|
+
|
50
|
+
(defvar fronde--keywords-slugs-alist nil
|
51
|
+
"A list associating each keywords to its related slug.
|
52
|
+
|
53
|
+
Can be hydrated with `fronde--build-keywords-list'.")
|
54
|
+
|
55
|
+
(defun fronde--build-keywords-list ()
|
56
|
+
(let ((keywords-file (format "%s/keywords" fronde-org-temp-dir))
|
57
|
+
keywords-slugs)
|
58
|
+
(when (file-readable-p keywords-file)
|
59
|
+
(let ((content (with-temp-buffer
|
60
|
+
(insert-file-contents keywords-file)
|
61
|
+
(string-trim-right (buffer-string)))))
|
62
|
+
(mapcar
|
63
|
+
(lambda (line)
|
64
|
+
(push (split-string line "\x1f") keywords-slugs))
|
65
|
+
(split-string content "\x1e"))))
|
66
|
+
keywords-slugs))
|
67
|
+
|
68
|
+
(defun fronde--format-rich-keywords (info function)
|
69
|
+
"Extract keywords from INFO and apply FUNCTION on them.
|
70
|
+
FUNCTION is expected to format each keyword for a rich display for the
|
71
|
+
current export backend. FUNCTION must receive 3 arguments: the current
|
72
|
+
KEYWORD, its related SLUG and the current project BASE-URI."
|
73
|
+
(let ((base-uri (plist-get info :fronde-base-uri)))
|
74
|
+
(mapcar
|
75
|
+
(lambda (k)
|
76
|
+
(let ((slug (cadr (assoc k fronde--keywords-slugs-alist))))
|
77
|
+
(funcall function k slug base-uri)))
|
78
|
+
(split-string
|
79
|
+
(org-export-data (plist-get info :keywords) info)
|
80
|
+
",+ *"))))
|
81
|
+
|
82
|
+
(defun fronde--org-html-format-spec (upstream info)
|
83
|
+
"Advise UPSTREAM to return format specification for preamble and postamble.
|
49
84
|
INFO is a plist used as a communication channel."
|
50
85
|
(let ((output (funcall upstream info)))
|
51
86
|
(push `(?A . ,(format "<span class=\"author\">%s</span>"
|
52
87
|
(org-export-data (plist-get info :author) info)))
|
53
|
-
|
88
|
+
output)
|
54
89
|
(push `(?k . ,(org-export-data (plist-get info :keywords) info)) output)
|
55
|
-
(push `(?K . ,(format "<ul class=\"keywords-list\"
|
56
|
-
(
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
90
|
+
(push `(?K . ,(format "<ul class=\"keywords-list\">\n%s</ul>"
|
91
|
+
(apply #'concat
|
92
|
+
(fronde--format-rich-keywords
|
93
|
+
info
|
94
|
+
(lambda (k slug base-uri)
|
95
|
+
(format "<li class=\"keyword\"><a href=\"%stags/%s.html\">%s</a></li>\n"
|
96
|
+
base-uri slug k))))))
|
97
|
+
output)
|
61
98
|
(push `(?l . ,(org-export-data (plist-get info :language) info)) output)
|
62
|
-
(push `(?n . ,(format "Fronde %s" fronde
|
63
|
-
(push `(?N . ,(format "<a href=\"https://etienne.depar.is/fronde/\">Fronde</a> %s" fronde
|
99
|
+
(push `(?n . ,(format "Fronde %s" fronde-version)) output)
|
100
|
+
(push `(?N . ,(format "<a href=\"https://etienne.depar.is/fronde/\">Fronde</a> %s" fronde-version)) output)
|
64
101
|
(push `(?x . ,(org-export-data (plist-get info :description) info)) output)
|
65
102
|
(push `(?X . ,(format "<p>%s</p>"
|
66
103
|
(org-export-data (plist-get info :description) info)))
|
67
|
-
|
104
|
+
output)))
|
68
105
|
|
69
|
-
(defun fronde
|
70
|
-
"
|
106
|
+
(defun fronde--org-gmi-format-spec (upstream info)
|
107
|
+
"Advise UPSTREAM to return format specification for gemini postamble.
|
71
108
|
INFO is a plist used as a communication channel."
|
72
109
|
(let ((output (funcall upstream info)))
|
73
|
-
(push `(?
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
110
|
+
(push `(?K . ,(org-gmi--build-links-list
|
111
|
+
(fronde--format-rich-keywords
|
112
|
+
info
|
113
|
+
(lambda (k slug base-uri)
|
114
|
+
(list (format "%stags/%s.gmi" base-uri slug)
|
115
|
+
(format "🏷️ %s" k))))))
|
116
|
+
output)
|
117
|
+
(push `(?n . ,(format "Fronde %s" fronde-version)) output)))
|
118
|
+
|
119
|
+
(defun fronde--org-i18n-export (link description backend)
|
120
|
+
"Export the given i18n LINK with its DESCRIPTION for the current BACKEND."
|
121
|
+
(let* ((splitted-link (split-string link "::"))
|
78
122
|
(path (car splitted-link))
|
79
123
|
(desc (or description path))
|
80
124
|
(lang (cadr splitted-link)))
|
81
|
-
(pcase
|
125
|
+
(pcase backend
|
82
126
|
(`html (if lang
|
83
127
|
(format "<a href=\"%s\" hreflang=\"%s\">%s</a>"
|
84
128
|
path lang desc)
|
85
129
|
(format "<a href=\"%s\">%s</a>" path desc)))
|
86
|
-
(
|
87
|
-
(_ (format "%s (%s)" desc path)))))
|
130
|
+
(_ nil))))
|
88
131
|
|
89
|
-
(defun fronde
|
90
|
-
"Visit
|
91
|
-
(browse-url (car (split-string link "
|
132
|
+
(defun fronde--org-i18n-follow (link)
|
133
|
+
"Visit the given i18n LINK."
|
134
|
+
(browse-url (car (split-string link "::"))))
|
92
135
|
|
93
136
|
(org-link-set-parameters "i18n"
|
94
|
-
:export #'fronde
|
95
|
-
:follow #'fronde
|
137
|
+
:export #'fronde--org-i18n-export
|
138
|
+
:follow #'fronde--org-i18n-follow)
|
96
139
|
|
97
140
|
|
98
141
|
;;; Set configuration options
|
99
142
|
|
100
|
-
(setq fronde
|
101
|
-
|
102
|
-
org-
|
143
|
+
(setq fronde-org-temp-dir (expand-file-name "var/tmp" fronde-current-work-dir)
|
144
|
+
fronde--keywords-slugs-alist (fronde--build-keywords-list)
|
145
|
+
org-publish-timestamp-directory (expand-file-name "timestamps/" fronde-org-temp-dir)
|
146
|
+
org-id-locations-file (expand-file-name "id-locations.el" fronde-org-temp-dir)
|
103
147
|
make-backup-files nil
|
104
|
-
enable-local-variables
|
105
|
-
|
148
|
+
enable-dir-local-variables nil
|
149
|
+
enable-local-variables t ;; enforce default
|
150
|
+
org-confirm-babel-evaluate t ;; enforce default
|
106
151
|
org-export-with-broken-links t
|
107
152
|
org-html-doctype "html5"
|
108
153
|
org-html-html5-fancy t
|
109
154
|
org-html-htmlize-output-type 'css
|
110
155
|
org-html-text-markup-alist '((bold . "<strong>%s</strong>")
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
(advice-add 'org-html-format-spec :around #'fronde
|
117
|
-
(advice-add 'org-gmi--format-spec :around #'fronde
|
156
|
+
(code . "<code>%s</code>")
|
157
|
+
(italic . "<em>%s</em>")
|
158
|
+
(strike-through . "<del>%s</del>")
|
159
|
+
(underline . "<span class=\"underline\">%s</span>")
|
160
|
+
(verbatim . "<code>%s</code>")))
|
161
|
+
(advice-add 'org-html-format-spec :around #'fronde--org-html-format-spec)
|
162
|
+
(advice-add 'org-gmi--format-spec :around #'fronde--org-gmi-format-spec)
|
118
163
|
|
119
164
|
(provide 'ox-fronde)
|
120
165
|
|