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
data/lib/fronde/config.rb
CHANGED
@@ -39,16 +39,16 @@ module Fronde
|
|
39
39
|
|
40
40
|
def initialize
|
41
41
|
@default_settings = {
|
42
|
-
'author' =>
|
42
|
+
'author' => ENV['USER'] || '',
|
43
43
|
'domain' => '',
|
44
44
|
'lang' => Fronde::Config::Helpers.extract_lang_from_env('en'),
|
45
45
|
'html_public_folder' => 'public_html',
|
46
46
|
'gemini_public_folder' => 'public_gmi',
|
47
47
|
'templates' => [], 'theme' => 'default'
|
48
48
|
}.freeze
|
49
|
-
@org_version = @sources = nil
|
50
|
-
@config = load_settings
|
51
49
|
# Do not load sources now to avoid dependency loop on config
|
50
|
+
@sources = nil
|
51
|
+
@config = load_settings
|
52
52
|
end
|
53
53
|
|
54
54
|
include Fronde::Config::Lisp
|
@@ -93,7 +93,7 @@ module Fronde
|
|
93
93
|
def reset
|
94
94
|
# Reload config, taking default settings into account
|
95
95
|
@config = load_settings
|
96
|
-
@
|
96
|
+
@sources = nil
|
97
97
|
@sources = load_sources
|
98
98
|
end
|
99
99
|
|
@@ -109,7 +109,7 @@ module Fronde
|
|
109
109
|
# @return [Fronde::Config::Store] self
|
110
110
|
def load_test(config)
|
111
111
|
@config = @default_settings.merge config
|
112
|
-
@
|
112
|
+
@sources = nil
|
113
113
|
@sources = load_sources
|
114
114
|
self
|
115
115
|
end
|
@@ -148,26 +148,48 @@ module Fronde
|
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
151
|
+
def check_duplicate_and_warn(collection, source, type)
|
152
|
+
path = source['path']
|
153
|
+
return path unless collection[type].has_key?(path)
|
154
|
+
|
155
|
+
warn(
|
156
|
+
R18n.t.fronde.error.source.duplicate(
|
157
|
+
source: source['name'], type: type
|
158
|
+
)
|
159
|
+
)
|
160
|
+
end
|
161
|
+
|
151
162
|
def remove_duplicate(sources)
|
152
163
|
check_paths = {}
|
153
164
|
sources.each do |source|
|
154
165
|
type = source.type
|
155
166
|
check_paths[type] ||= {}
|
156
|
-
path = source
|
167
|
+
path = check_duplicate_and_warn check_paths, source, type
|
157
168
|
# Avoid duplicate
|
158
|
-
|
159
|
-
|
160
|
-
R18n.t.fronde.error.source.duplicate(
|
161
|
-
source: source['name'], type: type
|
162
|
-
)
|
163
|
-
)
|
164
|
-
next
|
165
|
-
end
|
169
|
+
next unless path
|
170
|
+
|
166
171
|
check_paths[type][path] = source
|
167
172
|
end
|
168
173
|
check_paths
|
169
174
|
end
|
170
175
|
|
176
|
+
def filter_possible_matchs(path, other_paths_list)
|
177
|
+
other_paths_list.select do |other_path|
|
178
|
+
path != other_path && other_path.start_with?(path)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def warn_on_existing_inclusion(type, other, possible_matchs, sources)
|
183
|
+
possible_matchs.each do |match|
|
184
|
+
warn(
|
185
|
+
R18n.t.fronde.error.source.inclusion(
|
186
|
+
source: sources[match]['title'],
|
187
|
+
other_source: other, type: type
|
188
|
+
)
|
189
|
+
)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
171
193
|
def remove_inclusion(check_paths)
|
172
194
|
check_paths.map do |type, sources_by_path|
|
173
195
|
skip_paths = []
|
@@ -183,21 +205,13 @@ module Fronde
|
|
183
205
|
next source unless source.recursive?
|
184
206
|
|
185
207
|
# Ensure that the current source does not embed another one
|
186
|
-
possible_matchs =
|
187
|
-
path != other_path && other_path.start_with?(path)
|
188
|
-
end
|
208
|
+
possible_matchs = filter_possible_matchs path, sorted_paths
|
189
209
|
next source if possible_matchs.empty?
|
190
210
|
|
191
211
|
skip_paths += possible_matchs
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
R18n.t.fronde.error.source.inclusion(
|
196
|
-
source: other_source['title'], type: type,
|
197
|
-
other_source: source['title']
|
198
|
-
)
|
199
|
-
)
|
200
|
-
end
|
212
|
+
warn_on_existing_inclusion(
|
213
|
+
type, source['title'], possible_matchs, sources_by_path
|
214
|
+
)
|
201
215
|
end
|
202
216
|
end.flatten
|
203
217
|
end
|
data/lib/fronde/emacs.rb
CHANGED
@@ -4,11 +4,16 @@
|
|
4
4
|
{% for index in indexes %}
|
5
5
|
* {{ index.title }}
|
6
6
|
:PROPERTIES:
|
7
|
-
|
7
|
+
{%- if project_type == 'html' %}
|
8
|
+
:HTML_CONTAINER_CLASS: index-tags{% endif %}
|
8
9
|
:UNNUMBERED: notoc
|
9
10
|
:END:
|
10
11
|
|
11
12
|
{% for tag in index.tags -%}
|
13
|
+
{%- if project_type == 'gemini' -%}
|
14
|
+
[[{{ domain }}{{ project_path }}tags/{{ tag.slug }}.gmi][{{ tag.title }} ({{ tag.weight }})]]
|
15
|
+
{%- else -%}
|
12
16
|
- [[{{ domain }}{{ project_path }}tags/{{ tag.slug }}.html][{{ tag.title }}]] ({{ tag.weight }})
|
17
|
+
{%- endif %}
|
13
18
|
{% endfor %}
|
14
19
|
{%- endfor -%}
|
@@ -1,22 +1,26 @@
|
|
1
1
|
#+title: {{ title }}
|
2
2
|
#+author: {{ author }}
|
3
3
|
#+language: {{ lang }}
|
4
|
-
{%-
|
4
|
+
{%- if project_type == 'html' and slug != '__HOME_PAGE__' %}
|
5
5
|
#+html_head_extra: <link rel="alternate" type="application/atom+xml" title="{{ title }}" href="{{ domain }}{{ project_path }}feeds/{{ slug }}.xml" />
|
6
|
-
{%
|
6
|
+
{% endif -%}
|
7
7
|
{%- assign last_year = 0 -%}
|
8
8
|
{% for article in entries %}
|
9
9
|
{% assign cur_year = article.timekey | slice: 0, 4 %}
|
10
10
|
{%- unless cur_year == last_year %}
|
11
11
|
* {% if cur_year == "0000" %}{{ unsorted }}{% else %}{{ cur_year }}{% endif %}
|
12
12
|
:PROPERTIES:
|
13
|
-
|
13
|
+
{%- if project_type == 'html' %}
|
14
|
+
:HTML_CONTAINER_CLASS: index-year{% endif %}
|
14
15
|
:UNNUMBERED: notoc
|
15
16
|
:END:
|
16
17
|
{% assign last_year = cur_year %}
|
17
18
|
{% endunless -%}
|
19
|
+
{%- if project_type == 'gemini' -%}
|
20
|
+
[[{{ article.url }}][{% if article.published != '' %}{{ article.published_gemini_index }} {% endif %}{{ article.title }}]]
|
21
|
+
{%- else -%}
|
18
22
|
- *[[{{ article.url }}][{{ article.title }}]]*
|
19
23
|
{%- if article.published != '' %} / {{ article.published }}{% endif -%}
|
20
24
|
{%- if article.excerpt != '' %} \\
|
21
|
-
{{ article.excerpt }}{% endif %}
|
25
|
+
{{ article.excerpt }}{% endif %}{% endif %}
|
22
26
|
{%- endfor %}
|
@@ -56,6 +56,7 @@ module Fronde
|
|
56
56
|
'title' => title,
|
57
57
|
'slug' => slug,
|
58
58
|
'project_path' => @project.public_absolute_path,
|
59
|
+
'project_type' => @project.type,
|
59
60
|
'domain' => Fronde::CONFIG.get('domain'),
|
60
61
|
'lang' => Fronde::CONFIG.get('lang'),
|
61
62
|
'author' => Fronde::CONFIG.get('author'),
|
@@ -81,6 +82,7 @@ module Fronde
|
|
81
82
|
'author' => Fronde::CONFIG.get('author'),
|
82
83
|
'domain' => Fronde::CONFIG.get('domain'),
|
83
84
|
'project_path' => @project.public_absolute_path,
|
85
|
+
'project_type' => @project.type,
|
84
86
|
'indexes' => indexes
|
85
87
|
)
|
86
88
|
end
|
data/lib/fronde/index.rb
CHANGED
@@ -30,26 +30,23 @@ module Fronde
|
|
30
30
|
|
31
31
|
def sort_by(kind)
|
32
32
|
accepted_values = %i[name weight]
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
@tags_names[tag] + " (#{@index[tag].length})"
|
39
|
-
end.reverse
|
33
|
+
unless accepted_values.include?(kind)
|
34
|
+
error_msg = R18n.t.fronde.error.index.wrong_sort_kind(
|
35
|
+
kind: kind, accepted_values: accepted_values.inspect
|
36
|
+
)
|
37
|
+
raise ArgumentError, error_msg
|
40
38
|
end
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
sort_tags_by_name_and_weight[:"by_#{kind}"].map do |tag|
|
40
|
+
@tags_names[tag] + " (#{@index[tag].length})"
|
41
|
+
end.reverse
|
42
|
+
# Reverse in order to have most important or A near next prompt
|
43
|
+
# and avoid to scroll to find the beginning of the list.
|
45
44
|
end
|
46
45
|
|
47
46
|
class << self
|
48
|
-
def
|
47
|
+
def all_blog_index(&block)
|
49
48
|
all_blogs = CONFIG.sources.filter_map do |project|
|
50
|
-
|
51
|
-
|
52
|
-
Index.new(project)
|
49
|
+
Index.new(project) if project.blog?
|
53
50
|
end
|
54
51
|
return all_blogs unless block
|
55
52
|
|
data/lib/fronde/org/file.rb
CHANGED
@@ -118,41 +118,53 @@ module Fronde
|
|
118
118
|
#
|
119
119
|
# *** Format:
|
120
120
|
#
|
121
|
-
# - %a :: the raw author name
|
121
|
+
# - %a :: the raw author name.
|
122
122
|
# - %A :: the HTML rendering of the author name, equivalent to
|
123
|
-
# ~<span class="author">%a</span
|
123
|
+
# ~<span class="author">%a</span>~.
|
124
124
|
# - %d :: the ~:short~ date HTML representation, equivalent
|
125
|
-
# to ~<time datetime="%I">%i</time
|
126
|
-
# - %D :: the ~:full~ date and time HTML representation
|
127
|
-
# - %
|
128
|
-
#
|
129
|
-
# - %
|
130
|
-
#
|
131
|
-
# - %
|
125
|
+
# to ~<time datetime="%I">%i</time>~.
|
126
|
+
# - %D :: the ~:full~ date and time HTML representation.
|
127
|
+
# - %F :: the ~link~ HTML tag for the main Atom feed of the
|
128
|
+
# current file source.
|
129
|
+
# - %h :: the declared host/domain name, taken from the
|
130
|
+
# {Fronde::Config#settings}.
|
131
|
+
# - %i :: the raw ~:short~ date and time.
|
132
|
+
# - %I :: the raw ~:iso8601~ date and time.
|
133
|
+
# - %k :: the document keywords separated by commas.
|
134
|
+
# - %K :: the HTML list rendering of the keywords.
|
135
|
+
# - %l :: the lang of the document.
|
132
136
|
# - %L :: the license information, taken from the
|
133
|
-
# {Fronde::Config#settings}
|
134
|
-
# - %n :: the
|
135
|
-
# - %N :: the
|
136
|
-
# home on the name
|
137
|
-
# - %
|
138
|
-
# - %
|
139
|
-
# - %
|
140
|
-
# - %
|
137
|
+
# {Fronde::Config#settings}.
|
138
|
+
# - %n :: the fronde name and version.
|
139
|
+
# - %N :: the fronde name and version with a link to the project
|
140
|
+
# home on the name.
|
141
|
+
# - %o :: the theme name (~o~ as in Outfit) of the current file source.
|
142
|
+
# - %s :: the subtitle of the document (from ~#+subtitle:~).
|
143
|
+
# - %t :: the title of the document (from ~#+title:~).
|
144
|
+
# - %u :: the URL to the related published HTML document.
|
145
|
+
# - %x :: the raw description (~x~ as in eXcerpt) of the document
|
146
|
+
# (from ~#+description:~).
|
141
147
|
# - %X :: the description, enclosed in an HTML ~p~ tag, equivalent
|
142
|
-
# to ~<p>%x</p
|
148
|
+
# to ~<p>%x</p>~.
|
143
149
|
#
|
144
150
|
# @example
|
145
151
|
# org_file.format("Article written by %a the %d")
|
146
152
|
# => "Article written by Alice Smith the Wednesday 3rd July"
|
147
153
|
#
|
148
154
|
# @return [String] the given ~string~ after replacement occurs
|
149
|
-
# rubocop:disable Metrics/MethodLength
|
150
155
|
# rubocop:disable Layout/LineLength
|
151
156
|
def format(string)
|
157
|
+
project_data = @project.to_h
|
158
|
+
# NOTE: The following keycode are reserved by Org itself:
|
159
|
+
# %a (author), %c (creator), %C (input-file), %d (date),
|
160
|
+
# %e (email), %s (subtitle), %t (title), %T (timestamp),
|
161
|
+
# %v (html validation link)
|
152
162
|
string.gsub('%a', @data[:author])
|
153
163
|
.gsub('%A', "<span class=\"author\">#{@data[:author]}</span>")
|
154
164
|
.gsub('%d', @data[:date].l18n_short_date_html)
|
155
165
|
.gsub('%D', @data[:date].l18n_long_date_html)
|
166
|
+
.gsub('%F', project_data['atom_feed'] || '')
|
167
|
+
.gsub('%h', project_data['domain'] || '')
|
156
168
|
.gsub('%i', @data[:date].l18n_short_date_string)
|
157
169
|
.gsub('%I', @data[:date].xmlschema)
|
158
170
|
.gsub('%k', @data[:keywords].join(', '))
|
@@ -161,6 +173,7 @@ module Fronde
|
|
161
173
|
.gsub('%L', Fronde::CONFIG.get('license', '').gsub(/\s+/, ' ').strip)
|
162
174
|
.gsub('%n', "Fronde #{Fronde::VERSION}")
|
163
175
|
.gsub('%N', "<a href=\"https://git.umaneti.net/fronde/about/\">Fronde</a> #{Fronde::VERSION}")
|
176
|
+
.gsub('%o', project_data['theme'] || '')
|
164
177
|
.gsub('%s', @data[:subtitle])
|
165
178
|
.gsub('%t', @data[:title])
|
166
179
|
.gsub('%u', @data[:url] || '')
|
@@ -168,7 +181,6 @@ module Fronde
|
|
168
181
|
.gsub('%X', "<p>#{@data[:excerpt]}</p>")
|
169
182
|
end
|
170
183
|
# rubocop:enable Layout/LineLength
|
171
|
-
# rubocop:enable Metrics/MethodLength
|
172
184
|
|
173
185
|
# Writes the current Org::File content to the underlying file.
|
174
186
|
#
|
@@ -215,6 +227,7 @@ module Fronde
|
|
215
227
|
data['published_body'] = extract_published_body
|
216
228
|
pub_date = @data[:date]
|
217
229
|
data['published'] = pub_date.l18n_long_date_string(with_year: false)
|
230
|
+
data['published_gemini_index'] = pub_date.strftime('%Y-%m-%d')
|
218
231
|
data['published_xml'] = pub_date.xmlschema
|
219
232
|
data['updated_xml'] = @data[:updated]&.xmlschema
|
220
233
|
data
|
@@ -228,8 +241,10 @@ module Fronde
|
|
228
241
|
else
|
229
242
|
source = find_source_for_publication_file
|
230
243
|
end
|
231
|
-
|
232
|
-
|
244
|
+
return source if source
|
245
|
+
|
246
|
+
short_file = @file.sub(/^#{Dir.pwd}/, '.')
|
247
|
+
warn R18n.t.fronde.error.org_file.no_project(file: short_file)
|
233
248
|
end
|
234
249
|
|
235
250
|
def find_source_for_org_file
|
@@ -250,20 +265,17 @@ module Fronde
|
|
250
265
|
def init_empty_file
|
251
266
|
@data = {
|
252
267
|
title: @options[:title] || '', subtitle: '', excerpt: '',
|
253
|
-
date: Time.now,
|
254
268
|
author: @options[:author] || Fronde::CONFIG.get('author'),
|
255
|
-
keywords: [],
|
256
269
|
lang: @options[:lang] || Fronde::CONFIG.get('lang'),
|
257
|
-
pub_file: nil, url: nil
|
270
|
+
date: Time.now, keywords: [], pub_file: nil, url: nil
|
258
271
|
}
|
259
|
-
body = @options[:content] || ''
|
260
272
|
@data[:content] = @options[:raw_content] || <<~ORG
|
261
273
|
#+title: #{@data[:title]}
|
262
274
|
#+date: <#{@data[:date].strftime('%Y-%m-%d %a. %H:%M:%S')}>
|
263
275
|
#+author: #{@data[:author]}
|
264
276
|
#+language: #{@data[:lang]}
|
265
277
|
|
266
|
-
#{
|
278
|
+
#{@options[:content]}
|
267
279
|
ORG
|
268
280
|
end
|
269
281
|
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
using TimePatch
|
4
4
|
|
5
|
+
require_relative '../../ext/time_no_time'
|
6
|
+
|
5
7
|
module Fronde
|
6
8
|
module Org
|
7
9
|
# This module holds extracter methods for the {Fronde::Org::File}
|
@@ -14,7 +16,7 @@ module Fronde
|
|
14
16
|
def extract_data
|
15
17
|
@data = { content: ::File.read(@file), pub_file: nil, url: nil }
|
16
18
|
%i[title subtitle date author keywords lang excerpt].each do |param|
|
17
|
-
@data[param] = send("extract_#{param}"
|
19
|
+
@data[param] = send(:"extract_#{param}")
|
18
20
|
end
|
19
21
|
return unless @project
|
20
22
|
|
@@ -29,22 +31,19 @@ module Fronde
|
|
29
31
|
match = daterx.match(@data[:content])
|
30
32
|
return NilTime.new if match.nil?
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
date = Time.strptime("#{match[1]} #{time}", '%Y-%m-%d %H:%M:%S')
|
39
|
-
date.no_time = notime
|
40
|
-
date
|
34
|
+
return TimeNoTime.parse_no_time(match[1]) if match[2].nil?
|
35
|
+
|
36
|
+
Time.strptime(
|
37
|
+
"#{match[1]} #{match[2]}:#{match[3] || '00'}",
|
38
|
+
'%Y-%m-%d %H:%M:%S'
|
39
|
+
)
|
41
40
|
end
|
42
41
|
|
43
42
|
def extract_title
|
44
43
|
match = /^#\+title:(.+)$/i.match(@data[:content])
|
45
44
|
if match.nil?
|
46
45
|
# Avoid to leak absolute path
|
47
|
-
project_relative_path = @file.sub
|
46
|
+
project_relative_path = @file.sub %r{^#{Dir.pwd}/}, ''
|
48
47
|
return project_relative_path
|
49
48
|
end
|
50
49
|
match[1].strip
|
@@ -81,13 +80,17 @@ module Fronde
|
|
81
80
|
# Always return something, even when not published yet
|
82
81
|
return @data[:excerpt] unless pub_file && @project
|
83
82
|
|
84
|
-
project_type = @project
|
83
|
+
project_type = @project.type
|
85
84
|
pub_folder = Fronde::CONFIG.get("#{project_type}_public_folder")
|
86
85
|
file_name = pub_folder + pub_file
|
87
86
|
return @data[:excerpt] unless ::File.exist? file_name
|
88
87
|
|
89
88
|
return ::File.read(file_name) if project_type == 'gemini'
|
90
89
|
|
90
|
+
read_html_body file_name
|
91
|
+
end
|
92
|
+
|
93
|
+
def read_html_body(file_name)
|
91
94
|
dom = ::File.open(file_name, 'r') { |file| Nokogiri::HTML file }
|
92
95
|
body = dom.css('div#content')
|
93
96
|
body.css('header').unlink # Remove the main title
|
data/lib/fronde/org.rb
CHANGED
@@ -55,23 +55,25 @@ module Fronde
|
|
55
55
|
# @param destination [String] where to save the org-mode tarball
|
56
56
|
# @return [String] the downloaded org-mode version
|
57
57
|
def download(destination = 'var/tmp')
|
58
|
-
# Remove version number in dest file to allow easy rake file
|
59
|
-
# task naming
|
60
|
-
dest_file = ::File.expand_path('org.tar.gz', destination)
|
61
58
|
org_last_version = last_version(force: false, cookie_dir: destination)
|
62
59
|
tarball = "org-mode-release_#{org_last_version}.tar.gz"
|
63
60
|
uri = URI("https://git.savannah.gnu.org/cgit/emacs/org-mode.git/snapshot/#{tarball}")
|
64
61
|
# Will crash on purpose if anything goes wrong
|
65
62
|
Net::HTTP.start(uri.host) do |http|
|
66
|
-
|
63
|
+
fetch_org_tarball http, Net::HTTP::Get.new(uri), destination
|
64
|
+
end
|
65
|
+
org_last_version
|
66
|
+
end
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
def fetch_org_tarball(http, request, destination)
|
69
|
+
# Remove version number in dest file to allow easy rake file
|
70
|
+
# task naming
|
71
|
+
dest_file = ::File.expand_path('org.tar.gz', destination)
|
72
|
+
http.request request do |response|
|
73
|
+
::File.open(dest_file, 'w') do |io|
|
74
|
+
response.read_body { |chunk| io.write chunk }
|
72
75
|
end
|
73
76
|
end
|
74
|
-
org_last_version
|
75
77
|
end
|
76
78
|
|
77
79
|
def make_org_cmd(org_dir, target, verbose: false)
|
data/lib/fronde/slug.rb
CHANGED
@@ -5,23 +5,50 @@ module Fronde
|
|
5
5
|
module Slug
|
6
6
|
class << self
|
7
7
|
def slug(title)
|
8
|
-
title.downcase
|
8
|
+
title.downcase
|
9
9
|
.encode('ascii', fallback: ->(k) { translit(k) })
|
10
|
-
.
|
10
|
+
.encode('utf-8') # Convert back to utf-8 string
|
11
|
+
.gsub(/[^\w-]/, '-')
|
12
|
+
.squeeze('-')
|
13
|
+
.delete_suffix('-')
|
11
14
|
end
|
12
15
|
|
16
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
17
|
+
# rubocop:disable Metrics/MethodLength
|
13
18
|
def translit(char)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
'
|
19
|
+
case char
|
20
|
+
when 'á', 'à', 'â', 'ä', 'ǎ', 'ã', 'å'
|
21
|
+
'a'
|
22
|
+
when 'é', 'è', 'ê', 'ë', 'ě', 'ẽ', '€'
|
23
|
+
'e'
|
24
|
+
when 'í', 'ì', 'î', 'ï', 'ǐ', 'ĩ'
|
25
|
+
'i'
|
26
|
+
when 'ó', 'ò', 'ô', 'ö', 'ǒ', 'õ', 'ø'
|
27
|
+
'o'
|
28
|
+
when 'ú', 'ù', 'û', 'ü', 'ǔ', 'ũ'
|
29
|
+
'u'
|
30
|
+
when 'ý', 'ỳ', 'ŷ', 'ÿ', 'ỹ'
|
31
|
+
'y'
|
32
|
+
when 'ç', '©', '🄯'
|
33
|
+
'c'
|
34
|
+
when 'ñ'
|
35
|
+
'n'
|
36
|
+
when 'ß'
|
37
|
+
'ss'
|
38
|
+
when 'œ'
|
39
|
+
'oe'
|
40
|
+
when 'æ'
|
41
|
+
'ae'
|
42
|
+
when '®'
|
43
|
+
'r'
|
44
|
+
when '™'
|
45
|
+
'tm'
|
46
|
+
else
|
47
|
+
'-'
|
48
|
+
end
|
24
49
|
end
|
50
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
51
|
+
# rubocop:enable Metrics/MethodLength
|
25
52
|
end
|
26
53
|
end
|
27
54
|
end
|
data/lib/fronde/source/gemini.rb
CHANGED
data/lib/fronde/source/html.rb
CHANGED
@@ -40,12 +40,12 @@ module Fronde
|
|
40
40
|
super
|
41
41
|
end
|
42
42
|
|
43
|
-
def org_default_options
|
43
|
+
def org_default_options
|
44
44
|
defaults = {
|
45
45
|
'publishing-function' => 'org-html-publish-to-html',
|
46
46
|
'html-head-include-default-style' => 't',
|
47
47
|
'html-head-include-scripts' => 't',
|
48
|
-
'html-head' => '
|
48
|
+
'html-head' => '%F',
|
49
49
|
'html-postamble' => Html.org_default_postamble
|
50
50
|
}
|
51
51
|
return defaults if @config['theme'] == 'default'
|
@@ -55,10 +55,10 @@ module Fronde
|
|
55
55
|
'html-head-include-scripts' => 'nil',
|
56
56
|
'html-head' => <<~HTMLHEAD
|
57
57
|
<link rel="stylesheet" type="text/css" media="screen"
|
58
|
-
href="
|
58
|
+
href="%h/assets/%o/css/style.css">
|
59
59
|
<link rel="stylesheet" type="text/css" media="screen"
|
60
|
-
href="
|
61
|
-
|
60
|
+
href="%h/assets/%o/css/htmlize.css">
|
61
|
+
%F
|
62
62
|
HTMLHEAD
|
63
63
|
)
|
64
64
|
end
|
data/lib/fronde/source.rb
CHANGED
@@ -147,7 +147,7 @@ module Fronde
|
|
147
147
|
|
148
148
|
def clean_config
|
149
149
|
fill_in_specific_config
|
150
|
-
@config['name'] ||= @config['path'].sub(
|
150
|
+
@config['name'] ||= @config['path'].sub(%r{^[.~]*/}, '').tr('/.', '-')
|
151
151
|
@config['title'] ||= @config['path']
|
152
152
|
@config['target'] ||= File.basename(@config['path']).delete_prefix '.'
|
153
153
|
@config['target'] = '' if @config['target'] == '.'
|
@@ -168,12 +168,16 @@ module Fronde
|
|
168
168
|
end
|
169
169
|
|
170
170
|
def render_heading
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
171
|
+
%w[head head-extra preamble postamble].each do |kind|
|
172
|
+
heading_key = "#{@config['type']}-#{kind}"
|
173
|
+
heading = @config.dig 'org-options', heading_key
|
174
|
+
next unless heading
|
175
|
+
|
176
|
+
@config['org-options'][heading_key] =
|
177
|
+
heading.gsub('%F', @config['atom_feed'])
|
178
|
+
.gsub('%h', @config['domain'])
|
179
|
+
.gsub('%o', @config['theme'])
|
180
|
+
end
|
177
181
|
end
|
178
182
|
|
179
183
|
def org_project_config
|
@@ -181,7 +185,8 @@ module Fronde
|
|
181
185
|
'base-directory' => @config['path'],
|
182
186
|
'base-extension' => 'org',
|
183
187
|
'publishing-directory' => publication_path,
|
184
|
-
'recursive' => @config['recursive']
|
188
|
+
'recursive' => @config['recursive'],
|
189
|
+
'fronde-base-uri' => "#{@config['domain']}#{public_absolute_path}"
|
185
190
|
}.merge(@config['org-options'])
|
186
191
|
exclude = @config['exclude']
|
187
192
|
attributes['exclude'] = exclude if exclude
|