fronde 0.4.0 → 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.
- checksums.yaml +4 -4
- data/lib/ext/r18n.rb +20 -0
- data/lib/ext/time.rb +6 -16
- data/lib/ext/time_no_time.rb +23 -0
- data/lib/fronde/cli/commands.rb +16 -12
- data/lib/fronde/cli/data/gitignore +0 -1
- data/lib/fronde/cli/opt_parse.rb +4 -7
- data/lib/fronde/cli/throbber.rb +24 -13
- data/lib/fronde/cli.rb +3 -2
- data/lib/fronde/config/data/org-config.el +3 -2
- data/lib/fronde/config/data/ox-fronde.el +72 -35
- 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 +0 -18
- data/lib/fronde/config/lisp.rb +13 -3
- data/lib/fronde/config.rb +40 -26
- data/lib/fronde/emacs.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 +2 -0
- data/lib/fronde/index.rb +12 -15
- data/lib/fronde/org/file.rb +39 -27
- data/lib/fronde/org/file_extracter.rb +15 -12
- data/lib/fronde/org.rb +11 -9
- data/lib/fronde/slug.rb +39 -12
- data/lib/fronde/source/gemini.rb +0 -5
- data/lib/fronde/source/html.rb +5 -5
- data/lib/fronde/source.rb +13 -8
- 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 +18 -11
- data/lib/fronde/version.rb +1 -1
- data/lib/tasks/org.rake +12 -17
- data/lib/tasks/site.rake +10 -13
- data/lib/tasks/sync.rake +13 -36
- data/lib/tasks/tags.rake +2 -2
- data/locales/en.yml +1 -0
- data/locales/fr.yml +1 -0
- metadata +49 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8691e788789cb725772213237a67731dc67ae77eeecc8d1d409e6779d94a22c8
|
4
|
+
data.tar.gz: d2f67191b421f902e1b41d7845fc07026843e227cfd3f70cdeff0f4d87e36b8e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8d3fa0a8bbfbcdecbf7a65ffc93b420876ddb27acf574a5a1a066b988ce2e039ff780b0a71bd6056f3a75b52072f4c37489135a6ead712e0a728f8385453de2
|
7
|
+
data.tar.gz: d2bd28e4fa15b156a83c61b79426f74e3e48534cfe483f92a03dd3d9a4a0675252843bb991bbb114f45421865b52e6b7f6f7dd500261cc0d8236063838f7baf4
|
data/lib/ext/r18n.rb
CHANGED
@@ -13,5 +13,25 @@ module R18nPatch
|
|
13
13
|
date: date_fmt, time: time_fmt
|
14
14
|
)
|
15
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
|
16
36
|
end
|
17
37
|
end
|
data/lib/ext/time.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'r18n'
|
4
|
+
using R18nPatch
|
5
|
+
|
3
6
|
# Monkey patch to add some helpers
|
4
7
|
module TimePatch
|
5
8
|
refine Time do
|
@@ -17,26 +20,13 @@ module TimePatch
|
|
17
20
|
"<time datetime=\"#{xmlschema}\">#{l18n_short_date_string}</time>"
|
18
21
|
end
|
19
22
|
|
20
|
-
def no_time=(value)
|
21
|
-
@no_time = value
|
22
|
-
end
|
23
|
-
|
24
23
|
# Returns the current Time instance as a localized long string.
|
25
24
|
#
|
26
|
-
# @param with_year [Boolean]
|
27
|
-
# year
|
25
|
+
# @param with_year [Boolean] whether or not the string must contain
|
26
|
+
# the year
|
28
27
|
# @return [String] the localized Time string representation
|
29
28
|
def l18n_long_date_string(with_year: true)
|
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)
|
29
|
+
R18n.t.long_date_string(self, with_year: with_year)
|
40
30
|
end
|
41
31
|
|
42
32
|
# Format the current Time as a HTML `time` tag showing a long date.
|
@@ -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
|
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,18 +71,22 @@ 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(R18n.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(R18n.t.fronde.bin.commands[cmd])
|
77
|
+
output << OptParse.help_command_body(cmd)
|
78
|
+
warn output.join
|
79
|
+
true
|
82
80
|
end
|
83
81
|
|
84
82
|
private
|
85
83
|
|
84
|
+
def format_label(label)
|
85
|
+
return '' if label == '' || label.is_a?(R18n::Untranslated)
|
86
|
+
|
87
|
+
format("%<label>s\n\n", label: label)
|
88
|
+
end
|
89
|
+
|
86
90
|
def file_name_from_title
|
87
91
|
title = @options[:title] || R18n.t.fronde.bin.options.default_title
|
88
92
|
# No title, nor a reliable file_path? Better abort
|
data/lib/fronde/cli/opt_parse.rb
CHANGED
@@ -61,9 +61,8 @@ module Fronde
|
|
61
61
|
key = opt[:keyword] || opt[:long].upcase
|
62
62
|
config = [short, format('%<long>s %<key>s', long: long, key: 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
|
|
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(R18n.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(R18n.t.fronde.bin.done).green, "\n"
|
48
43
|
end
|
49
44
|
|
50
45
|
class << self
|
@@ -70,6 +65,17 @@ module Fronde
|
|
70
65
|
|
71
66
|
private
|
72
67
|
|
68
|
+
def thread_loop
|
69
|
+
frames_len = @frames.length
|
70
|
+
current = 0
|
71
|
+
while @thread.alive?
|
72
|
+
sleep 0.1
|
73
|
+
show_message @frames[current % frames_len]
|
74
|
+
current += 1
|
75
|
+
end
|
76
|
+
@thread.join # Ensure any inner exception is re-raised
|
77
|
+
end
|
78
|
+
|
73
79
|
def terminal_width
|
74
80
|
# Not a tty. Docker?
|
75
81
|
return 0 unless system('test -t 0')
|
@@ -77,6 +83,11 @@ module Fronde
|
|
77
83
|
`stty size`.strip.split[1].to_i - 1
|
78
84
|
end
|
79
85
|
|
86
|
+
def show_message(suffix, end_of_line = "\r")
|
87
|
+
message = "#{@message} #{suffix}".ljust(@term_width)
|
88
|
+
print "#{message}#{end_of_line}"
|
89
|
+
end
|
90
|
+
|
80
91
|
def show_error
|
81
92
|
warn(
|
82
93
|
format(
|
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
|
@@ -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,72 +34,109 @@
|
|
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
|
+
(defun fronde--format-rich-keywords (info function)
|
51
|
+
"Extract keywords from INFO and apply FUNCTION on them.
|
52
|
+
FUNCTION is expected to format each keyword for a rich display for the
|
53
|
+
current export backend. FUNCTION must receive 3 arguments: the current
|
54
|
+
KEYWORD, its related SLUG and the current project BASE-URI."
|
55
|
+
(let ((base-uri (plist-get info :fronde-base-uri))
|
56
|
+
(current-path (symbol-file 'fronde--format-rich-keywords))
|
57
|
+
sluglib)
|
58
|
+
(when current-path
|
59
|
+
(setq sluglib
|
60
|
+
(expand-file-name
|
61
|
+
(format "%s../../slug" (file-name-directory current-path)))))
|
62
|
+
(mapcar
|
63
|
+
(lambda (k)
|
64
|
+
(let ((slug (if sluglib
|
65
|
+
(string-trim-right
|
66
|
+
(shell-command-to-string
|
67
|
+
(format "ruby -r %s -e \"puts Fronde::Slug.slug '%s'\""
|
68
|
+
(shell-quote-argument sluglib)
|
69
|
+
(shell-quote-argument k))))
|
70
|
+
k)))
|
71
|
+
(funcall function k slug base-uri)))
|
72
|
+
(split-string
|
73
|
+
(org-export-data (plist-get info :keywords) info)
|
74
|
+
",+ *"))))
|
75
|
+
|
76
|
+
(defun fronde--org-html-format-spec (upstream info)
|
77
|
+
"Advise UPSTREAM to return format specification for preamble and postamble.
|
49
78
|
INFO is a plist used as a communication channel."
|
50
79
|
(let ((output (funcall upstream info)))
|
51
80
|
(push `(?A . ,(format "<span class=\"author\">%s</span>"
|
52
81
|
(org-export-data (plist-get info :author) info)))
|
53
82
|
output)
|
54
83
|
(push `(?k . ,(org-export-data (plist-get info :keywords) info)) output)
|
55
|
-
(push `(?K . ,(format "<ul class=\"keywords-list\"
|
56
|
-
(
|
57
|
-
|
58
|
-
|
59
|
-
|
84
|
+
(push `(?K . ,(format "<ul class=\"keywords-list\">\n%s</ul>"
|
85
|
+
(apply #'concat
|
86
|
+
(fronde--format-rich-keywords
|
87
|
+
info
|
88
|
+
(lambda (k slug base-uri)
|
89
|
+
(format "<li class=\"keyword\"><a href=\"%stags/%s.html\">%s</a></li>\n"
|
90
|
+
base-uri slug k))))))
|
60
91
|
output)
|
61
92
|
(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
|
93
|
+
(push `(?n . ,(format "Fronde %s" fronde-version)) output)
|
94
|
+
(push `(?N . ,(format "<a href=\"https://etienne.depar.is/fronde/\">Fronde</a> %s" fronde-version)) output)
|
64
95
|
(push `(?x . ,(org-export-data (plist-get info :description) info)) output)
|
65
96
|
(push `(?X . ,(format "<p>%s</p>"
|
66
97
|
(org-export-data (plist-get info :description) info)))
|
67
98
|
output)))
|
68
99
|
|
69
|
-
(defun fronde
|
70
|
-
"
|
100
|
+
(defun fronde--org-gmi-format-spec (upstream info)
|
101
|
+
"Advise UPSTREAM to return format specification for gemini postamble.
|
71
102
|
INFO is a plist used as a communication channel."
|
72
103
|
(let ((output (funcall upstream info)))
|
73
|
-
(push `(?
|
104
|
+
(push `(?K . ,(org-gmi--build-links-list
|
105
|
+
(fronde--format-rich-keywords
|
106
|
+
info
|
107
|
+
(lambda (k slug base-uri)
|
108
|
+
(list (format "%stags/%s.gmi" base-uri slug)
|
109
|
+
(format "🏷️ %s" k))))))
|
110
|
+
output)
|
111
|
+
(push `(?n . ,(format "Fronde %s" fronde-version)) output)))
|
74
112
|
|
75
|
-
(defun fronde
|
76
|
-
"Export
|
77
|
-
(let* ((splitted-link (split-string link "
|
113
|
+
(defun fronde--org-i18n-export (link description backend)
|
114
|
+
"Export the given i18n LINK with its DESCRIPTION for the current BACKEND."
|
115
|
+
(let* ((splitted-link (split-string link "::"))
|
78
116
|
(path (car splitted-link))
|
79
117
|
(desc (or description path))
|
80
118
|
(lang (cadr splitted-link)))
|
81
|
-
(pcase
|
119
|
+
(pcase backend
|
82
120
|
(`html (if lang
|
83
121
|
(format "<a href=\"%s\" hreflang=\"%s\">%s</a>"
|
84
122
|
path lang desc)
|
85
123
|
(format "<a href=\"%s\">%s</a>" path desc)))
|
86
|
-
(
|
87
|
-
(_ (format "%s (%s)" desc path)))))
|
124
|
+
(_ nil))))
|
88
125
|
|
89
|
-
(defun fronde
|
90
|
-
"Visit
|
91
|
-
(browse-url (car (split-string link "
|
126
|
+
(defun fronde--org-i18n-follow (link)
|
127
|
+
"Visit the given i18n LINK."
|
128
|
+
(browse-url (car (split-string link "::"))))
|
92
129
|
|
93
130
|
(org-link-set-parameters "i18n"
|
94
|
-
:export #'fronde
|
95
|
-
:follow #'fronde
|
131
|
+
:export #'fronde--org-i18n-export
|
132
|
+
:follow #'fronde--org-i18n-follow)
|
96
133
|
|
97
134
|
|
98
135
|
;;; Set configuration options
|
99
136
|
|
100
|
-
(setq fronde
|
101
|
-
org-publish-timestamp-directory (expand-file-name "timestamps/" fronde
|
102
|
-
org-id-locations-file (expand-file-name "id-locations.el" fronde
|
137
|
+
(setq fronde-org-temp-dir (expand-file-name "var/tmp" fronde-current-work-dir)
|
138
|
+
org-publish-timestamp-directory (expand-file-name "timestamps/" fronde-org-temp-dir)
|
139
|
+
org-id-locations-file (expand-file-name "id-locations.el" fronde-org-temp-dir)
|
103
140
|
make-backup-files nil
|
104
141
|
enable-local-variables :all
|
105
142
|
org-confirm-babel-evaluate nil
|
@@ -113,8 +150,8 @@ INFO is a plist used as a communication channel."
|
|
113
150
|
(strike-through . "<del>%s</del>")
|
114
151
|
(underline . "<span class=\"underline\">%s</span>")
|
115
152
|
(verbatim . "<code>%s</code>")))
|
116
|
-
(advice-add 'org-html-format-spec :around #'fronde
|
117
|
-
(advice-add 'org-gmi--format-spec :around #'fronde
|
153
|
+
(advice-add 'org-html-format-spec :around #'fronde--org-html-format-spec)
|
154
|
+
(advice-add 'org-gmi--format-spec :around #'fronde--org-gmi-format-spec)
|
118
155
|
|
119
156
|
(provide 'ox-fronde)
|
120
157
|
|