neruda 0.2.4 → 0.2.6

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.
@@ -1,114 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Neruda
4
- # Embeds methods responsible for generating an org file for a given
5
- # index.
6
- module IndexOrgGenerator
7
- def to_org(index_name = 'index', is_project: false)
8
- return project_home_page(index_name) if is_project
9
- return all_tags_index if index_name == 'index'
10
- [org_header(index_name),
11
- org_articles(@index[index_name])].join("\n")
12
- end
13
- alias_method :to_s, :to_org
14
-
15
- def write_org(index_name)
16
- return unless save?
17
- slug = Neruda::OrgFile.slug index_name
18
- FileUtils.mkdir 'tags' unless Dir.exist? 'tags'
19
- content = to_org index_name
20
- orgdest = "tags/#{slug}.org"
21
- IO.write(orgdest, content)
22
- end
23
-
24
- private
25
-
26
- def project_home_page(project_name)
27
- content = [org_header(project_name, is_tag: false)]
28
- if @projects[project_name]&.any?
29
- content += org_articles(@projects[project_name])
30
- end
31
- content.join("\n")
32
- end
33
-
34
- def write_all_blog_home(verbose)
35
- Neruda::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
- IO.write(orgdest, to_org(project['name'], is_project: true))
41
- end
42
- end
43
-
44
- def all_tags_index
45
- content = [
46
- org_header(R18n.t.neruda.index.all_tags, is_tag: false)
47
- ]
48
- sort_tags_by_name_and_weight.each do |t, tags|
49
- content << ''
50
- content << org_title(R18n.t.neruda.index.send(t), 'index-tags')
51
- next if tags.empty?
52
- tags.each do |k|
53
- content << "- #{tag_published_url(k)} (#{@index[k].length})"
54
- end
55
- end
56
- content.join("\n")
57
- end
58
-
59
- def tag_published_url(tag_name)
60
- domain = Neruda::Config.settings['domain']
61
- title = @tags_names[tag_name]
62
- tag_link = "#{domain}/tags/#{tag_name}.html"
63
- "[[#{tag_link}][#{title}]]"
64
- end
65
-
66
- def org_header(title = nil, is_tag: true)
67
- if is_tag
68
- title = @tags_names[title]
69
- elsif title.nil? || title == 'index'
70
- title = Neruda::Config.settings['title']
71
- end
72
- <<~HEADER.strip
73
- #+title: #{title}
74
- #+author: #{Neruda::Config.settings['author']}
75
- #+language: #{Neruda::Config.settings['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
87
- end
88
- year_title + org_entry(article)
89
- end
90
- end
91
-
92
- def org_entry(article)
93
- line = "- *[[#{article.url}][#{article.title}]]*"
94
- if article.date
95
- art_date = article.datestring(:full, year: false)
96
- published = R18n.t.neruda.index.published_on art_date
97
- line += " / #{published}"
98
- end
99
- line += " \\\\\n #{article.excerpt}" if article.excerpt != ''
100
- line
101
- end
102
-
103
- def org_title(year, html_class = 'index-year')
104
- year = R18n.t.neruda.index.unsorted if year == '0000'
105
- <<~ENDPROP
106
- * #{year}
107
- :PROPERTIES:
108
- :HTML_CONTAINER_CLASS: #{html_class}
109
- :UNNUMBERED: notoc
110
- :END:
111
- ENDPROP
112
- end
113
- end
114
- end
data/lib/neruda/index.rb DELETED
@@ -1,130 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'fileutils'
4
- require 'digest/md5'
5
- require 'neruda/config'
6
- require 'neruda/org_file'
7
- require 'neruda/index/atom_generator'
8
- require 'neruda/index/org_generator'
9
-
10
- module Neruda
11
- # Generates website indexes and atom feeds for all the org documents
12
- # keywords.
13
- class Index
14
- attr_reader :date
15
-
16
- include Neruda::IndexAtomGenerator
17
- include Neruda::IndexOrgGenerator
18
-
19
- def initialize
20
- @pubdir = Neruda::Config.settings['public_folder']
21
- @index = { 'index' => [] }
22
- @projects = {}
23
- @tags_names = {}
24
- @date = DateTime.now
25
- feed
26
- sort!
27
- end
28
-
29
- def entries
30
- @index.keys.reject { |k| k == 'index' }
31
- end
32
-
33
- def empty?
34
- @index['index'].empty?
35
- end
36
-
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
- def sort_by(kind)
48
- if [:name, :weight].include?(kind)
49
- tags_sorted = sort_tags_by_name_and_weight["by_#{kind}".to_sym]
50
- # Reverse in order to have most important or A near next prompt
51
- # and avoid to scroll to find the beginning of the list.
52
- return tags_sorted.map do |k|
53
- @tags_names[k] + " (#{@index[k].length})"
54
- end.reverse
55
- end
56
- raise ArgumentError, "#{kind} not in [:name, :weight]"
57
- end
58
-
59
- private
60
-
61
- def feed
62
- Neruda::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
- Neruda::OrgFile.new(org_file, project: project)
74
- )
75
- end
76
- end
77
- end
78
-
79
- def add_to_project_index(article)
80
- project = article.project
81
- @projects[project['name']] ||= []
82
- @projects[project['name']] << article
83
- end
84
-
85
- def add_to_indexes(article)
86
- @index['index'] << article
87
- add_to_project_index article
88
- article.keywords.each do |k|
89
- slug = Neruda::OrgFile.slug k
90
- @tags_names[slug] = k # Overwrite is permitted
91
- @index[slug] ||= []
92
- @index[slug] << article
93
- end
94
- end
95
-
96
- def sort!
97
- @index.each do |k, i|
98
- @index[k] = i.sort { |a, b| b.timekey <=> a.timekey }
99
- end
100
- @projects.each do |k, i|
101
- @projects[k] = i.sort { |a, b| b.timekey <=> a.timekey }
102
- end
103
- end
104
-
105
- def sort_tags_by_name_and_weight
106
- tags_sorted = {}
107
- all_keys = entries
108
- tags_sorted[:by_name] = all_keys.sort
109
- tags_sorted[:by_weight] = all_keys.sort do |a, b|
110
- @index[b].length <=> @index[a].length
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
- Neruda::Config.sources.each do |project|
125
- return true if project['is_blog'] && Dir.exist?(project['path'])
126
- end
127
- false
128
- end
129
- end
130
- end
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Neruda
4
- # This module holds class methods for the {Neruda::OrgFile} class.
5
- module OrgFileClassMethods
6
- def source_for_target(file_name)
7
- # file_name may be frozen...
8
- src = file_name.sub(/\.html\z/, '.org')
9
- pubfolder = Neruda::Config.settings['public_folder']
10
- src.sub!(/^#{pubfolder}\//, '')
11
- # Look for match in each possible sources. The first found wins.
12
- Neruda::Config.sources.each do |project|
13
- if project['target'] == '.'
14
- origin = File.join(project['path'], src)
15
- else
16
- origin = File.join(
17
- project['path'], src.sub(/^#{project['target']}\//, '')
18
- )
19
- end
20
- return origin if File.exist?(origin)
21
- end
22
- nil
23
- end
24
-
25
- def target_for_source(file_name, project, with_public_folder: true)
26
- return nil if file_name.nil?
27
- # file_name may be frozen...
28
- target = file_name.sub(/\.org\z/, '.html').sub(/^#{Dir.pwd}\//, '')
29
- if project.nil?
30
- subfolder = File.basename(File.dirname(target))
31
- target = File.basename(target)
32
- target = "#{subfolder}/#{target}" if subfolder != '.'
33
- else
34
- project_relative_path = project['path'].sub(/^#{Dir.pwd}\//, '')
35
- target.sub!(/^#{project_relative_path}\//, '')
36
- target = "#{project['target']}/#{target}" if project['target'] != '.'
37
- end
38
- return target unless with_public_folder
39
- pubfolder = Neruda::Config.settings['public_folder']
40
- "#{pubfolder}/#{target}"
41
- end
42
-
43
- def project_for_source(file_name)
44
- # Look for match in each possible sources. The first found wins.
45
- Neruda::Config.sources.each do |project|
46
- project_relative_path = project['path'].sub(/^#{Dir.pwd}\//, '')
47
- return project if file_name.match?(/^#{project_relative_path}\//)
48
- end
49
- nil
50
- end
51
-
52
- def slug(title)
53
- title.downcase.tr(' ', '-')
54
- .encode('ascii', fallback: ->(k) { translit(k) })
55
- .gsub(/[^\w-]/, '').delete_suffix('-')
56
- end
57
-
58
- private
59
-
60
- def translit(char)
61
- return 'a' if ['á', 'à', 'â', 'ä', 'ǎ', 'ã', 'å'].include?(char)
62
- return 'e' if ['é', 'è', 'ê', 'ë', 'ě', 'ẽ'].include?(char)
63
- return 'i' if ['í', 'ì', 'î', 'ï', 'ǐ', 'ĩ'].include?(char)
64
- return 'o' if ['ó', 'ò', 'ô', 'ö', 'ǒ', 'õ'].include?(char)
65
- return 'u' if ['ú', 'ù', 'û', 'ü', 'ǔ', 'ũ'].include?(char)
66
- return 'y' if ['ý', 'ỳ', 'ŷ', 'ÿ', 'ỹ'].include?(char)
67
- return 'c' if char == 'ç'
68
- return 'n' if char == 'ñ'
69
- '-'
70
- end
71
- end
72
- end
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Neruda
4
- # This module holds extracter methods for the {Neruda::OrgFile} class.
5
- module OrgFileExtracter
6
- private
7
-
8
- # Main method, which will call the other to initialize an
9
- # {Neruda::OrgFile} instance.
10
- def extract_data
11
- @content = IO.read @file
12
- @title = extract_title
13
- @subtitle = extract_subtitle
14
- @date = extract_date
15
- @author = extract_author
16
- @keywords = extract_keywords
17
- @lang = extract_lang
18
- @excerpt = extract_excerpt
19
- end
20
-
21
- def extract_date
22
- timerx = '([0-9:]{5})(?::([0-9]{2}))?'
23
- m = /^#\+date: *<([0-9-]{10}) [\w.]+(?: #{timerx})?> *$/i.match(@content)
24
- return nil if m.nil?
25
- @notime = m[2].nil?
26
- if @notime
27
- time = '00:00:00'
28
- else
29
- time = "#{m[2]}:#{m[3] || '00'}"
30
- end
31
- DateTime.strptime("#{m[1]} #{time}", '%Y-%m-%d %H:%M:%S')
32
- end
33
-
34
- def extract_title
35
- m = /^#\+title:(.+)$/i.match(@content)
36
- if m.nil?
37
- # Avoid to leak absolute path
38
- project_relative_path = @file.sub(/^#{Dir.pwd}\//, '')
39
- return project_relative_path
40
- end
41
- m[1].strip
42
- end
43
-
44
- def extract_subtitle
45
- m = /^#\+subtitle:(.+)$/i.match(@content)
46
- return '' if m.nil?
47
- m[1].strip
48
- end
49
-
50
- def extract_author
51
- m = /^#\+author:(.+)$/i.match(@content)
52
- return Neruda::Config.settings['author'] if m.nil?
53
- m[1].strip
54
- end
55
-
56
- def extract_keywords
57
- m = /^#\+keywords:(.+)$/i.match(@content)
58
- return [] if m.nil?
59
- m[1].split(',').map(&:strip)
60
- end
61
-
62
- def extract_lang
63
- m = /^#\+language:(.+)$/i.match(@content)
64
- return Neruda::Config.settings['lang'] if m.nil?
65
- m[1].strip
66
- end
67
-
68
- def extract_excerpt
69
- @content.scan(/^#\+description:(.+)$/i).map { |l| l[0].strip }.join(' ')
70
- end
71
- end
72
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'neruda/config'
4
- require 'neruda/emacs'
5
-
6
- module Neruda
7
- # This module holds HTML formatter methods for the {Neruda::OrgFile}
8
- # class.
9
- module OrgFileHtmlizer
10
- private
11
-
12
- # Format {Neruda::OrgFile#keywords} list in an HTML listing.
13
- #
14
- # @return [String] the HTML keywords list
15
- def keywords_to_html
16
- domain = Neruda::Config.settings['domain']
17
- klist = @keywords.map do |k|
18
- <<~KEYWORDLINK
19
- <li class="keyword">
20
- <a href="#{domain}/tags/#{Neruda::OrgFile.slug(k)}.html">#{k}</a>
21
- </li>
22
- KEYWORDLINK
23
- end.join
24
- "<ul class=\"keywords-list\">#{klist}</ul>"
25
- end
26
-
27
- # Format {Neruda::OrgFile#date} as a HTML `time` tag.
28
- #
29
- # @return [String] the HTML `time` tag
30
- def date_to_html(dateformat = :full)
31
- return '<time></time>' if @date.nil?
32
- "<time datetime=\"#{@date.rfc3339}\">#{datestring(dateformat)}</time>"
33
- end
34
-
35
- # Format {Neruda::OrgFile#author} in a HTML `span` tag with a
36
- # specific class.
37
- #
38
- # @return [String] the author HTML `span`
39
- def author_to_html
40
- "<span class=\"author\">#{@author}</span>"
41
- end
42
- end
43
- end