fronde 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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 :'