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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ext/r18n.rb +20 -0
  3. data/lib/ext/time.rb +6 -16
  4. data/lib/ext/time_no_time.rb +23 -0
  5. data/lib/fronde/cli/commands.rb +16 -12
  6. data/lib/fronde/cli/data/gitignore +0 -1
  7. data/lib/fronde/cli/opt_parse.rb +4 -7
  8. data/lib/fronde/cli/throbber.rb +24 -13
  9. data/lib/fronde/cli.rb +3 -2
  10. data/lib/fronde/config/data/org-config.el +3 -2
  11. data/lib/fronde/config/data/ox-fronde.el +72 -35
  12. data/lib/fronde/config/data/themes/umaneti/css/htmlize.css +364 -0
  13. data/lib/fronde/config/data/themes/umaneti/css/style.css +250 -0
  14. data/lib/fronde/config/data/themes/umaneti/img/bottom.png +0 -0
  15. data/lib/fronde/config/data/themes/umaneti/img/content.png +0 -0
  16. data/lib/fronde/config/data/themes/umaneti/img/tic.png +0 -0
  17. data/lib/fronde/config/data/themes/umaneti/img/top.png +0 -0
  18. data/lib/fronde/config/helpers.rb +0 -18
  19. data/lib/fronde/config/lisp.rb +13 -3
  20. data/lib/fronde/config.rb +40 -26
  21. data/lib/fronde/emacs.rb +1 -1
  22. data/lib/fronde/index/data/all_tags.org +6 -1
  23. data/lib/fronde/index/data/template.org +8 -4
  24. data/lib/fronde/index/org_generator.rb +2 -0
  25. data/lib/fronde/index.rb +12 -15
  26. data/lib/fronde/org/file.rb +39 -27
  27. data/lib/fronde/org/file_extracter.rb +15 -12
  28. data/lib/fronde/org.rb +11 -9
  29. data/lib/fronde/slug.rb +39 -12
  30. data/lib/fronde/source/gemini.rb +0 -5
  31. data/lib/fronde/source/html.rb +5 -5
  32. data/lib/fronde/source.rb +13 -8
  33. data/lib/fronde/sync/neocities.rb +220 -0
  34. data/lib/fronde/sync/rsync.rb +46 -0
  35. data/lib/fronde/sync.rb +32 -0
  36. data/lib/fronde/templater.rb +18 -11
  37. data/lib/fronde/version.rb +1 -1
  38. data/lib/tasks/org.rake +12 -17
  39. data/lib/tasks/site.rake +10 -13
  40. data/lib/tasks/sync.rake +13 -36
  41. data/lib/tasks/tags.rake +2 -2
  42. data/locales/en.yml +1 -0
  43. data/locales/fr.yml +1 -0
  44. metadata +49 -10
@@ -0,0 +1,364 @@
1
+ /**
2
+ * This file has been generated with the `org-html-htmlize-generate-css'
3
+ * command of org mode, with the Dracula theme enabled.
4
+ * The Dracula theme is released under an MIT license and thus the
5
+ * following is also released under this license.
6
+ * See https://github.com/dracula/emacs for details.
7
+ */
8
+
9
+ pre.src {
10
+ color: #f8f8f2;
11
+ background-color: #282a36;
12
+ padding: .6em 1em;
13
+ padding-top: .6em !important; /* Override default style */
14
+ overflow: visible !important; /* Fix default style */
15
+ }
16
+ pre.src a:hover {
17
+ text-decoration: underline;
18
+ }
19
+ pre.src::before {
20
+ color: #282a36;
21
+ border-color: #282a36;
22
+ }
23
+ .org-src-container {
24
+ overflow: auto;
25
+ }
26
+ .org-src-container label.org-src-name {
27
+ display: block;
28
+ text-align: center;
29
+ font-size: .9em;
30
+ color: #666666;
31
+ }
32
+ .org-src-container label.org-src-name+pre.src {
33
+ margin-top: .5em;
34
+ }
35
+
36
+ .org-bold {
37
+ /* bold */
38
+ font-weight: bold;
39
+ }
40
+ .org-bold-italic {
41
+ /* bold-italic */
42
+ font-weight: bold;
43
+ font-style: italic;
44
+ }
45
+
46
+ .org-builtin {
47
+ /* font-lock-builtin-face */
48
+ color: #ffb86c;
49
+ }
50
+ .org-button {
51
+ /* button */
52
+ color: #8be9fd;
53
+ text-decoration: underline;
54
+ }
55
+ .org-comment {
56
+ /* font-lock-comment-face */
57
+ color: #6272a4;
58
+ }
59
+ .org-comment-delimiter {
60
+ /* font-lock-comment-delimiter-face */
61
+ color: #6272a4;
62
+ }
63
+ .org-constant {
64
+ /* font-lock-constant-face */
65
+ color: #8be9fd;
66
+ }
67
+ .org-cursor {
68
+ /* cursor */
69
+ background-color: #8be9fd;
70
+ }
71
+ .org-doc {
72
+ /* font-lock-doc-face */
73
+ color: #6272a4;
74
+ }
75
+ .org-error {
76
+ /* error */
77
+ color: #ffc0cb;
78
+ font-weight: bold;
79
+ }
80
+ .org-escape-glyph {
81
+ /* escape-glyph */
82
+ color: #00ffff;
83
+ }
84
+ .org-file-name-shadow {
85
+ /* file-name-shadow */
86
+ color: #b3b3b3;
87
+ }
88
+ .org-fringe {
89
+ /* fringe */
90
+ color: #b6b6b2;
91
+ background-color: #282a36;
92
+ }
93
+ .org-function-name {
94
+ /* font-lock-function-name-face */
95
+ color: #50fa7b;
96
+ font-weight: bold;
97
+ }
98
+ .org-glyphless-char {
99
+ /* glyphless-char */
100
+ font-size: 60%;
101
+ }
102
+ .org-header-line {
103
+ /* header-line */
104
+ background-color: #282a36;
105
+ }
106
+ .org-header-line-highlight {
107
+ /* header-line-highlight */
108
+ color: #ccccc7;
109
+ background-color: #464752;
110
+ }
111
+ .org-help-argument-name {
112
+ /* help-argument-name */
113
+ font-style: italic;
114
+ }
115
+ .org-highlight {
116
+ /* highlight */
117
+ color: #ccccc7;
118
+ background-color: #464752;
119
+ }
120
+ .org-hl-line {
121
+ /* hl-line */
122
+ background-color: #44475a;
123
+ }
124
+ .org-homoglyph {
125
+ /* homoglyph */
126
+ color: #00ffff;
127
+ }
128
+ .org-italic {
129
+ /* italic */
130
+ font-style: italic;
131
+ }
132
+ .org-keyword {
133
+ /* font-lock-keyword-face */
134
+ color: #ff79c6;
135
+ font-weight: bold;
136
+ }
137
+ .org-lazy-highlight {
138
+ /* lazy-highlight */
139
+ color: #e2e2dc;
140
+ background-color: #464752;
141
+ }
142
+ .org-line-number-current-line {
143
+ /* line-number-current-line */
144
+ color: #b3b3b3;
145
+ background-color: #282a36;
146
+ }
147
+ .org-link {
148
+ /* link */
149
+ color: #8be9fd;
150
+ text-decoration: underline;
151
+ }
152
+ .org-link-visited {
153
+ /* link-visited */
154
+ color: #ee82ee;
155
+ text-decoration: underline;
156
+ }
157
+ .org-linum {
158
+ /* linum */
159
+ color: #565761;
160
+ background-color: #282a36;
161
+ font-style: italic;
162
+ }
163
+ .org-match {
164
+ /* match */
165
+ background-color: #3a5fcd;
166
+ }
167
+ .org-negation-char {
168
+ /* font-lock-negation-char-face */
169
+ color: #8be9fd;
170
+ }
171
+ .org-next-error {
172
+ /* next-error */
173
+ color: #282a36;
174
+ background-color: #f1fa8c;
175
+ }
176
+ .org-nobreak-hyphen {
177
+ /* nobreak-hyphen */
178
+ color: #00ffff;
179
+ }
180
+ .org-nobreak-space {
181
+ /* nobreak-space */
182
+ color: #00ffff;
183
+ text-decoration: underline;
184
+ }
185
+ .org-outline-1 {
186
+ /* outline-1 */
187
+ color: #50fa7b;
188
+ }
189
+ .org-outline-2 {
190
+ /* outline-2 */
191
+ color: #bd93f9;
192
+ }
193
+ .org-outline-3 {
194
+ /* outline-3 */
195
+ color: #8be9fd;
196
+ }
197
+ .org-outline-4 {
198
+ /* outline-4 */
199
+ color: #ffb86c;
200
+ }
201
+ .org-outline-5 {
202
+ /* outline-5 */
203
+ color: #ffb86c;
204
+ }
205
+ .org-outline-6 {
206
+ /* outline-6 */
207
+ color: #0189cc;
208
+ }
209
+ .org-outline-7 {
210
+ /* outline-7 */
211
+ color: #ffb86c;
212
+ }
213
+ .org-outline-8 {
214
+ /* outline-8 */
215
+ color: #f1fa8c;
216
+ }
217
+ .org-page-break-lines {
218
+ /* page-break-lines */
219
+ color: #6272a4;
220
+ }
221
+ .org-preprocessor {
222
+ /* font-lock-preprocessor-face */
223
+ color: #ffb86c;
224
+ }
225
+ .org-py-builtins {
226
+ /* py-builtins-face */
227
+ color: #ffb86c;
228
+ }
229
+ .org-py-class-name {
230
+ /* py-class-name-face */
231
+ color: #bd93f9;
232
+ }
233
+ .org-py-decorators {
234
+ /* py-decorators-face */
235
+ color: #ff79c6;
236
+ font-weight: bold;
237
+ }
238
+ .org-py-def-class {
239
+ /* py-def-class-face */
240
+ color: #ff79c6;
241
+ font-weight: bold;
242
+ }
243
+ .org-py-exception-name {
244
+ /* py-exception-name-face */
245
+ color: #ffb86c;
246
+ }
247
+ .org-py-import-from {
248
+ /* py-import-from-face */
249
+ color: #ff79c6;
250
+ font-weight: bold;
251
+ }
252
+ .org-py-number {
253
+ /* py-number-face */
254
+ color: #f8f8f2;
255
+ background-color: #282a36;
256
+ }
257
+ .org-py-object-reference {
258
+ /* py-object-reference-face */
259
+ color: #ff79c6;
260
+ font-weight: bold;
261
+ }
262
+ .org-py-pseudo-keyword {
263
+ /* py-pseudo-keyword-face */
264
+ color: #ff79c6;
265
+ font-weight: bold;
266
+ }
267
+ .org-py-try-if {
268
+ /* py-try-if-face */
269
+ color: #ff79c6;
270
+ font-weight: bold;
271
+ }
272
+ .org-py-variable-name {
273
+ /* py-variable-name-face */
274
+ color: #f8f8f2;
275
+ background-color: #282a36;
276
+ }
277
+ .org-py-xxx-tag {
278
+ /* py-XXX-tag-face */
279
+ color: #f1fa8c;
280
+ }
281
+ .org-query-replace {
282
+ /* query-replace */
283
+ color: #ffb86c;
284
+ background-color: #464752;
285
+ font-weight: bold;
286
+ }
287
+ .org-regexp-grouping-backslash {
288
+ /* font-lock-regexp-grouping-backslash */
289
+ font-weight: bold;
290
+ }
291
+ .org-regexp-grouping-construct {
292
+ /* font-lock-regexp-grouping-construct */
293
+ font-weight: bold;
294
+ }
295
+ .org-region {
296
+ /* region */
297
+ color: #282a36;
298
+ background-color: #f1fa8c;
299
+ }
300
+ .org-shadow {
301
+ /* shadow */
302
+ color: #b3b3b3;
303
+ }
304
+ .org-show-paren-match {
305
+ /* show-paren-match */
306
+ background-color: #4f94cd;
307
+ }
308
+ .org-show-paren-match-expression {
309
+ /* show-paren-match-expression */
310
+ background-color: #4f94cd;
311
+ }
312
+ .org-show-paren-mismatch {
313
+ /* show-paren-mismatch */
314
+ color: #ffffff;
315
+ background-color: #a020f0;
316
+ }
317
+ .org-string {
318
+ /* font-lock-string-face */
319
+ color: #f1fa8c;
320
+ }
321
+ .org-success {
322
+ /* success */
323
+ color: #00ff00;
324
+ font-weight: bold;
325
+ }
326
+ .org-tooltip {
327
+ /* tooltip */
328
+ color: #000000;
329
+ background-color: #ffffe0;
330
+ }
331
+ .org-trailing-whitespace {
332
+ /* trailing-whitespace */
333
+ background-color: #ffb86c;
334
+ }
335
+ .org-type {
336
+ /* font-lock-type-face */
337
+ color: #bd93f9;
338
+ }
339
+ .org-underline {
340
+ /* underline */
341
+ text-decoration: underline;
342
+ }
343
+ .org-variable-name {
344
+ /* font-lock-variable-name-face */
345
+ color: #f8f8f2;
346
+ }
347
+ .org-vertical-border {
348
+ /* vertical-border */
349
+ color: #373844;
350
+ }
351
+ .org-warning {
352
+ /* warning */
353
+ color: #ffb86c;
354
+ }
355
+ .org-warning-1 {
356
+ /* font-lock-warning-face */
357
+ color: #ffb86c;
358
+ background-color: #373844;
359
+ }
360
+ .org-which-func {
361
+ /* which-func */
362
+ color: #50fa7b;
363
+ font-weight: bold;
364
+ }
@@ -0,0 +1,250 @@
1
+ body {
2
+ font-size: 10pt;
3
+ color: #000000;
4
+ font-family: sans-serif;
5
+ margin: 0;
6
+ }
7
+
8
+ h1 {color: #ffba53;}
9
+
10
+ h2 {color: #68a5c3;}
11
+
12
+ h3 {color:#ffba53;}
13
+
14
+ a[hreflang]:after {
15
+ content: "\00a0[" attr(hreflang) "]";
16
+ color: #cccccc;
17
+ background: transparent;
18
+ }
19
+
20
+ a, a:visited {color: #666666;}
21
+ a:hover {text-decoration: none;}
22
+
23
+ img {border: 0;}
24
+
25
+ blockquote {
26
+ font-style: italic;
27
+ border-left: 4px solid #666666;
28
+ padding-left: 1em;
29
+ }
30
+
31
+ acronym {
32
+ border-bottom:dotted 1px #666666;
33
+ cursor:help;
34
+ }
35
+
36
+ code {
37
+ font-family: monospace;
38
+ color: #bb1111;
39
+ }
40
+ h2 code {color: #68a5c3;}
41
+ h3 code {color: #ffba53;}
42
+ h4 code {color: #000000;}
43
+
44
+ ul {
45
+ list-style: url('/assets/umaneti/img/tic.png');
46
+ padding-left: 2em;
47
+ }
48
+
49
+ ol {padding-left: 2em;}
50
+
51
+ p, li {
52
+ text-align: justify;
53
+ line-height: 1.75em;
54
+ }
55
+
56
+ dt {
57
+ font-weight: bold;
58
+ }
59
+
60
+ .underline {
61
+ text-decoration: underline;
62
+ }
63
+
64
+ .org-center {
65
+ text-align: center;
66
+ }
67
+
68
+ fieldset {border: 0;}
69
+
70
+ input, textarea {
71
+ border: 1px solid #cccccc;
72
+ margin: 3px 0px;
73
+ background: #ffffff;
74
+ }
75
+ input:hover,
76
+ input:focus,
77
+ textarea:hover,
78
+ textarea:focus {
79
+ border: 1px solid #ffba53;
80
+ background: #ffffff;
81
+ }
82
+
83
+ /* Sidebar */
84
+
85
+ nav#table-of-contents {
86
+ width: 300px;
87
+ position: fixed;
88
+ top: 0px;
89
+ left: 0px;
90
+ padding: 1em 10px;
91
+ height: 100%;
92
+ height: calc(100% - 2em);
93
+ overflow: auto;
94
+ background-color: #666666;
95
+ color: #cccccc;
96
+ }
97
+ nav#table-of-contents a,
98
+ nav#table-of-contents a:hover,
99
+ nav#table-of-contents a:visited {
100
+ color: #cccccc;
101
+ text-decoration: none;
102
+ display: inline-block;
103
+ padding: .2em .5em;
104
+ width: 100%;
105
+ width: calc(100% - 1em);
106
+ }
107
+ nav#table-of-contents a code { color: #cccccc; }
108
+
109
+ #text-table-of-contents ul { padding-left: 0; }
110
+ #text-table-of-contents li {
111
+ font-weight: bold;
112
+ list-style: none;
113
+ line-height: 2em;
114
+ }
115
+ #text-table-of-contents li:hover {
116
+ background-color: #444444;
117
+ }
118
+ #text-table-of-contents li li {
119
+ font-weight: normal;
120
+ }
121
+ #text-table-of-contents li li:hover {
122
+ background-color: #222222;
123
+ }
124
+ #text-table-of-contents li li li:hover {
125
+ background-color: #000000;
126
+ }
127
+
128
+ /* Main content */
129
+
130
+ #content, #postamble {
131
+ max-width: 800px;
132
+ margin: 0 auto;
133
+ padding: 0 1.5em;
134
+ background-image: url('/assets/umaneti/img/top.png');
135
+ background-position: top left;
136
+ background-repeat: repeat-x;
137
+ }
138
+
139
+ nav#table-of-contents ~ #content,
140
+ nav#table-of-contents ~ #postamble {
141
+ margin: 0 0 0 320px;
142
+ }
143
+
144
+ div.tipblock,
145
+ div.warningblock,
146
+ div.cautionblock,
147
+ div.noteblock {
148
+ border-width: 1px;
149
+ border-style: solid;
150
+ margin: 1.2em;
151
+ padding: 0 1em;
152
+ box-shadow: 3px 3px 3px #eeeeee;
153
+ }
154
+ div.tipblock::before,
155
+ div.warningblock::before,
156
+ div.cautionblock::before,
157
+ div.noteblock::before {
158
+ font-size: 2em;
159
+ margin-top: 0.3em;
160
+ padding-right: .5em;
161
+ position: absolute;
162
+ }
163
+ div.tipblock > *,
164
+ div.warningblock > *,
165
+ div.cautionblock > *,
166
+ div.noteblock > * {
167
+ margin-left: 4em;
168
+ }
169
+
170
+ div.warningblock {
171
+ border-color: #ffba53;
172
+ }
173
+ div.warningblock::before {
174
+ content: "⚠️";
175
+ border-right: 1px solid #ffba53;
176
+ }
177
+ div.noteblock {
178
+ border-color: #68a5c3;
179
+ }
180
+ div.noteblock::before {
181
+ content: "ℹ️";
182
+ border-right: 1px solid #68a5c3;
183
+ }
184
+ div.tipblock {
185
+ border-color: #87C25D;
186
+ }
187
+ div.tipblock::before {
188
+ content: "💡";
189
+ border-right: 1px solid #87C25D;
190
+ }
191
+ div.cautionblock {
192
+ border-color: #ff5555;
193
+ }
194
+ div.cautionblock::before {
195
+ content: "🔥";
196
+ border-right: 1px solid #ff5555;
197
+ }
198
+
199
+
200
+ @media screen and (max-width: 660px) {
201
+ nav#table-of-contents {
202
+ display: none;
203
+ }
204
+ #content, #postamble {
205
+ max-width: 95%;
206
+ margin: 0;
207
+ }
208
+ nav#table-of-contents ~ #content,
209
+ nav#table-of-contents ~ #postamble {
210
+ max-width: 95%;
211
+ margin: 0;
212
+ }
213
+ }
214
+
215
+ #postamble {
216
+ border-top: 1px solid #cccccc;
217
+ font-size: .8em;
218
+ text-align: center;
219
+ line-height: 1.5em;
220
+ padding: 1em 1.5em;
221
+ }
222
+
223
+ .post-meta {
224
+ font-size: .9em;
225
+ font-style: italic;
226
+ }
227
+
228
+ /* Header */
229
+ #content header {
230
+ padding: 1em;
231
+ padding-bottom: 1.5em;
232
+ }
233
+ #content header h1 {
234
+ text-align: center;
235
+ }
236
+
237
+ #preamble nav ul {
238
+ list-style: none;
239
+ padding-left: 0;
240
+ }
241
+ #preamble li {
242
+ display: inline;
243
+ line-height: 1em;
244
+ }
245
+ #preamble li::before {
246
+ content: " · ";
247
+ }
248
+ #preamble li:first-child::before {
249
+ content: "";
250
+ }
@@ -30,24 +30,6 @@ module Fronde
30
30
  config
31
31
  end
32
32
 
33
- # Generate emacs directory variables file.
34
- #
35
- # This method generate the file ~.dir-locals.el~, which is
36
- # responsible to load fronde Org settings when visiting an Org file
37
- # of this fronde instance.
38
- #
39
- # @return [Integer] the length written (as returned by the
40
- # underlying ~File.write~ method call)
41
- def self.write_dir_locals
42
- workdir = Dir.pwd
43
- # rubocop:disable Layout/LineLength
44
- File.write(
45
- "#{workdir}/.dir-locals.el",
46
- "((org-mode . ((eval . (load-file \"#{workdir}/var/lib/org-config.el\")))))"
47
- )
48
- # rubocop:enable Layout/LineLength
49
- end
50
-
51
33
  def self.render_liquid_template(content, data)
52
34
  template = Liquid::Template.parse(content)
53
35
  template.render(data)
@@ -22,7 +22,6 @@ module Fronde
22
22
  #
23
23
  # @return [Integer] the length written (as returned by the
24
24
  # underlying ~File.write~ method call)
25
- # rubocop:disable Metrics/MethodLength
26
25
  def write_org_lisp_config
27
26
  workdir = Dir.pwd
28
27
  all_projects = sources.map(&:org_config).flatten
@@ -37,16 +36,27 @@ module Fronde
37
36
  'long_date_fmt' => R18n.t.full_datetime_format.to_s,
38
37
  'author' => { 'email' => get('author_email', ''),
39
38
  'name' => get('author') },
39
+ 'domain' => get('domain'),
40
40
  'all_projects' => all_projects + all_themes
41
41
  )
42
42
  File.write("#{workdir}/var/lib/org-config.el", content)
43
43
  end
44
- # rubocop:enable Metrics/MethodLength
45
44
 
46
45
  private
47
46
 
47
+ def theme_directory(theme)
48
+ # User theme first to allow overwriting
49
+ directory = File.expand_path("themes/#{theme}")
50
+ return directory if Dir.exist? directory
51
+
52
+ directory = File.expand_path("data/themes/#{theme}", __dir__)
53
+ return directory if Dir.exist? directory
54
+
55
+ raise Errno::ENOENT, "Theme #{theme} not found"
56
+ end
57
+
48
58
  def org_theme_config(theme)
49
- { 'base-directory' => File.expand_path("themes/#{theme}"),
59
+ { 'base-directory' => theme_directory(theme),
50
60
  # rubocop:disable Layout/LineLength
51
61
  'base-extension' => %w[css js gif jpg png svg otf ttf woff2?].join('\\\\|'),
52
62
  'publishing-directory' => "#{get('html_public_folder')}/assets/#{theme}",