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.
- checksums.yaml +4 -4
- data/bin/fronde +15 -30
- data/lib/ext/nil_time.rb +25 -0
- data/lib/ext/r18n.rb +17 -0
- data/lib/ext/time.rb +49 -0
- data/lib/fronde/cli/commands.rb +92 -103
- data/lib/fronde/cli/data/Rakefile +8 -0
- data/lib/fronde/cli/data/config.yml +13 -0
- data/lib/fronde/cli/data/gitignore +7 -0
- data/lib/fronde/cli/data/zsh_completion +37 -0
- data/lib/fronde/cli/helpers.rb +55 -0
- data/lib/fronde/cli/opt_parse.rb +143 -0
- data/lib/fronde/cli/throbber.rb +99 -0
- data/lib/fronde/cli.rb +41 -42
- data/lib/fronde/config/data/org-config.el +24 -0
- data/lib/fronde/config/{ox-fronde.el → data/ox-fronde.el} +1 -1
- data/lib/fronde/config/helpers.rb +80 -0
- data/lib/fronde/config/lisp.rb +70 -0
- data/lib/fronde/config.rb +135 -99
- data/lib/fronde/emacs.rb +23 -20
- data/lib/fronde/index/atom_generator.rb +55 -66
- data/lib/fronde/index/data/all_tags.org +14 -0
- data/lib/fronde/index/data/template.org +22 -0
- data/lib/fronde/index/data/template.xml +37 -0
- data/lib/fronde/index/org_generator.rb +70 -88
- data/lib/fronde/index.rb +56 -82
- data/lib/fronde/org/file.rb +287 -0
- data/lib/fronde/org/file_extracter.rb +98 -0
- data/lib/fronde/org.rb +103 -0
- data/lib/fronde/preview.rb +43 -39
- data/lib/fronde/slug.rb +27 -0
- data/lib/fronde/source/gemini.rb +39 -0
- data/lib/fronde/source/html.rb +67 -0
- data/lib/fronde/source.rb +204 -0
- data/lib/fronde/templater.rb +94 -71
- data/lib/fronde/version.rb +1 -1
- data/lib/tasks/cli.rake +33 -0
- data/lib/tasks/org.rake +63 -43
- data/lib/tasks/site.rake +68 -30
- data/lib/tasks/sync.rake +41 -21
- data/lib/tasks/tags.rake +11 -7
- data/locales/en.yml +60 -14
- data/locales/fr.yml +68 -14
- metadata +57 -156
- data/lib/fronde/config/lisp_config.rb +0 -340
- data/lib/fronde/config/org-config.el +0 -19
- data/lib/fronde/org_file/class_methods.rb +0 -72
- data/lib/fronde/org_file/extracter.rb +0 -72
- data/lib/fronde/org_file/htmlizer.rb +0 -43
- data/lib/fronde/org_file.rb +0 -298
- data/lib/fronde/utils.rb +0 -229
data/lib/fronde/emacs.rb
CHANGED
@@ -1,37 +1,40 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'config'
|
4
4
|
|
5
5
|
module Fronde
|
6
6
|
# Wraps Gnu/Emacs calls
|
7
7
|
class Emacs
|
8
|
-
def initialize(
|
9
|
-
@file = file_path
|
8
|
+
def initialize(verbose: false)
|
10
9
|
@verbose = verbose
|
10
|
+
@command = nil
|
11
11
|
end
|
12
12
|
|
13
|
-
def publish
|
14
|
-
|
15
|
-
|
16
|
-
)
|
17
|
-
if @verbose
|
18
|
-
warn command
|
19
|
-
return system(command, exception: true)
|
20
|
-
end
|
21
|
-
system command, out: '/dev/null', err: '/dev/null', exception: true
|
13
|
+
def publish(project = 'website')
|
14
|
+
build_command("(org-publish \"#{project}\")")
|
15
|
+
run_command
|
22
16
|
end
|
23
17
|
|
24
18
|
private
|
25
19
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
20
|
+
def run_command
|
21
|
+
cmd = @command.join(' ')
|
22
|
+
if @verbose
|
23
|
+
warn cmd
|
24
|
+
return system(cmd, exception: true)
|
25
|
+
end
|
26
|
+
system cmd, out: '/dev/null', err: '/dev/null', exception: true
|
27
|
+
end
|
28
|
+
|
29
|
+
def build_command(org_action)
|
30
|
+
default_emacs = Fronde::CONFIG.get('emacs')
|
31
|
+
@command = [default_emacs || 'emacs -Q --batch -nw']
|
32
|
+
@command << '--eval \'(setq inhibit-message t)\'' unless @verbose
|
33
|
+
@command += [
|
34
|
+
'--eval \'(setq enable-dir-local-variables nil)\'',
|
35
|
+
'-l ./var/lib/org-config.el',
|
36
|
+
"--eval '#{org_action}'"
|
31
37
|
]
|
32
|
-
emacs_cmd << '--eval \'(setq inhibit-message t)\'' unless @verbose
|
33
|
-
emacs_cmd.concat(arguments)
|
34
|
-
emacs_cmd.join(' ')
|
35
38
|
end
|
36
39
|
end
|
37
40
|
end
|
@@ -1,85 +1,74 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require 'fronde/config'
|
3
|
+
require_relative '../config'
|
5
4
|
|
6
5
|
module Fronde
|
7
|
-
#
|
8
|
-
|
6
|
+
# Reopen Index class to embed Atom feeds sepecific methods
|
7
|
+
class Index
|
9
8
|
def to_atom(index_name = 'index')
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
format '%<content>s</feed>', content: content.join("\n")
|
9
|
+
entries = @index[index_name][0...10].map(&:to_h)
|
10
|
+
return atom_index(entries) if index_name == 'index'
|
11
|
+
|
12
|
+
atom_file(index_name, entries)
|
15
13
|
end
|
16
14
|
|
17
15
|
def write_atom(index_name)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
16
|
+
slug = Slug.slug index_name
|
17
|
+
atomdest = "#{@project.publication_path}/feeds/#{slug}.xml"
|
18
|
+
File.write atomdest, to_atom(index_name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def write_all_feeds(verbose: true)
|
22
|
+
FileUtils.mkdir_p "#{@project.publication_path}/feeds"
|
23
|
+
@index.each_key do |tag|
|
24
|
+
write_atom(tag)
|
25
|
+
warn R18n.t.fronde.index.atom_generated(tag: tag) if verbose
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
29
|
private
|
26
30
|
|
27
|
-
# Render
|
31
|
+
# Render an Atom feed file.
|
28
32
|
#
|
29
|
-
# @param
|
30
|
-
# @
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
|
49
|
-
xml:lang="#{Fronde::Config.get('lang')}">
|
50
|
-
|
51
|
-
<title>#{title}</title>
|
52
|
-
<link href="#{domain}/feeds/#{slug}.xml" rel="self" type="application/atom+xml"/>
|
53
|
-
<link href="#{tagurl}" rel="alternate" type="text/html" title="#{title}"/>
|
54
|
-
<updated>#{upddate}</updated>
|
55
|
-
<author><name>#{Fronde::Config.get('author', '')}</name></author>
|
56
|
-
<id>urn:md5:#{Digest::MD5.hexdigest(domain)}</id>
|
57
|
-
<generator uri="https://git.umaneti.net/fronde/about/">Fronde</generator>
|
58
|
-
ENDATOM
|
33
|
+
# @param tag_name [String] the tag name of the current atom feed
|
34
|
+
# @param entries [Array] the article to list in this file
|
35
|
+
# @return [String] the Atom feed as a String
|
36
|
+
def atom_file(tag_name, entries)
|
37
|
+
domain = Fronde::CONFIG.get('domain')
|
38
|
+
slug = Slug.slug(tag_name)
|
39
|
+
tagurl = "#{domain}#{@project.public_absolute_path}tags/#{slug}.html"
|
40
|
+
Config::Helpers.render_liquid_template(
|
41
|
+
File.read(File.expand_path('./data/template.xml', __dir__)),
|
42
|
+
'title' => @tags_names[tag_name],
|
43
|
+
'lang' => Fronde::CONFIG.get('lang'),
|
44
|
+
'domain' => domain,
|
45
|
+
'slug' => slug,
|
46
|
+
'tagurl' => tagurl,
|
47
|
+
'upddate' => @date.xmlschema,
|
48
|
+
'author' => Fronde::CONFIG.get('author'),
|
49
|
+
'publication_format' => @project['mime_type'],
|
50
|
+
'entries' => entries
|
51
|
+
)
|
59
52
|
end
|
60
53
|
|
61
|
-
# Render
|
54
|
+
# Render the main/index Atom feed.
|
62
55
|
#
|
63
|
-
# @param
|
64
|
-
#
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
<author><name>#{CGI.escapeHTML(article.author)}</name></author>
|
80
|
-
#{keywords}<content type="html">#{CGI.escapeHTML(article.excerpt)}</content>
|
81
|
-
</entry>
|
82
|
-
ENDENTRY
|
56
|
+
# @param entries [Array] the article to list in this file
|
57
|
+
# @return [String] the Atom feed as a String
|
58
|
+
def atom_index(entries)
|
59
|
+
domain = Fronde::CONFIG.get('domain')
|
60
|
+
Config::Helpers.render_liquid_template(
|
61
|
+
File.read(File.expand_path('./data/template.xml', __dir__)),
|
62
|
+
'title' => @project['title'],
|
63
|
+
'lang' => Fronde::CONFIG.get('lang'),
|
64
|
+
'domain' => domain,
|
65
|
+
'slug' => 'index',
|
66
|
+
'tagurl' => domain,
|
67
|
+
'upddate' => @date.xmlschema,
|
68
|
+
'author' => Fronde::CONFIG.get('author'),
|
69
|
+
'publication_format' => @project['mime_type'],
|
70
|
+
'entries' => entries
|
71
|
+
)
|
83
72
|
end
|
84
73
|
end
|
85
74
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#+title: {{ title }}
|
2
|
+
#+author: {{ author }}
|
3
|
+
#+language: {{ lang }}
|
4
|
+
{% for index in indexes %}
|
5
|
+
* {{ index.title }}
|
6
|
+
:PROPERTIES:
|
7
|
+
:HTML_CONTAINER_CLASS: index-tags
|
8
|
+
:UNNUMBERED: notoc
|
9
|
+
:END:
|
10
|
+
|
11
|
+
{% for tag in index.tags -%}
|
12
|
+
- [[{{ domain }}{{ project_path }}tags/{{ tag.slug }}.html][{{ tag.title }}]] ({{ tag.weight }})
|
13
|
+
{% endfor %}
|
14
|
+
{%- endfor -%}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#+title: {{ title }}
|
2
|
+
#+author: {{ author }}
|
3
|
+
#+language: {{ lang }}
|
4
|
+
{%- unless slug == '__HOME_PAGE__' %}
|
5
|
+
#+html_head_extra: <link rel="alternate" type="application/atom+xml" title="{{ title }}" href="{{ domain }}{{ project_path }}feeds/{{ slug }}.xml" />
|
6
|
+
{% endunless -%}
|
7
|
+
{%- assign last_year = 0 -%}
|
8
|
+
{% for article in entries %}
|
9
|
+
{% assign cur_year = article.timekey | slice: 0, 4 %}
|
10
|
+
{%- unless cur_year == last_year %}
|
11
|
+
* {% if cur_year == "0000" %}{{ unsorted }}{% else %}{{ cur_year }}{% endif %}
|
12
|
+
:PROPERTIES:
|
13
|
+
:HTML_CONTAINER_CLASS: index-year
|
14
|
+
:UNNUMBERED: notoc
|
15
|
+
:END:
|
16
|
+
{% assign last_year = cur_year %}
|
17
|
+
{% endunless -%}
|
18
|
+
- *[[{{ article.url }}][{{ article.title }}]]*
|
19
|
+
{%- if article.published != '' %} / {{ article.published }}{% endif -%}
|
20
|
+
{%- if article.excerpt != '' %} \\
|
21
|
+
{{ article.excerpt }}{% endif %}
|
22
|
+
{%- endfor %}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<feed xmlns="http://www.w3.org/2005/Atom"
|
3
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
4
|
+
xml:lang="{{ lang }}">
|
5
|
+
|
6
|
+
<title>{{ title | escape }}</title>
|
7
|
+
<link href="{{ domain }}/feeds/{{ slug }}.xml" rel="self" type="application/atom+xml"/>
|
8
|
+
<link href="{{ tagurl }}" rel="alternate" type="text/html" title="{{ title }}"/>
|
9
|
+
<updated>{{ upddate }}</updated>
|
10
|
+
<author><name>{{ author }}</name></author>
|
11
|
+
<id>urn:md5:{{ domain | md5 }}</id>
|
12
|
+
<generator uri="https://git.umaneti.net/fronde/about/">Fronde</generator>
|
13
|
+
|
14
|
+
{%- for article in entries %}
|
15
|
+
|
16
|
+
<entry>
|
17
|
+
<title>{{ article.title | escape }}</title>
|
18
|
+
<link href="{{ article.url }}" rel="alternate"
|
19
|
+
type="{{ publication_format }}"
|
20
|
+
title="{{ article.title }}"/>
|
21
|
+
<id>urn:md5:{{ article.timekey | md5 }}</id>
|
22
|
+
<published>{{ article.published_xml }}</published>
|
23
|
+
<updated>{{ article.updated_xml }}</updated>
|
24
|
+
<author><name>{{ article.author | escape }}</name></author>
|
25
|
+
{%- for keyword in article.keywords %}
|
26
|
+
<dc:subject>{{ keyword | escape }}</dc:subject>
|
27
|
+
{%- endfor %}
|
28
|
+
{%- if publication_format == 'text/html' %}
|
29
|
+
<content type="html">
|
30
|
+
{%- else %}
|
31
|
+
<content>
|
32
|
+
{%- endif %}
|
33
|
+
{{- article.published_body | escape -}}
|
34
|
+
</content>
|
35
|
+
</entry>
|
36
|
+
{%- endfor %}
|
37
|
+
</feed>
|
@@ -1,114 +1,96 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
using TimePatch
|
4
|
+
|
3
5
|
module Fronde
|
4
|
-
#
|
5
|
-
# index.
|
6
|
-
|
7
|
-
def
|
8
|
-
|
6
|
+
# Reopen Index class to embed methods responsible for generating an
|
7
|
+
# org file for a given index.
|
8
|
+
class Index
|
9
|
+
def blog_home_page
|
10
|
+
org_index @project['title'], '__HOME_PAGE__', @entries.map(&:to_h)
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_org(index_name = 'index')
|
9
14
|
return all_tags_index if index_name == 'index'
|
10
|
-
|
11
|
-
|
15
|
+
|
16
|
+
org_index(
|
17
|
+
@tags_names[index_name], index_name,
|
18
|
+
(@index[index_name] || []).map(&:to_h)
|
19
|
+
)
|
12
20
|
end
|
13
21
|
alias_method :to_s, :to_org
|
14
22
|
|
15
23
|
def write_org(index_name)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
content = to_org index_name
|
20
|
-
orgdest = "tags/#{slug}.org"
|
21
|
-
File.write(orgdest, content)
|
24
|
+
slug = Slug.slug index_name
|
25
|
+
orgdest = "#{@project['path']}/tags/#{slug}.org"
|
26
|
+
File.write orgdest, to_org(index_name)
|
22
27
|
end
|
23
28
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
content += org_articles(@projects[project_name])
|
29
|
+
def write_all_org(verbose: true)
|
30
|
+
FileUtils.mkdir_p "#{@project['path']}/tags"
|
31
|
+
@index.each_key do |tag|
|
32
|
+
write_org(tag)
|
33
|
+
warn R18n.t.fronde.index.index_generated(tag: tag) if verbose
|
30
34
|
end
|
31
|
-
|
35
|
+
write_blog_home_page(verbose)
|
32
36
|
end
|
33
37
|
|
34
|
-
|
35
|
-
Fronde::Config.sources.each do |project|
|
36
|
-
next unless project['is_blog']
|
37
|
-
next unless Dir.exist?(project['path'])
|
38
|
-
warn "Generated blog home for #{project['name']}" if verbose
|
39
|
-
orgdest = format('%<root>s/index.org', root: project['path'])
|
40
|
-
File.write(orgdest, to_org(project['name'], is_project: true))
|
41
|
-
end
|
42
|
-
end
|
38
|
+
private
|
43
39
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
40
|
+
# Render an Org index file.
|
41
|
+
#
|
42
|
+
# @param title [String] the title of the current org index
|
43
|
+
# @param slug [String] the slug of the current org index
|
44
|
+
# @param entries [Array] the article to list in this file
|
45
|
+
# @return [String] the org file content as a String
|
46
|
+
def org_index(title, slug, entries)
|
47
|
+
entries.map! do |article|
|
48
|
+
published = article['published']
|
49
|
+
unless published == ''
|
50
|
+
article['published'] = R18n.t.fronde.index.published_on published
|
54
51
|
end
|
52
|
+
article
|
55
53
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
54
|
+
Config::Helpers.render_liquid_template(
|
55
|
+
File.read(File.expand_path('./data/template.org', __dir__)),
|
56
|
+
'title' => title,
|
57
|
+
'slug' => slug,
|
58
|
+
'project_path' => @project.public_absolute_path,
|
59
|
+
'domain' => Fronde::CONFIG.get('domain'),
|
60
|
+
'lang' => Fronde::CONFIG.get('lang'),
|
61
|
+
'author' => Fronde::CONFIG.get('author'),
|
62
|
+
'unsorted' => R18n.t.fronde.index.unsorted,
|
63
|
+
'entries' => entries
|
64
|
+
)
|
64
65
|
end
|
65
66
|
|
66
|
-
def
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
#+title: #{title}
|
74
|
-
#+author: #{Fronde::Config.get('author')}
|
75
|
-
#+language: #{Fronde::Config.get('lang')}
|
76
|
-
HEADER
|
77
|
-
end
|
78
|
-
|
79
|
-
def org_articles(articles_list)
|
80
|
-
last_year = nil
|
81
|
-
articles_list.map do |article|
|
82
|
-
year_title = ''
|
83
|
-
year = article.timekey.slice(0, 4)
|
84
|
-
if year != last_year
|
85
|
-
year_title = format("\n%<title>s\n", title: org_title(year))
|
86
|
-
last_year = year
|
67
|
+
def all_tags_index
|
68
|
+
indexes = sort_tags_by_name_and_weight.map do |title, tags|
|
69
|
+
all_tags = tags.map do |tag|
|
70
|
+
{
|
71
|
+
'slug' => tag, 'title' => @tags_names[tag],
|
72
|
+
'weight' => @index[tag].length
|
73
|
+
}
|
87
74
|
end
|
88
|
-
|
75
|
+
{ 'title' => R18n.t.fronde.index.send(title), 'tags' => all_tags }
|
89
76
|
end
|
77
|
+
Config::Helpers.render_liquid_template(
|
78
|
+
File.read(File.expand_path('./data/all_tags.org', __dir__)),
|
79
|
+
'title' => R18n.t.fronde.index.all_tags,
|
80
|
+
'lang' => Fronde::CONFIG.get('lang'),
|
81
|
+
'author' => Fronde::CONFIG.get('author'),
|
82
|
+
'domain' => Fronde::CONFIG.get('domain'),
|
83
|
+
'project_path' => @project.public_absolute_path,
|
84
|
+
'indexes' => indexes
|
85
|
+
)
|
90
86
|
end
|
91
87
|
|
92
|
-
def
|
93
|
-
|
94
|
-
if
|
95
|
-
|
96
|
-
published = R18n.t.fronde.index.published_on art_date
|
97
|
-
line += " / #{published}"
|
88
|
+
def write_blog_home_page(verbose)
|
89
|
+
orgdest = format('%<root>s/index.org', root: @project['path'])
|
90
|
+
if verbose
|
91
|
+
warn R18n.t.fronde.org.generate_blog_index(name: @project['name'])
|
98
92
|
end
|
99
|
-
|
100
|
-
line
|
101
|
-
end
|
102
|
-
|
103
|
-
def org_title(year, html_class = 'index-year')
|
104
|
-
year = R18n.t.fronde.index.unsorted if year == '0000'
|
105
|
-
<<~ENDPROP
|
106
|
-
* #{year}
|
107
|
-
:PROPERTIES:
|
108
|
-
:HTML_CONTAINER_CLASS: #{html_class}
|
109
|
-
:UNNUMBERED: notoc
|
110
|
-
:END:
|
111
|
-
ENDPROP
|
93
|
+
File.write(orgdest, blog_home_page)
|
112
94
|
end
|
113
95
|
end
|
114
96
|
end
|
data/lib/fronde/index.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
require 'fronde/org_file'
|
7
|
-
require 'fronde/index/atom_generator'
|
8
|
-
require 'fronde/index/org_generator'
|
3
|
+
require_relative 'slug'
|
4
|
+
require_relative 'config'
|
5
|
+
require_relative 'org/file'
|
9
6
|
|
10
7
|
module Fronde
|
11
8
|
# Generates website indexes and atom feeds for all the org documents
|
@@ -13,118 +10,95 @@ module Fronde
|
|
13
10
|
class Index
|
14
11
|
attr_reader :date
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def initialize
|
20
|
-
@pubdir = Fronde::Config.get('public_folder')
|
13
|
+
def initialize(project)
|
14
|
+
@project = project
|
21
15
|
@index = { 'index' => [] }
|
22
|
-
@
|
16
|
+
@entries = []
|
23
17
|
@tags_names = {}
|
24
|
-
@date =
|
25
|
-
|
26
|
-
|
18
|
+
@date = Time.now
|
19
|
+
generate_feeds if @project.blog?
|
20
|
+
sort_feeds!
|
27
21
|
end
|
28
22
|
|
29
|
-
def
|
30
|
-
@index.keys.reject { |
|
23
|
+
def all_tags
|
24
|
+
@index.keys.reject { |tag| tag == 'index' }
|
31
25
|
end
|
32
26
|
|
33
27
|
def empty?
|
34
28
|
@index['index'].empty?
|
35
29
|
end
|
36
30
|
|
37
|
-
def write_all(verbose: true)
|
38
|
-
@index.each_key do |k|
|
39
|
-
write_org(k)
|
40
|
-
warn "Generated index file for #{k}" if verbose
|
41
|
-
write_atom(k)
|
42
|
-
warn "Generated atom feed for #{k}" if verbose
|
43
|
-
end
|
44
|
-
write_all_blog_home(verbose)
|
45
|
-
end
|
46
|
-
|
47
31
|
def sort_by(kind)
|
48
|
-
|
32
|
+
accepted_values = %i[name weight]
|
33
|
+
if accepted_values.include?(kind)
|
49
34
|
tags_sorted = sort_tags_by_name_and_weight["by_#{kind}".to_sym]
|
50
35
|
# Reverse in order to have most important or A near next prompt
|
51
36
|
# and avoid to scroll to find the beginning of the list.
|
52
|
-
return tags_sorted.map do |
|
53
|
-
@tags_names[
|
37
|
+
return tags_sorted.map do |tag|
|
38
|
+
@tags_names[tag] + " (#{@index[tag].length})"
|
54
39
|
end.reverse
|
55
40
|
end
|
56
|
-
|
41
|
+
error_msg = R18n.t.fronde.error.index.wrong_sort_kind(
|
42
|
+
kind: kind, accepted_values: accepted_values.inspect
|
43
|
+
)
|
44
|
+
raise ArgumentError, error_msg
|
57
45
|
end
|
58
46
|
|
59
|
-
|
47
|
+
class << self
|
48
|
+
def all_html_blog_index(&block)
|
49
|
+
all_blogs = CONFIG.sources.filter_map do |project|
|
50
|
+
next unless project['type'] == 'html' && project.blog?
|
60
51
|
|
61
|
-
|
62
|
-
Fronde::Config.sources.each do |project|
|
63
|
-
next unless project['is_blog']
|
64
|
-
if project['recursive']
|
65
|
-
file_pattern = '**/*.org'
|
66
|
-
else
|
67
|
-
file_pattern = '*.org'
|
68
|
-
end
|
69
|
-
Dir.glob(file_pattern, base: project['path']).map do |s|
|
70
|
-
org_file = File.join(project['path'], s)
|
71
|
-
next if exclude_file?(org_file, project)
|
72
|
-
add_to_indexes(
|
73
|
-
Fronde::OrgFile.new(org_file, project: project)
|
74
|
-
)
|
52
|
+
Index.new(project)
|
75
53
|
end
|
54
|
+
return all_blogs unless block
|
55
|
+
|
56
|
+
all_blogs.each(&block)
|
76
57
|
end
|
77
58
|
end
|
78
59
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
60
|
+
private
|
61
|
+
|
62
|
+
def generate_feeds
|
63
|
+
file_pattern = '**/*.org'
|
64
|
+
Dir.glob(file_pattern, base: @project['path']).map do |index_file|
|
65
|
+
# Obviously don't parse tags
|
66
|
+
next if index_file.start_with?('tags/')
|
67
|
+
|
68
|
+
org_file = File.join(@project['path'], index_file)
|
69
|
+
next if @project.exclude_file? org_file
|
70
|
+
|
71
|
+
add_to_indexes(Org::File.new(org_file))
|
72
|
+
end
|
83
73
|
end
|
84
74
|
|
85
75
|
def add_to_indexes(article)
|
86
76
|
@index['index'] << article
|
87
|
-
|
88
|
-
article.keywords.each do |
|
89
|
-
slug =
|
90
|
-
@tags_names[slug] =
|
77
|
+
@entries << article
|
78
|
+
article.keywords.each do |tag|
|
79
|
+
slug = Slug.slug tag
|
80
|
+
@tags_names[slug] = tag # Overwrite is permitted
|
91
81
|
@index[slug] ||= []
|
92
82
|
@index[slug] << article
|
93
83
|
end
|
94
84
|
end
|
95
85
|
|
96
|
-
def
|
97
|
-
@index.
|
98
|
-
|
99
|
-
end
|
100
|
-
@projects.each do |k, i|
|
101
|
-
@projects[k] = i.sort { |a, b| b.timekey <=> a.timekey }
|
86
|
+
def sort_feeds!
|
87
|
+
@index.transform_values! do |articles|
|
88
|
+
articles.sort_by(&:timekey).reverse
|
102
89
|
end
|
90
|
+
@entries = @entries.sort_by(&:timekey).reverse
|
103
91
|
end
|
104
92
|
|
105
93
|
def sort_tags_by_name_and_weight
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
end
|
112
|
-
tags_sorted
|
113
|
-
end
|
114
|
-
|
115
|
-
def exclude_file?(file_path, project)
|
116
|
-
# Obviously excluding index itself for blogs
|
117
|
-
return true if file_path == File.join(project['path'], 'index.org')
|
118
|
-
return false unless project['exclude']
|
119
|
-
file_path.match? project['exclude']
|
120
|
-
end
|
121
|
-
|
122
|
-
def save?
|
123
|
-
return true unless empty?
|
124
|
-
Fronde::Config.sources.each do |project|
|
125
|
-
return true if project['is_blog'] && Dir.exist?(project['path'])
|
126
|
-
end
|
127
|
-
false
|
94
|
+
all_keys = all_tags
|
95
|
+
{
|
96
|
+
by_name: all_keys.sort,
|
97
|
+
by_weight: all_keys.sort_by { @index[_1].length }.reverse
|
98
|
+
}
|
128
99
|
end
|
129
100
|
end
|
130
101
|
end
|
102
|
+
|
103
|
+
require_relative 'index/org_generator'
|
104
|
+
require_relative 'index/atom_generator'
|