fronde 0.3.3 → 0.4.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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/bin/fronde +15 -30
  3. data/lib/ext/nil_time.rb +25 -0
  4. data/lib/ext/r18n.rb +17 -0
  5. data/lib/ext/time.rb +49 -0
  6. data/lib/fronde/cli/commands.rb +92 -103
  7. data/lib/fronde/cli/data/Rakefile +8 -0
  8. data/lib/fronde/cli/data/config.yml +13 -0
  9. data/lib/fronde/cli/data/gitignore +7 -0
  10. data/lib/fronde/cli/data/zsh_completion +37 -0
  11. data/lib/fronde/cli/helpers.rb +55 -0
  12. data/lib/fronde/cli/opt_parse.rb +143 -0
  13. data/lib/fronde/cli/throbber.rb +99 -0
  14. data/lib/fronde/cli.rb +41 -42
  15. data/lib/fronde/config/data/org-config.el +24 -0
  16. data/lib/fronde/config/{ox-fronde.el → data/ox-fronde.el} +1 -1
  17. data/lib/fronde/config/helpers.rb +80 -0
  18. data/lib/fronde/config/lisp.rb +70 -0
  19. data/lib/fronde/config.rb +135 -99
  20. data/lib/fronde/emacs.rb +23 -20
  21. data/lib/fronde/index/atom_generator.rb +55 -66
  22. data/lib/fronde/index/data/all_tags.org +14 -0
  23. data/lib/fronde/index/data/template.org +22 -0
  24. data/lib/fronde/index/data/template.xml +37 -0
  25. data/lib/fronde/index/org_generator.rb +70 -88
  26. data/lib/fronde/index.rb +56 -82
  27. data/lib/fronde/org/file.rb +287 -0
  28. data/lib/fronde/org/file_extracter.rb +98 -0
  29. data/lib/fronde/org.rb +103 -0
  30. data/lib/fronde/preview.rb +43 -39
  31. data/lib/fronde/slug.rb +27 -0
  32. data/lib/fronde/source/gemini.rb +39 -0
  33. data/lib/fronde/source/html.rb +67 -0
  34. data/lib/fronde/source.rb +204 -0
  35. data/lib/fronde/templater.rb +94 -71
  36. data/lib/fronde/version.rb +1 -1
  37. data/lib/tasks/cli.rake +33 -0
  38. data/lib/tasks/org.rake +63 -43
  39. data/lib/tasks/site.rake +68 -30
  40. data/lib/tasks/sync.rake +41 -21
  41. data/lib/tasks/tags.rake +11 -7
  42. data/locales/en.yml +60 -14
  43. data/locales/fr.yml +68 -14
  44. metadata +57 -156
  45. data/lib/fronde/config/lisp_config.rb +0 -340
  46. data/lib/fronde/config/org-config.el +0 -19
  47. data/lib/fronde/org_file/class_methods.rb +0 -72
  48. data/lib/fronde/org_file/extracter.rb +0 -72
  49. data/lib/fronde/org_file/htmlizer.rb +0 -43
  50. data/lib/fronde/org_file.rb +0 -298
  51. data/lib/fronde/utils.rb +0 -229
data/lib/tasks/site.rake CHANGED
@@ -1,54 +1,92 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fronde/emacs'
4
- require 'fronde/index'
5
- require 'fronde/utils'
6
- require 'fronde/org_file'
7
- require 'fronde/templater'
3
+ require_relative '../fronde/emacs'
4
+ require_relative '../fronde/index'
5
+ require_relative '../fronde/templater'
6
+ require_relative '../fronde/cli/throbber'
8
7
 
9
8
  namespace :site do
10
- desc 'Generates all index files'
11
- task :index do
12
- index = Fronde::Index.new
13
- if verbose
14
- index.write_all
15
- next
9
+ desc 'Build all your projects'
10
+ task :build, [:force?] => ['var/lib/org-config.el'] do |_, args|
11
+ args.with_defaults(force?: false)
12
+ build_index = Thread.new do
13
+ all_index = Fronde::Index.all_html_blog_index
14
+ all_index.each do |index|
15
+ index.write_all_org(verbose: verbose)
16
+ end
17
+ Thread.current[:all_indexes] = all_index
16
18
  end
17
- build = Thread.new do
18
- index.write_all(verbose: false)
19
+ if verbose
20
+ build_index.join
21
+ else
22
+ Fronde::CLI::Throbber.run(
23
+ build_index, R18n.t.fronde.tasks.site.generating_indexes
24
+ )
19
25
  end
20
- Fronde::Utils.throbber(build, 'Generating indexes:')
21
- next if index.empty?
22
- Fronde::Config.write_org_lisp_config(with_tags: true)
23
- end
26
+ all_indexes = build_index[:all_indexes]
24
27
 
25
- desc 'Convert and customize all org files'
26
- task :build, [:force?] => ['var/lib/org-config.el', :index] do |_, args|
27
- args.with_defaults(:force? => false)
28
- build_html = Thread.new do
29
- rm_r 'var/tmp/timestamps', force: true if args[:force?]
30
- Fronde::Emacs.new(verbose: verbose).publish
31
- end
32
28
  begin
33
- Fronde::Utils.throbber(build_html, 'Building:')
29
+ build_html = Thread.new do
30
+ rm_r 'var/tmp/timestamps', force: true if args[:force?]
31
+ Fronde::Emacs.new(verbose: verbose).publish
32
+ end
33
+ Fronde::CLI::Throbber.run(build_html, R18n.t.fronde.tasks.site.building)
34
+
34
35
  # :nocov:
35
36
  rescue RuntimeError
36
- warn 'Aborting'
37
+ warn R18n.t.fronde.tasks.site.aborting
37
38
  next
38
39
  end
39
40
  # :nocov:
41
+
42
+ if all_indexes.any?
43
+ if verbose
44
+ all_indexes.each(&:write_all_feeds)
45
+ else
46
+ publish_feed = Thread.new do
47
+ all_indexes.each do |index|
48
+ index.write_all_feeds(verbose: false)
49
+ end
50
+ end
51
+ Fronde::CLI::Throbber.run(
52
+ publish_feed, R18n.t.fronde.tasks.site.publishing_feeds
53
+ )
54
+ end
55
+ end
56
+
57
+ next unless Fronde::CONFIG.sources.any? { |source| source.type == 'html' }
58
+
40
59
  customize_html = Thread.new do
41
- pubfolder = Fronde::Config.get('public_folder')
60
+ pubfolder = Fronde::CONFIG.get('html_public_folder')
42
61
  Dir["#{pubfolder}/**/*.html"].each do |f|
43
62
  Fronde::Templater.customize_output(f)
44
63
  end
45
64
  end
46
- Fronde::Utils.throbber(customize_html, 'Customizing:')
65
+ Fronde::CLI::Throbber.run(
66
+ customize_html, R18n.t.fronde.tasks.site.customizing
67
+ )
68
+ end
69
+
70
+ desc 'Cleanup orphaned published files'
71
+ task :clean do
72
+ pubfolder = Fronde::CONFIG.get('html_public_folder')
73
+ Dir["#{pubfolder}/**/*.html"].each do |file_name|
74
+ source = Fronde::Org::File.new(file_name)
75
+
76
+ # Return if an org file has been found for this published file
77
+ next unless source.file == file_name
78
+
79
+ print R18n.t.fronde.tasks.site.remove_orphan_file
80
+ action = $stdin.gets.strip.downcase
81
+ next unless action == 'y'
82
+
83
+ rm file_name
84
+ end
47
85
  end
48
86
 
49
87
  desc 'Start a test server'
50
88
  task :preview do
51
- require 'fronde/preview'
52
- Fronde.start_preview
89
+ require_relative '../fronde/preview'
90
+ Fronde::Preview.start
53
91
  end
54
92
  end
data/lib/tasks/sync.rake CHANGED
@@ -1,15 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fronde/config'
4
- require 'fronde/utils'
3
+ require_relative '../fronde/config'
4
+ require_relative '../fronde/cli/throbber'
5
5
 
6
6
  module Fronde
7
- class SyncError < Error; end
7
+ class SyncError < ::StandardError; end
8
8
  end
9
9
 
10
10
  def rsync_command(test = nil)
11
- rsync_command = Fronde::Config.get('rsync')
11
+ rsync_command = Fronde::CONFIG.get('rsync')
12
12
  return rsync_command unless rsync_command.nil?
13
+
13
14
  optstring = []
14
15
  optstring << 'n' if test
15
16
  if verbose
@@ -20,37 +21,56 @@ def rsync_command(test = nil)
20
21
  "rsync -#{optstring.join}rlt --delete"
21
22
  end
22
23
 
23
- def pull_or_push(direction, label, test)
24
- unless [:pull, :push].include? direction
25
- raise Fronde::SyncError, 'Not a valid direction'
26
- end
27
- remote_path = Fronde::Config.get('remote')
28
- raise Fronde::SyncError, 'No remote path set' if remote_path.nil?
29
- public_folder = Fronde::Config.get('public_folder')
24
+ def pull_or_push(direction, type, test)
25
+ remote_path = Fronde::CONFIG.get("#{type}_remote")
26
+ raise Fronde::SyncError, "No #{type} remote path set" if remote_path.nil?
27
+
28
+ public_folder = Fronde::CONFIG.get("#{type}_public_folder")
30
29
  # Default is to push
31
30
  cmd = ["#{public_folder}/", remote_path]
32
31
  cmd.reverse! if direction == :pull
33
32
  rsync = rsync_command(test)
34
- publish_thread = Thread.new do
33
+ Thread.new do
35
34
  sh "#{rsync} #{cmd.join(' ')}"
36
35
  end
37
- Fronde::Utils.throbber(publish_thread, label)
36
+ end
37
+
38
+ def source_types
39
+ Fronde::CONFIG.sources.map(&:type).uniq
38
40
  end
39
41
 
40
42
  namespace :sync do
41
43
  desc 'Push changes to server'
42
44
  task :push, :test? do |_, args|
43
- pull_or_push(:push, 'Publishing:', args[:test?])
44
- rescue Fronde::SyncError => e
45
- warn e
46
- next
45
+ source_types.each do |type|
46
+ publish_thread = pull_or_push(:push, type, args[:test?])
47
+ if verbose
48
+ publish_thread.join
49
+ else
50
+ Fronde::CLI::Throbber.run(
51
+ publish_thread, format('Publishing %<fmt>s:', fmt: type)
52
+ )
53
+ end
54
+ rescue Fronde::SyncError => e
55
+ warn e
56
+ next
57
+ end
47
58
  end
48
59
 
49
60
  desc 'Pull changes from server'
50
61
  task :pull, :test? do |_, args|
51
- pull_or_push(:pull, 'Pulling:', args[:test?])
52
- rescue Fronde::SyncError => e
53
- warn e
54
- next
62
+ source_types.each do |type|
63
+ pull_thread = pull_or_push(:pull, type, args[:test?])
64
+ if verbose
65
+ pull_thread.join
66
+ else
67
+ Fronde::CLI::Throbber.run(
68
+ pull_thread, format('Pulling %<fmt>s:', fmt: type)
69
+ )
70
+ end
71
+ rescue Fronde::SyncError => e
72
+ warn e
73
+ next
74
+ end
55
75
  end
56
76
  end
data/lib/tasks/tags.rake CHANGED
@@ -1,19 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fronde/index'
3
+ require_relative '../fronde/index'
4
4
 
5
5
  namespace :tags do
6
6
  desc 'List all tags by name'
7
7
  task :name do
8
- index = Fronde::Index.new
9
- next if index.empty?
10
- puts index.sort_by(:name).join("\n")
8
+ Fronde::Index.all_html_blog_index do |index|
9
+ next if index.empty?
10
+
11
+ puts index.sort_by(:name).join("\n")
12
+ end
11
13
  end
12
14
 
13
15
  desc 'List all tags by weight'
14
16
  task :weight do
15
- index = Fronde::Index.new
16
- next if index.empty?
17
- puts index.sort_by(:weight).join("\n")
17
+ Fronde::Index.all_html_blog_index do |index|
18
+ next if index.empty?
19
+
20
+ puts index.sort_by(:weight).join("\n")
21
+ end
18
22
  end
19
23
  end
data/locales/en.yml CHANGED
@@ -2,27 +2,55 @@
2
2
  fronde:
3
3
  bin:
4
4
  usage: 'Usage: fronde %1 [options]'
5
+ done: done
5
6
  commands:
6
7
  cmd_title: Commands
7
- alias: Alias for %1.
8
- init: Initialize your Fronde instance (you just need to do it once).
9
- update: Update Fronde dependency (to be run once in a while).
10
- preview: 'Start a test web server to preview your website on http://127.0.0.1:5000'
8
+ alias: Alias for ‘%1’.
9
+ new: Initialize a new Fronde instance.
10
+ update: >-
11
+ Update Fronde configuration and dependency (to be run after each
12
+ modification of the config.yml file and once in a while to stay
13
+ up-to-date with Org).
14
+ preview: Start a test web server to preview the generated website.
11
15
  open: Open or create an org file.
12
- build: Compile your org files to HTML.
13
- publish: Push local changes to your public web server.
16
+ build: Compile all org files to HTML or gemtext.
17
+ publish: Push local changes to the public web server.
14
18
  help: Alias for the -h switch.
15
19
  options:
16
20
  cmd_title: Options
17
- directory: Wrap the new org file in this named folder.
18
21
  help: Display help for a command and exit.
19
22
  version: Display Fronde version and exit.
20
- error:
21
- no_command: 'ERROR: no command or unknown command given.'
22
- no_file: 'ERROR: no file to open or edit.'
23
+ default_title: New article
23
24
  error:
24
- label: An error occurred.
25
- explanation: To see the error, run your command again with more verbosity, for example, fronde build -v
25
+ bin:
26
+ label: An error occurred.
27
+ explanation: >-
28
+ To see the error, run the same command again with more
29
+ verbosity, for example, fronde build -v
30
+ no_command: 'ERROR: no command or unknown command given.'
31
+ no_file: >-
32
+ Warning: No file path given. Default file will be used.
33
+ config:
34
+ deprecated_public_folder: >-
35
+ ‘public_folder’ setting is deprecated. Please use either
36
+ ‘html_public_folder’ or ‘gemini_public_folder’.
37
+ source:
38
+ no_path: Skipping %{source} as its ‘path’ key is missing.
39
+ duplicate: >-
40
+ Skipping %{source} as it appears at least twice in the sources
41
+ of type %{type}.
42
+ inclusion: >-
43
+ Skipping %{source} as it might be already embedded into the
44
+ other source %{other_source} of type %{type}.
45
+ org_file:
46
+ no_file_or_title: No file or title given.
47
+ no_project: No project found for %{file}. Publication will fail.
48
+ index:
49
+ wrong_sort_kind: '%{kind} not in %{accepted_values}'
50
+ templater:
51
+ no_element_found: >-
52
+ No element found with the selector %{source} in %{file}.
53
+ no_head_element: No head tag found in file %{file}.
26
54
  index:
27
55
  unsorted: Unsorted
28
56
  published_on: Published on %1
@@ -31,9 +59,27 @@ fronde:
31
59
  by_weight: By publication number
32
60
  full_date_format: '%A %{date}'
33
61
  full_date_with_time_format: '%{date} at %{time}'
62
+ index_generated: Generated index file for %{tag}.
63
+ atom_generated: Generated Atom feed for %{tag}.
34
64
  org:
65
+ generate_blog_index: Generating blog home page for %{name}
35
66
  postamble:
36
67
  written_by: Written by %a
37
68
  last_modification: Last modification on %C
38
- with_emacs: 'with %c, and published with %n'
39
- with_emacs_html: 'with %c, and published with %N'
69
+ with_emacs: with %c, and published with %n
70
+ with_emacs_html: with %c, and published with %N
71
+ tasks:
72
+ site:
73
+ aborting: Aborting
74
+ generating_indexes: 'Generating index files:'
75
+ building_indexes: 'Building index files:'
76
+ publishing_feeds: 'Publishing Atom feeds:'
77
+ building: 'Building:'
78
+ customizing: 'Customizing:'
79
+ remove_orphan_file: 'Remove it? [y/N]: '
80
+ org:
81
+ downloaded: Org version %{version} has been downloaded.
82
+ downloading: 'Downloading Org:'
83
+ no_download: Impossible to download Org now. Please try again later.
84
+ installed: Org version %{version} has been locally installed.
85
+ installing: 'Installing Org:'
data/locales/fr.yml CHANGED
@@ -2,27 +2,61 @@
2
2
  fronde:
3
3
  bin:
4
4
  usage: 'Usage : fronde %1 [options]'
5
+ done: fait
5
6
  commands:
6
7
  cmd_title: Commandes
7
- alias: Alias pour %1.
8
- init: Initialise votre instance de Fronde (vous ne devriez faire cela qu'une fois).
9
- update: Met à jour les dépendances de Fronde (à lancer une fois de temps à autre).
10
- preview: "Démarre un serveur web de test pour prévisualiser votre site à l'adresse http://127.0.0.1:5000"
8
+ alias: Alias pour ‘%1’.
9
+ new: Initialise une nouvelle instance de Fronde.
10
+ update: >-
11
+ Met à jour la configuration et les dépendances de Fronde (à
12
+ lancer après chaque modification du fichier config.yml et une
13
+ fois de temps à autre pour rester à jour avec Org).
14
+ preview: >-
15
+ Démarre un serveur web de test pour prévisualiser le site
16
+ généré.
11
17
  open: Ouvre ou crée un fichier org.
12
- build: Compile vos fichiers org en HTML.
13
- publish: Pousse vos changements locaux vers votre serveur web public.
18
+ build: Compile les fichiers org en HTML ou gemtext.
19
+ publish: >-
20
+ Pousse les changements locaux vers le serveur web public.
14
21
  help: Alias pour l'argument -h.
15
22
  options:
16
23
  cmd_title: Options
17
- directory: Place le nouveau fichier org dans un dossier à ce nom.
18
24
  help: Affiche l'aide pour une commande et quitte.
19
25
  version: Affiche la version de Fronde et quitte.
20
- error:
21
- no_command: 'ERREUR : Aucune commande ou commande inconnue donnée.'
22
- no_file: 'ERREUR : Aucun fichier à ouvrir ou éditer.'
26
+ default_title: Nouvel article
23
27
  error:
24
- label: Une erreur est survenue
25
- explanation: Pour voir le détail, lancez de nouveau la commande avec plus de verbosité, par exemple fronde build -v
28
+ bin:
29
+ label: Une erreur est survenue
30
+ explanation: >-
31
+ Pour voir le détail, lancez de nouveau la commande avec plus de
32
+ verbosité, par exemple fronde build -v
33
+ no_command: 'ERREUR : Aucune commande ou commande inconnue donnée.'
34
+ no_file: >-
35
+ Attention : Aucun chemin de fichier donné. Utilisation du
36
+ fichier par défaut.
37
+ config:
38
+ deprecated_public_folder: >-
39
+ La clé de configuration ‘public_folder’ est dépréciée. Merci
40
+ d’utiliser ‘html_public_folder’ ou ‘gemini_public_folder’ à la
41
+ place.
42
+ source:
43
+ no_path: >-
44
+ Ignore %{source} comme sa clé ‘path’ est manquante.
45
+ duplicate: >-
46
+ Ignore %{source} comme elle apparaît au moins deux fois dans les
47
+ sources de type %{type}.
48
+ inclusion: >-
49
+ Ignore %{source} qui semble être déjà inclue dans l’autre source
50
+ %{other_source} de type %{type}.
51
+ org_file:
52
+ no_file_or_title: Aucun chemin de fichier ou titre donné.
53
+ no_project: Aucun projet trouvé pour %{file}. Sa publication va échouer.
54
+ index:
55
+ wrong_sort_kind: '%{kind} n’est pas dans %{accepted_values}'
56
+ templater:
57
+ no_element_found: >-
58
+ Aucun élément trouvé avec le sélecteur %{source} dans %{file}.
59
+ no_head_element: Aucun élément head trouvé dans le fichier %{file}.
26
60
  index:
27
61
  unsorted: Non triés
28
62
  published_on: Publié le %1
@@ -31,9 +65,29 @@ fronde:
31
65
  by_weight: Par nombre de publication
32
66
  full_date_format: '%A %{date}'
33
67
  full_date_with_time_format: '%{date} à %{time}'
68
+ index_generated: Fichier d’index généré pour %{tag}.
69
+ atom_generated: Flux Atom généré pour %{tag}.
34
70
  org:
71
+ generate_blog_index: Génération de la page d’accueil du blog pour %{name}
35
72
  postamble:
36
73
  written_by: Écrit par %a
37
74
  last_modification: dernière modification le %C
38
- with_emacs: 'avec %c et publié avec %n'
39
- with_emacs_html: 'avec %c et publié avec %N'
75
+ with_emacs: avec %c et publié avec %n
76
+ with_emacs_html: avec %c et publié avec %N
77
+ tasks:
78
+ site:
79
+ aborting: Annulation
80
+ generating_indexes: 'Génération des fichiers d’index :'
81
+ building_indexes: 'Compilation des fichiers d’index :'
82
+ publishing_feeds: 'Publication des flux Atom :'
83
+ building: 'Compilation :'
84
+ customizing: 'Décoration :'
85
+ remove_orphan_file: 'Le supprimer ? [y/N]: '
86
+ org:
87
+ downloaded: La version %{version} de Org a été téléchargée.
88
+ downloading: 'Téléchargement de Org :'
89
+ no_download: >-
90
+ Impossible de télécharger Org maintenant. Merci de réessayer
91
+ plus tard.
92
+ installed: La version %{version} de Org a été installé localement.
93
+ installing: 'Installation de Org :'