aardi 0.9.2 → 2.0.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/lib/aardi/abstract_blog.rb +9 -4
- data/lib/aardi/abstract_feed.rb +15 -3
- data/lib/aardi/abstract_page_support.rb +10 -4
- data/lib/aardi/archive.rb +24 -19
- data/lib/aardi/atom_feed.rb +11 -11
- data/lib/aardi/blog.rb +18 -12
- data/lib/aardi/config.rb +16 -12
- data/lib/aardi/content_hashes.rb +13 -6
- data/lib/aardi/custom_renderer.rb +2 -4
- data/lib/aardi/day.rb +6 -5
- data/lib/aardi/errors.rb +6 -0
- data/lib/aardi/file_target.rb +7 -8
- data/lib/aardi/folder.rb +7 -12
- data/lib/aardi/home.rb +14 -15
- data/lib/aardi/home_footer_links.rb +21 -0
- data/lib/aardi/init_files/config.yml +1 -0
- data/lib/aardi/json_feed.rb +6 -7
- data/lib/aardi/metadata.rb +36 -0
- data/lib/aardi/month.rb +12 -12
- data/lib/aardi/orphanage.rb +3 -3
- data/lib/aardi/page.rb +1 -1
- data/lib/aardi/page_content.rb +2 -2
- data/lib/aardi/page_target.rb +4 -6
- data/lib/aardi/path_servlet.rb +2 -2
- data/lib/aardi/post.rb +12 -21
- data/lib/aardi/post_bookmark_line.rb +26 -0
- data/lib/aardi/renderer.rb +42 -0
- data/lib/aardi/site.rb +11 -44
- data/lib/aardi/sitemap.rb +14 -8
- data/lib/aardi/tag_blog.rb +42 -0
- data/lib/aardi/tags.rb +61 -0
- data/lib/aardi/tasks/fixtimes.rake +2 -2
- data/lib/aardi/tasks/homepage.rake +2 -2
- data/lib/aardi/tasks/init.rake +24 -22
- data/lib/aardi/tasks/load_config.rake +1 -1
- data/lib/aardi/tasks/new.rake +2 -2
- data/lib/aardi/tasks/now.rake +1 -1
- data/lib/aardi/tasks/recent.rake +1 -1
- data/lib/aardi/tasks/render.rake +3 -1
- data/lib/aardi/tasks/server.rake +6 -6
- data/lib/aardi/tasks.rb +2 -2
- data/lib/aardi/template.rb +33 -19
- data/lib/aardi/timekeeper.rb +6 -13
- data/lib/aardi/version.rb +1 -1
- data/lib/aardi/year.rb +7 -6
- data/lib/aardi.rb +51 -41
- metadata +14 -144
- data/lib/aardi/ledger.rb +0 -15
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Aardi
|
|
4
|
+
class Metadata
|
|
5
|
+
KNOWN_KEYS = %w[Title Description Creation Updated Tags].freeze
|
|
6
|
+
|
|
7
|
+
def initialize(yaml_str = '', source = nil)
|
|
8
|
+
yaml = YAML.safe_load(yaml_str, permitted_classes: [Time])
|
|
9
|
+
@yaml = {}
|
|
10
|
+
@yaml = yaml if yaml.is_a? Hash
|
|
11
|
+
confirm_keys(source)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def creation = @yaml['Creation']
|
|
15
|
+
def description = @yaml['Description']
|
|
16
|
+
def empty? = @yaml.empty?
|
|
17
|
+
def tags = @yaml['Tags']&.split&.sort
|
|
18
|
+
def title = @yaml['Title']
|
|
19
|
+
def updated = @yaml['Updated']
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def confirm_keys(source)
|
|
24
|
+
unknown = @yaml.keys - KNOWN_KEYS
|
|
25
|
+
return if unknown.empty?
|
|
26
|
+
|
|
27
|
+
unknown.each { |key| warn "Ignored unknown declaration '#{key}'#{source_location(source)}" }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def source_location(source)
|
|
31
|
+
return '' unless source
|
|
32
|
+
|
|
33
|
+
" in #{source}"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/aardi/month.rb
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Aardi
|
|
4
|
+
# :reek:TooManyInstanceVariables
|
|
4
5
|
class Month < AbstractBlog
|
|
5
|
-
def initialize(year, key, archive_path)
|
|
6
|
+
def initialize(year, key, archive_path, tag = nil)
|
|
6
7
|
@year = year
|
|
7
8
|
@key = key
|
|
8
9
|
@archive_path = archive_path
|
|
9
|
-
@index = Hash.new { |hash, day| hash[day] = Day.new(year, self, day, archive_path) }
|
|
10
|
+
@index = Hash.new { |hash, day| hash[day] = Day.new(year, self, day, archive_path, tag) }
|
|
11
|
+
@tag = tag
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def <<(post)
|
|
13
|
-
@index[post.day] << post
|
|
15
|
+
@index[post.creation.day] << post
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
def archive_cell(month_fmt)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
return ' |' if count.zero?
|
|
20
|
+
|
|
21
|
+
"#{format(month_fmt, count:, archive_path: @archive_path, year: @year, month: self)} |"
|
|
19
22
|
end
|
|
20
23
|
|
|
21
24
|
def content
|
|
22
|
-
@content ||=
|
|
23
|
-
days_content = days.map { |day| "##{day.content}" }.join
|
|
24
|
-
"# #{title}\n#{days_content}"
|
|
25
|
-
end
|
|
25
|
+
@content ||= "# #{title}\n#{days.map { |day| "##{day.content}" }.join}"
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def count = days.sum(&:count)
|
|
@@ -31,12 +31,12 @@ module Aardi
|
|
|
31
31
|
"./#{@archive_path}/#{@year}/#{self}/index.html"
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
def
|
|
35
|
-
|
|
36
|
-
def to_s = @key.to_s.rjust(2, "0")
|
|
34
|
+
def to_s = @key.to_s.rjust(2, '0')
|
|
37
35
|
|
|
38
36
|
private
|
|
39
37
|
|
|
38
|
+
def base_title = Date.new(@year.key, @key).strftime('%B %Y')
|
|
39
|
+
|
|
40
40
|
def children
|
|
41
41
|
days
|
|
42
42
|
end
|
data/lib/aardi/orphanage.rb
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
module Aardi
|
|
4
4
|
class Orphanage
|
|
5
|
-
def
|
|
6
|
-
|
|
5
|
+
def report(html_files, generated_paths)
|
|
6
|
+
(html_files - generated_paths).each { |path| warn("Orphan: #{path}") unless ignored?(path) }
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
private
|
|
10
10
|
|
|
11
11
|
def ignored?(path)
|
|
12
|
-
|
|
12
|
+
Array(Config.fetch(:ignore_orphans)).any? { |prefix| path.start_with?(prefix) }
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
end
|
data/lib/aardi/page.rb
CHANGED
data/lib/aardi/page_content.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Aardi
|
|
|
4
4
|
class PageContent < Content
|
|
5
5
|
attr_reader :title, :metadata
|
|
6
6
|
|
|
7
|
-
def initialize(src_content, title, metadata =
|
|
7
|
+
def initialize(src_content, title, metadata = Metadata.new)
|
|
8
8
|
super(src_content)
|
|
9
9
|
@title = title
|
|
10
10
|
@metadata = metadata
|
|
@@ -15,7 +15,7 @@ module Aardi
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def output
|
|
18
|
-
@output ||= Aardi.
|
|
18
|
+
@output ||= Aardi.renderer.render(self)
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
end
|
data/lib/aardi/page_target.rb
CHANGED
|
@@ -2,15 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
module Aardi
|
|
4
4
|
class PageTarget < FileTarget
|
|
5
|
-
def write
|
|
6
|
-
super
|
|
7
|
-
Aardi.ledger[:html_files].delete(@path)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
5
|
private
|
|
11
6
|
|
|
7
|
+
# Optimization: in PageTarget first check the existing .html
|
|
8
|
+
# list rather than always rechecking the file system. But then
|
|
9
|
+
# check anyway because html_files doesn't always catch tag pages.
|
|
12
10
|
def file_exists?
|
|
13
|
-
|
|
11
|
+
@html_files.include?(@path) || File.exist?(@path)
|
|
14
12
|
end
|
|
15
13
|
end
|
|
16
14
|
end
|
data/lib/aardi/path_servlet.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require 'webrick'
|
|
4
4
|
|
|
5
5
|
module Aardi
|
|
6
6
|
class PathServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
7
7
|
def service(req, res)
|
|
8
8
|
# use index if folder
|
|
9
|
-
path = "./#{req.path}".sub(%r{/$},
|
|
9
|
+
path = "./#{req.path}".sub(%r{/$}, '/index.html')
|
|
10
10
|
|
|
11
11
|
file = path if File.exist?(path)
|
|
12
12
|
file ||= "#{path}.html" if File.exist?("#{path}.html")
|
data/lib/aardi/post.rb
CHANGED
|
@@ -7,50 +7,41 @@ module Aardi
|
|
|
7
7
|
def initialize(path)
|
|
8
8
|
@path = path
|
|
9
9
|
parse_source path
|
|
10
|
+
|
|
11
|
+
raise "#{path}: missing Creation metadata" unless metadata.creation
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def content
|
|
13
|
-
"#{@src_content}\n<div
|
|
15
|
+
@content ||= "#{@src_content}\n<div>#{PostBookmarkLine.new(self)}</div>\n"
|
|
14
16
|
end
|
|
15
17
|
|
|
16
|
-
def creation = metadata
|
|
17
|
-
|
|
18
|
-
def day = creation.day
|
|
18
|
+
def creation = metadata.creation
|
|
19
19
|
|
|
20
20
|
def feed_snippet
|
|
21
|
-
|
|
22
|
-
render_markup(clean_content).strip
|
|
21
|
+
@feed_snippet ||= Aardi.renderer.markup_feed_snippet(@src_content)
|
|
23
22
|
end
|
|
24
23
|
|
|
25
|
-
def
|
|
26
|
-
|
|
27
|
-
def name = File.basename(@path, ".*")
|
|
24
|
+
def name = File.basename(@path, '.*')
|
|
28
25
|
|
|
29
26
|
def report_field_summary
|
|
30
|
-
creation_header = creation.strftime(
|
|
27
|
+
creation_header = creation.strftime('%e %b %Y')
|
|
31
28
|
puts "#{creation_header} | #{@path} | #{title}"
|
|
32
29
|
end
|
|
33
30
|
|
|
31
|
+
def tags = metadata.tags
|
|
32
|
+
|
|
34
33
|
def target_path
|
|
35
34
|
"./#{short_target}.html"
|
|
36
35
|
end
|
|
37
36
|
|
|
38
|
-
def updated = metadata
|
|
37
|
+
def updated = metadata.updated || creation
|
|
39
38
|
|
|
40
|
-
def url = "#{
|
|
41
|
-
|
|
42
|
-
def year = creation.year
|
|
39
|
+
def url = "#{Config[:site_url]}/#{short_target}"
|
|
43
40
|
|
|
44
41
|
private
|
|
45
42
|
|
|
46
|
-
def render_markup(content)
|
|
47
|
-
ledger = Aardi.ledger
|
|
48
|
-
ledger[:custom_renderer].reset
|
|
49
|
-
ledger[:markdown_renderer].render(content)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
43
|
def short_target
|
|
53
|
-
"#{
|
|
44
|
+
"#{Config[:blog_archive_path]}/#{creation.strftime('%Y/%m/%d')}/#{name}"
|
|
54
45
|
end
|
|
55
46
|
end
|
|
56
47
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Aardi
|
|
4
|
+
class PostBookmarkLine
|
|
5
|
+
def initialize(post)
|
|
6
|
+
@post = post
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def to_s
|
|
10
|
+
%(<span class="bookmark">[<a href="#{@post.url}">bookmark</a>]#{tag_links}</span>)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def tag_links
|
|
16
|
+
tags = @post.tags
|
|
17
|
+
return '' unless tags&.any?
|
|
18
|
+
|
|
19
|
+
" #{tags.map { |tag| %(<a href="#{tags_base_url}/#{tag}/">#{tag}</a>) }.join(', ')}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def tags_base_url
|
|
23
|
+
"#{Config[:site_url]}/#{Config[:blog_tags_path]}"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Aardi
|
|
4
|
+
# :reek:TooManyInstanceVariables
|
|
5
|
+
class Renderer
|
|
6
|
+
attr_reader :content_hashes, :html_files, :sitemap
|
|
7
|
+
|
|
8
|
+
# :reek:ControlParameter
|
|
9
|
+
def initialize(html_files: nil, content_hashes: nil, sitemap: nil)
|
|
10
|
+
@html_files = html_files || Dir.glob('./**/*.html').to_set
|
|
11
|
+
@content_hashes = content_hashes || ContentHashes.new(Config[:content_hashes_path])
|
|
12
|
+
@sitemap = sitemap || Sitemap.new
|
|
13
|
+
@template = Template.new(Config[:template_path])
|
|
14
|
+
@custom_renderer = CustomRenderer.new
|
|
15
|
+
@markup_renderer = Redcarpet::Markdown.new(@custom_renderer, markup_options)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def finalize(result)
|
|
19
|
+
content_hashes.save(result)
|
|
20
|
+
Orphanage.new.report(html_files, result.keys)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def markup(content)
|
|
24
|
+
@custom_renderer.reset
|
|
25
|
+
@markup_renderer.render(content)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def markup_feed_snippet(content)
|
|
29
|
+
markup(content.sub(/\A(### .*\n)?\n+/, '')).strip
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def render(src)
|
|
33
|
+
@template.render(src)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def markup_options
|
|
39
|
+
(Config.fetch(:markup_options) || {}).transform_keys(&:to_sym)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/aardi/site.rb
CHANGED
|
@@ -3,66 +3,33 @@
|
|
|
3
3
|
module Aardi
|
|
4
4
|
class Site < AbstractBlog
|
|
5
5
|
def initialize
|
|
6
|
-
|
|
6
|
+
posts.each do |post|
|
|
7
|
+
blog << post
|
|
8
|
+
end
|
|
7
9
|
end
|
|
8
10
|
|
|
9
|
-
# :reek:FeatureEnvy
|
|
10
11
|
def blog
|
|
11
|
-
|
|
12
|
-
@blog ||= Blog.new(aardi_config[:blog_posts_path], aardi_config[:blog_archive_path])
|
|
12
|
+
@blog ||= Blog.new
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def render
|
|
16
|
-
super
|
|
17
|
-
content_hashes.write
|
|
18
|
-
warn_about_orphans
|
|
16
|
+
Aardi.renderer.finalize(super)
|
|
19
17
|
end
|
|
20
18
|
|
|
21
19
|
private
|
|
22
20
|
|
|
23
21
|
def children
|
|
24
|
-
[Folder.new(
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def content_hashes
|
|
28
|
-
@content_hashes ||= ContentHashes.new(Aardi.config[:content_hashes_path])
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def custom_renderer
|
|
32
|
-
@custom_renderer ||= CustomRenderer.new
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def html_files
|
|
36
|
-
@html_files ||= Dir.glob("./**/*.html").to_set
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def initialize_ledger
|
|
40
|
-
ledger = Aardi.ledger
|
|
41
|
-
# set up content hashes so they're in place while building out the rest
|
|
42
|
-
ledger[:content_hashes] = content_hashes
|
|
43
|
-
|
|
44
|
-
{custom_renderer:, markdown_renderer:, html_files:, sitemap:, template:}.each do |message, value|
|
|
45
|
-
ledger[message] = value
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def markdown_renderer
|
|
50
|
-
Redcarpet::Markdown.new(custom_renderer, Aardi.config[:markup_options])
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def sitemap
|
|
54
|
-
@sitemap ||= Sitemap.new
|
|
22
|
+
[Folder.new('.'), blog, Aardi.renderer.sitemap]
|
|
55
23
|
end
|
|
56
24
|
|
|
57
|
-
def
|
|
58
|
-
|
|
25
|
+
def post_paths
|
|
26
|
+
Dir.glob("#{Config[:blog_posts_path]}/**/*.md")
|
|
59
27
|
end
|
|
60
28
|
|
|
61
|
-
def
|
|
62
|
-
|
|
29
|
+
def posts
|
|
30
|
+
post_paths.map { |path| Post.new(path) }
|
|
63
31
|
end
|
|
64
32
|
|
|
65
|
-
def write_target
|
|
66
|
-
end
|
|
33
|
+
def write_target = {}
|
|
67
34
|
end
|
|
68
35
|
end
|
data/lib/aardi/sitemap.rb
CHANGED
|
@@ -4,8 +4,8 @@ module Aardi
|
|
|
4
4
|
class Sitemap
|
|
5
5
|
# :reek:NestedIterators
|
|
6
6
|
def content
|
|
7
|
-
sitemap = Nokogiri::XML::Builder.new(encoding:
|
|
8
|
-
urlset(xmlns:
|
|
7
|
+
sitemap = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do
|
|
8
|
+
urlset(xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9') do |urlset|
|
|
9
9
|
urls.each do |path, details|
|
|
10
10
|
url_details(path, details, urlset)
|
|
11
11
|
end
|
|
@@ -15,18 +15,25 @@ module Aardi
|
|
|
15
15
|
sitemap.to_xml
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
def record_mtime(path, path_mtime)
|
|
19
|
+
return unless urls.key?(path) && path_mtime
|
|
20
|
+
|
|
21
|
+
update_mtime(path, path_mtime)
|
|
22
|
+
end
|
|
23
|
+
|
|
18
24
|
def render
|
|
19
25
|
source = Content.new(content)
|
|
20
26
|
FileTarget.new(source, target_path).write
|
|
21
27
|
end
|
|
22
28
|
|
|
23
|
-
def target_path =
|
|
29
|
+
def target_path = './sitemap.xml'
|
|
24
30
|
|
|
25
31
|
def update_mtime(path, path_mtime)
|
|
26
32
|
urls[path][:lastmod] = path_mtime.iso8601
|
|
27
33
|
end
|
|
28
34
|
|
|
29
|
-
#
|
|
35
|
+
# Absent a block variable on Nokogiri::XML::Builder.new, this
|
|
36
|
+
# is called by the builder, not sitemap itself, and must be public.
|
|
30
37
|
# :reek:FeatureEnvy
|
|
31
38
|
def url_details(path, details, urlset)
|
|
32
39
|
missing_path(path) unless File.exist?("./#{path}")
|
|
@@ -39,18 +46,17 @@ module Aardi
|
|
|
39
46
|
end
|
|
40
47
|
|
|
41
48
|
def urls
|
|
42
|
-
@urls ||=
|
|
49
|
+
@urls ||= Config[:sitemap_entries].to_h { |path, cf| [path, url_values(path, cf)] }
|
|
43
50
|
end
|
|
44
51
|
|
|
45
52
|
private
|
|
46
53
|
|
|
47
54
|
def missing_path(path)
|
|
48
|
-
|
|
49
|
-
exit
|
|
55
|
+
raise MissingPathError, "#{path} is missing"
|
|
50
56
|
end
|
|
51
57
|
|
|
52
58
|
def url_values(path, changefreq)
|
|
53
|
-
{loc: "#{
|
|
59
|
+
{ loc: "#{Config[:site_url]}#{path}", changefreq: }
|
|
54
60
|
end
|
|
55
61
|
end
|
|
56
62
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Aardi
|
|
4
|
+
class TagBlog < Blog
|
|
5
|
+
# :reek:DuplicateMethodCall
|
|
6
|
+
def initialize(tag)
|
|
7
|
+
super()
|
|
8
|
+
@tag = tag
|
|
9
|
+
@blog_path = "#{Config[:blog_tags_path]}/#{tag}"
|
|
10
|
+
@archive_path = "#{@blog_path}/#{Config[:blog_archive_path]}"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def <<(post)
|
|
14
|
+
@posts << post
|
|
15
|
+
archive << post
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def count
|
|
19
|
+
@posts.count
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def index_line
|
|
23
|
+
"- #{inline_link_text}"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def inline_link_text
|
|
27
|
+
"[#{tag}](#{url}) (#{count})"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def url
|
|
31
|
+
"#{Config[:site_url]}/#{@blog_path}/"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
attr_reader :tag
|
|
37
|
+
|
|
38
|
+
def children
|
|
39
|
+
[archive, home, atom_feed, json_feed]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/aardi/tags.rb
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Aardi
|
|
4
|
+
class Tags < AbstractBlog
|
|
5
|
+
def initialize
|
|
6
|
+
@index = Hash.new { |hash, tag| hash[tag] = TagBlog.new(tag) }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def <<(post)
|
|
10
|
+
post.tags&.each do |tag|
|
|
11
|
+
@index[tag] << post
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def content
|
|
16
|
+
return "# Tags\n" if counts.empty?
|
|
17
|
+
|
|
18
|
+
"# Tags\n\n#{tag_lines.join("\n")}\n"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def empty? = @index.empty?
|
|
22
|
+
|
|
23
|
+
def inline_links
|
|
24
|
+
counts.map { |_tag, tag_blog| tag_blog.inline_link_text }.join(', ')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def target_path
|
|
28
|
+
"./#{tags_base_path}/index.html"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def title = 'Tags'
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def children
|
|
36
|
+
@index.values
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def counts
|
|
40
|
+
sorted_index
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def sorted_index
|
|
44
|
+
@sorted_index ||= @index.sort_by { |_key, tag_blog| tag_blog.count }.reverse.to_h
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def tag_lines
|
|
48
|
+
sorted_index.map { |_tag, tag_blog| tag_blog.index_line }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def tags_base_path
|
|
52
|
+
Config[:blog_tags_path]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def write_target
|
|
56
|
+
return {} if empty?
|
|
57
|
+
|
|
58
|
+
super
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
data/lib/aardi/tasks/init.rake
CHANGED
|
@@ -1,34 +1,36 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
INIT_FILES_DIR = File.expand_path(
|
|
3
|
+
INIT_FILES_DIR = File.expand_path('../init_files', __dir__)
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
unless defined?(InitTask)
|
|
6
|
+
module InitTask
|
|
7
|
+
def self.install_file(src)
|
|
8
|
+
dest = File.basename(src)
|
|
9
|
+
return puts "Skipped #{dest}" if File.exist?(dest) && !prompt_overwrite?(dest)
|
|
9
10
|
|
|
10
|
-
dest = File.basename(src)
|
|
11
|
-
|
|
12
|
-
unless File.exist?(dest)
|
|
13
11
|
FileUtils.cp(src, dest)
|
|
14
|
-
puts "
|
|
15
|
-
next
|
|
12
|
+
puts "Wrote #{dest}"
|
|
16
13
|
end
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
break
|
|
26
|
-
when "n"
|
|
27
|
-
puts "Skipped #{dest}"
|
|
28
|
-
break
|
|
15
|
+
def self.prompt_overwrite?(filename)
|
|
16
|
+
loop do
|
|
17
|
+
print "#{filename} already exists. Overwrite? [y]es / [n]o: "
|
|
18
|
+
case $stdin.gets&.strip&.downcase
|
|
19
|
+
when 'y' then return true
|
|
20
|
+
when 'n' then return false
|
|
21
|
+
end
|
|
29
22
|
end
|
|
30
23
|
end
|
|
31
24
|
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
desc('Scaffold a new Aardi site')
|
|
28
|
+
task :init do
|
|
29
|
+
Dir.glob("#{INIT_FILES_DIR}/**/*", File::FNM_DOTMATCH).each do |src|
|
|
30
|
+
next if File.directory?(src)
|
|
31
|
+
|
|
32
|
+
InitTask.install_file(src)
|
|
33
|
+
end
|
|
32
34
|
|
|
33
|
-
puts
|
|
35
|
+
puts 'Site scaffolding installed.'
|
|
34
36
|
end
|
data/lib/aardi/tasks/new.rake
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
def create_new_post
|
|
4
4
|
now = Time.now.utc
|
|
5
5
|
new_post_file = "#{now.to_i}.md"
|
|
6
|
-
new_post_path = "#{Aardi
|
|
6
|
+
new_post_path = "#{Aardi::Config[:blog_posts_path]}/#{new_post_file.hash.modulo(36).to_s(36)}/#{new_post_file}"
|
|
7
7
|
new_post_content = "Creation: #{now.iso8601}\n\n----\n### title\n\n[source](url): \"excerpt\"\n"
|
|
8
8
|
FileUtils.mkdir_p(File.dirname(new_post_path))
|
|
9
9
|
File.write(new_post_path, new_post_content)
|
|
10
10
|
puts(new_post_path)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
desc(
|
|
13
|
+
desc('Create a new blog post and reveal it in Finder')
|
|
14
14
|
task new: [:load_config] do
|
|
15
15
|
create_new_post
|
|
16
16
|
end
|
data/lib/aardi/tasks/now.rake
CHANGED