ragerender 0.1.1
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 +7 -0
- data/README.rdoc +221 -0
- data/Rakefile +10 -0
- data/assets/404.html +7 -0
- data/assets/archive-comics.html +7 -0
- data/assets/archive.html +6 -0
- data/assets/blog.html +6 -0
- data/assets/overview.html +6 -0
- data/assets/search.html +6 -0
- data/lib/ragerender/date_formats.rb +6 -0
- data/lib/ragerender/jekyll/archive.rb +147 -0
- data/lib/ragerender/jekyll/blog.rb +37 -0
- data/lib/ragerender/jekyll/blog_archive.rb +115 -0
- data/lib/ragerender/jekyll/chapter.rb +132 -0
- data/lib/ragerender/jekyll/comics.rb +230 -0
- data/lib/ragerender/jekyll/error.rb +18 -0
- data/lib/ragerender/jekyll/named_data_delegator.rb +9 -0
- data/lib/ragerender/jekyll/overview.rb +22 -0
- data/lib/ragerender/jekyll/pagination.rb +29 -0
- data/lib/ragerender/jekyll/search.rb +37 -0
- data/lib/ragerender/jekyll.rb +185 -0
- data/lib/ragerender/language.rb +77 -0
- data/lib/ragerender/to_erb.rb +50 -0
- data/lib/ragerender/to_liquid.rb +105 -0
- data/lib/ragerender.rb +7 -0
- metadata +348 -0
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'jekyll/generator'
|
2
|
+
require 'jekyll/drops/document_drop'
|
3
|
+
|
4
|
+
# Add default values for the 'unchapter' which is used to hold all comics that
|
5
|
+
# don't have a chapter.
|
6
|
+
Jekyll::Hooks.register :site, :after_init do |site|
|
7
|
+
site.config['defaults'].prepend({
|
8
|
+
'scope' => {
|
9
|
+
'path' => '_chapters/0.html',
|
10
|
+
'type' => 'chapters',
|
11
|
+
},
|
12
|
+
'values' => {
|
13
|
+
'title' => 'Unchaptered',
|
14
|
+
'description' => 'These comic pages are not part of any chapter',
|
15
|
+
},
|
16
|
+
})
|
17
|
+
end
|
18
|
+
|
19
|
+
Jekyll::Hooks.register :chapters, :pre_render do |chapter, payload|
|
20
|
+
payload.merge! RageRender::ChapterDrop.new(chapter).to_liquid
|
21
|
+
payload.merge! RageRender::ArchiveDrop.new(chapter).to_liquid
|
22
|
+
end
|
23
|
+
|
24
|
+
module RageRender
|
25
|
+
# Create chapter objects for any chapters listed in comics but that don't
|
26
|
+
# currently have an explicit page created.
|
27
|
+
class ChapterFromComicsGenerator < Jekyll::Generator
|
28
|
+
priority :high
|
29
|
+
|
30
|
+
def generate site
|
31
|
+
required = Set.new(site.collections['comics'].docs.map {|c| c.data['chapter'] }.reject(&:nil?))
|
32
|
+
existing = Set.new(site.collections['chapters'].docs.map {|c| c.data['slug'] })
|
33
|
+
missing = required - existing
|
34
|
+
missing.each do |slug|
|
35
|
+
filename = Pathname.new(site.collections['chapters'].relative_directory).join("#{slug}.html")
|
36
|
+
chapter = Jekyll::Document.new(filename.to_path, site: site, collection: site.collections['chapters'])
|
37
|
+
chapter.send(:merge_defaults)
|
38
|
+
chapter.data['slug'] ||= slug
|
39
|
+
chapter.data['title'] ||= slug
|
40
|
+
chapter.content = nil
|
41
|
+
site.collections['chapters'].docs << chapter
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Set the default cover for any chapters that don't have one to be the first
|
47
|
+
# page of the first comic in that chapter.
|
48
|
+
class DefaultCoverSetter < Jekyll::Generator
|
49
|
+
priority :lowest
|
50
|
+
|
51
|
+
def generate site
|
52
|
+
site.collections['chapters'].docs.each do |chapter|
|
53
|
+
chapter.data['image'] ||= default_cover(chapter)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def default_cover chapter
|
58
|
+
Pathname.new('/').join(first_comic(chapter).data['image']).to_path
|
59
|
+
end
|
60
|
+
|
61
|
+
def first_comic chapter
|
62
|
+
chapter.site.collections['comics'].docs.select {|c| c.data['chapter'] == chapter.data['slug'] }.first
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Values to pass to the archive layout when rendering a chapter.
|
67
|
+
class ChapterDrop < Jekyll::Drops::DocumentDrop
|
68
|
+
COVER_MAX_HEIGHT = 420
|
69
|
+
COVER_MAX_WIDTH = 300
|
70
|
+
|
71
|
+
PAGINATION_FIELDS = %w[ chaptername chapterdescription ]
|
72
|
+
|
73
|
+
delegate_method_as :data, :fallback_data
|
74
|
+
extend NamedDataDelegator
|
75
|
+
extend Forwardable
|
76
|
+
|
77
|
+
def_data_delegator :title, :chaptername
|
78
|
+
def_data_delegator :description, :chapterdescription
|
79
|
+
def_delegator :@obj, :url, :chapterarchiveurl
|
80
|
+
|
81
|
+
def cover
|
82
|
+
cover_obj.url
|
83
|
+
end
|
84
|
+
|
85
|
+
def cover_width_small
|
86
|
+
if (cover_height.to_f / COVER_MAX_HEIGHT) > (cover_width.to_f / COVER_MAX_WIDTH)
|
87
|
+
(cover_height_small * cover_width) / cover_height
|
88
|
+
else
|
89
|
+
[COVER_MAX_WIDTH, cover_width].min
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def cover_height_small
|
94
|
+
if (cover_height.to_f / COVER_MAX_HEIGHT) > (cover_width.to_f / COVER_MAX_WIDTH)
|
95
|
+
[COVER_MAX_HEIGHT, cover_height].min
|
96
|
+
else
|
97
|
+
(cover_width_small * cover_height) / cover_width
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def firstcomicinchapter
|
102
|
+
first_comic&.url
|
103
|
+
end
|
104
|
+
|
105
|
+
def to_liquid
|
106
|
+
super.reject do |k, v|
|
107
|
+
Jekyll::Drops::DocumentDrop::NESTED_OBJECT_FIELD_BLACKLIST.include? k
|
108
|
+
end.to_h
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
def cover_width
|
113
|
+
cover_obj.data['width'] ||= Dimensions.width cover_obj.path
|
114
|
+
end
|
115
|
+
|
116
|
+
def cover_height
|
117
|
+
cover_obj.data['height'] ||= Dimensions.height cover_obj.path
|
118
|
+
end
|
119
|
+
|
120
|
+
def cover_obj
|
121
|
+
@cover_obj ||= @obj.site.static_files.detect {|f| f.relative_path == cover_relative_path }
|
122
|
+
end
|
123
|
+
|
124
|
+
def cover_relative_path
|
125
|
+
Pathname.new('/').join(@obj.data['image']).to_s
|
126
|
+
end
|
127
|
+
|
128
|
+
def first_comic
|
129
|
+
@obj.site.collections['comics'].docs.select {|c| c.data['chapter'] == @obj.data['slug'] }.first
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'jekyll/generator'
|
2
|
+
require 'jekyll/document'
|
3
|
+
require 'jekyll/drops/document_drop'
|
4
|
+
require_relative '../date_formats'
|
5
|
+
require_relative 'named_data_delegator'
|
6
|
+
|
7
|
+
Jekyll::Hooks.register :comics, :pre_render do |page, payload|
|
8
|
+
payload.merge! RageRender::ComicDrop.new(page).to_liquid
|
9
|
+
end
|
10
|
+
|
11
|
+
module RageRender
|
12
|
+
SPECIAL_COMIC_SLUGS = %w{frontpage index}
|
13
|
+
|
14
|
+
# Creates comics for each file found in the 'images' directory
|
15
|
+
# that does not already have an associated comic object.
|
16
|
+
class ComicFromImageGenerator < Jekyll::Generator
|
17
|
+
priority :highest
|
18
|
+
|
19
|
+
def generate site
|
20
|
+
images = site.static_files.select {|f| f.relative_path.start_with? '/images' }.map {|f| [f.basename, f] }.to_h
|
21
|
+
comics = site.collections['comics'].docs.map {|c| [c.basename_without_ext, c] }.to_h
|
22
|
+
missing = Set.new(images.keys) - Set.new(comics.keys)
|
23
|
+
missing -= Set.new(comics.map {|k, c| c.data['image'] }.reject(&:nil?).map {|img| File.basename(img, '.*') })
|
24
|
+
missing.each do |slug|
|
25
|
+
comic = Jekyll::Document.new(images[slug].relative_path, site: site, collection: site.collections['comics'])
|
26
|
+
comic.send(:merge_defaults)
|
27
|
+
comic.data['slug'] = slug
|
28
|
+
comic.data['title'] = slug
|
29
|
+
comic.data['date'] = images[slug].modified_time
|
30
|
+
comic.data['image'] = images[slug].relative_path
|
31
|
+
comic.content = nil
|
32
|
+
site.collections['comics'].docs << comic
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# The index for the comics collection is always the latest comic.
|
38
|
+
class LatestComicGenerator < Jekyll::Generator
|
39
|
+
priority :lowest
|
40
|
+
|
41
|
+
def generate site
|
42
|
+
comics = site.collections['comics']
|
43
|
+
index = comics.docs.last.dup
|
44
|
+
index.instance_variable_set(:"@data", index.data.dup)
|
45
|
+
index.data['slug'] = 'index'
|
46
|
+
comics.docs << index
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class DefaultImageSetter < Jekyll::Generator
|
51
|
+
priority :normal
|
52
|
+
|
53
|
+
def generate site
|
54
|
+
site.collections['comics'].docs.each do |comic|
|
55
|
+
comic.data['image'] ||= default_image_path(comic)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def default_image_path comic
|
60
|
+
"images/#{comic.data['slug']}.jpg"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# If the image for this comic was inside a subdirectory, set that subdirectory
|
65
|
+
# name to be the chapter slug for this comic, if one is not already set.
|
66
|
+
class ChapterFromDirectorySetter < Jekyll::Generator
|
67
|
+
priority :low
|
68
|
+
|
69
|
+
def generate site
|
70
|
+
site.collections['comics'].docs.each do |comic|
|
71
|
+
components = Pathname.new(comic.data['image']).descend.reduce([]) {|acc, path| acc << path.basename }
|
72
|
+
chapter_slug = components.drop_while {|path| path.root? || path.to_s == 'images' }[...-1].first
|
73
|
+
comic.data['chapter'] ||= chapter_slug.to_s unless chapter_slug.nil?
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class ComicDrop < Jekyll::Drops::DocumentDrop
|
79
|
+
extend NamedDataDelegator
|
80
|
+
|
81
|
+
PAGINATION_FIELDS = %w[ comicurl comictitle posttime ]
|
82
|
+
|
83
|
+
delegate_method_as :id, :comicid
|
84
|
+
def_data_delegator :title, :comictitle
|
85
|
+
def_delegator :@obj, :url, :comicurl
|
86
|
+
data_delegator 'rating'
|
87
|
+
data_delegator 'votecount'
|
88
|
+
|
89
|
+
def posttime
|
90
|
+
comicfury_date(@obj.date)
|
91
|
+
end
|
92
|
+
|
93
|
+
def usechapters
|
94
|
+
all_comics.any? {|comic| comic.data.include? 'chapter' }
|
95
|
+
end
|
96
|
+
|
97
|
+
def haschapter
|
98
|
+
@obj.data.include? 'chapter'
|
99
|
+
end
|
100
|
+
|
101
|
+
def chaptername
|
102
|
+
chapter.data['title']
|
103
|
+
end
|
104
|
+
|
105
|
+
def chapterlink
|
106
|
+
chapter.url
|
107
|
+
end
|
108
|
+
|
109
|
+
def dropdown
|
110
|
+
all_comics.each_with_object([]) do |c, dropdown|
|
111
|
+
new_group = dropdown.last.nil? ? true : dropdown.last['grouplabel'] != c.data['chapter']
|
112
|
+
if new_group && !dropdown.last.nil? && dropdown.last['title'] == c.data['chapter']
|
113
|
+
dropdown.last['endgroup'] = true
|
114
|
+
end
|
115
|
+
|
116
|
+
in_this_chapter = @obj.data['chapter'] == c.data['chapter']
|
117
|
+
if in_this_chapter
|
118
|
+
dropdown << {
|
119
|
+
'is_selected' => @obj == c,
|
120
|
+
'is_disabled' => false,
|
121
|
+
'title' => c.data['title'],
|
122
|
+
'grouplabel' => c.data['chapter'],
|
123
|
+
'newgroup' => new_group,
|
124
|
+
'endgroup' => false,
|
125
|
+
'url' => c.url,
|
126
|
+
}
|
127
|
+
elsif new_group
|
128
|
+
dropdown << {
|
129
|
+
'is_selected' => false,
|
130
|
+
'is_disabled' => false,
|
131
|
+
'title' => c.data['chapter'],
|
132
|
+
'grouplabel' => c.data['chapter'],
|
133
|
+
'newgroup' => false,
|
134
|
+
'endgroup' => false,
|
135
|
+
'url' => c.url, # navigating to chapter just goes to first page
|
136
|
+
}
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def authornotes
|
142
|
+
@obj.data['authornotes'] || [{
|
143
|
+
'is_reply' => false,
|
144
|
+
'comment' => @obj.content,
|
145
|
+
'isguest' => false,
|
146
|
+
'avatar' => nil,
|
147
|
+
'authorname' => @obj.data['author'],
|
148
|
+
'commentanchor' => "comment-#{@obj.date.strftime('%s')}",
|
149
|
+
'posttime' => comicfury_date(@obj.date),
|
150
|
+
'profilelink' => nil, # TODO
|
151
|
+
}]
|
152
|
+
end
|
153
|
+
|
154
|
+
def custom
|
155
|
+
@obj.data.fetch('custom', {}).reject do |k, v|
|
156
|
+
v.nil? || (v.respond_to?(:empty?) && v.empty?)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def isfirstcomic
|
161
|
+
all_comics.first == @obj
|
162
|
+
end
|
163
|
+
|
164
|
+
def islastcomic
|
165
|
+
all_comics.last == @obj
|
166
|
+
end
|
167
|
+
|
168
|
+
def prevcomic
|
169
|
+
@obj.previous_doc&.url
|
170
|
+
end
|
171
|
+
|
172
|
+
def nextcomic
|
173
|
+
@obj.next_doc&.url
|
174
|
+
end
|
175
|
+
|
176
|
+
def comicimageurl
|
177
|
+
File.join (@obj.site.baseurl || ''), image_relative_path
|
178
|
+
end
|
179
|
+
|
180
|
+
def comicwidth
|
181
|
+
image_obj.data['width'] ||= Dimensions.width image_path
|
182
|
+
end
|
183
|
+
|
184
|
+
def comicheight
|
185
|
+
image_obj.data['height'] ||= Dimensions.height image_path
|
186
|
+
end
|
187
|
+
|
188
|
+
# An HTML tag to print for the comic image. If there is a future image, then
|
189
|
+
# this is also a link to the next comic page.
|
190
|
+
def comicimage
|
191
|
+
linkopen = nextcomic ? <<~HTML : ''
|
192
|
+
<a href="#{nextcomic}">
|
193
|
+
HTML
|
194
|
+
image = <<~HTML
|
195
|
+
<img id="comicimage" src="#{comicimageurl}" width="#{comicwidth}" height="#{comicheight}">
|
196
|
+
HTML
|
197
|
+
linkclose = nextcomic ? <<~HTML : ''
|
198
|
+
</a>
|
199
|
+
HTML
|
200
|
+
[linkopen, image, linkclose].join
|
201
|
+
end
|
202
|
+
|
203
|
+
def to_liquid
|
204
|
+
super.reject do |k, v|
|
205
|
+
Jekyll::Drops::DocumentDrop::NESTED_OBJECT_FIELD_BLACKLIST.include? k
|
206
|
+
end.to_h
|
207
|
+
end
|
208
|
+
|
209
|
+
private
|
210
|
+
def all_comics
|
211
|
+
@obj.collection.docs.reject {|c| SPECIAL_COMIC_SLUGS.include? c.data['slug'] }
|
212
|
+
end
|
213
|
+
|
214
|
+
def chapter
|
215
|
+
@obj.site.collections['chapters'].docs.detect {|c| c.data['slug'] == @obj.data['chapter'] }
|
216
|
+
end
|
217
|
+
|
218
|
+
def image_obj
|
219
|
+
@image_obj ||= @obj.site.static_files.detect {|f| f.relative_path == image_relative_path }
|
220
|
+
end
|
221
|
+
|
222
|
+
def image_path
|
223
|
+
image_obj.path
|
224
|
+
end
|
225
|
+
|
226
|
+
def image_relative_path
|
227
|
+
Pathname.new('/').join(@obj.data['image']).to_s
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'named_data_delegator'
|
2
|
+
|
3
|
+
Jekyll::Hooks.register :pages, :pre_render do |page, payload|
|
4
|
+
if page.data['layout'] == 'error-page'
|
5
|
+
payload.merge! RageRender::ErrorDrop.new(page).to_liquid
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module RageRender
|
10
|
+
class ErrorDrop < Jekyll::Drops::Drop
|
11
|
+
private delegate_method_as :data, :fallback_data
|
12
|
+
extend NamedDataDelegator
|
13
|
+
extend Forwardable
|
14
|
+
|
15
|
+
def_data_delegator :title, :errortitle
|
16
|
+
def_delegator :@obj, :content, :errormessage
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'jekyll/hooks'
|
2
|
+
require 'jekyll/drops/drop'
|
3
|
+
require_relative 'comics'
|
4
|
+
require_relative 'blog_archive'
|
5
|
+
|
6
|
+
# Pass the right variables to overview pages.
|
7
|
+
Jekyll::Hooks.register :pages, :pre_render do |page, payload|
|
8
|
+
if page.data['layout'] == 'overview'
|
9
|
+
payload.merge! RageRender::ComicDrop.new(page.site.collections['comics'].docs.last).to_liquid
|
10
|
+
payload.merge! RageRender::OverviewDrop.new(page).to_liquid
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module RageRender
|
15
|
+
class OverviewDrop < Jekyll::Drops::Drop
|
16
|
+
private delegate_method_as :data, :fallback_data
|
17
|
+
|
18
|
+
def latestblogs
|
19
|
+
@obj.site.posts.docs[-5..].map {|post| RageRender::PaginatedBlogDrop.new(post) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module RageRender
|
2
|
+
def self.duplicate_page page
|
3
|
+
Jekyll::Page.new(
|
4
|
+
page.site,
|
5
|
+
page.instance_variable_get(:"@base"),
|
6
|
+
page.instance_variable_get(:"@dir"),
|
7
|
+
page.name,
|
8
|
+
)
|
9
|
+
end
|
10
|
+
|
11
|
+
module PaginationGenerator
|
12
|
+
def handle_page page
|
13
|
+
end
|
14
|
+
|
15
|
+
def generate site
|
16
|
+
archive = source_page site
|
17
|
+
archive.data['number'] = 1
|
18
|
+
|
19
|
+
num_pages(site).times.each do |number|
|
20
|
+
paged_archive = RageRender.duplicate_page archive
|
21
|
+
paged_archive.data['permalink'] = permalink.gsub(/:number/, (number + 1).to_s)
|
22
|
+
paged_archive.data['number'] = number + 1
|
23
|
+
Jekyll.logger.debug 'Paginating:', paged_archive.data['permalink']
|
24
|
+
site.pages << paged_archive
|
25
|
+
handle_page paged_archive
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
Jekyll::Hooks.register :pages, :pre_render do |page, payload|
|
2
|
+
if page.data['layout'] == 'search'
|
3
|
+
payload.merge! RageRender::SearchDrop.new(page).to_liquid
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
module RageRender
|
8
|
+
class SearchDrop < Jekyll::Drops::Drop
|
9
|
+
private delegate_method_as :data, :fallback_data
|
10
|
+
data_delegator 'searchterm'
|
11
|
+
|
12
|
+
def searched
|
13
|
+
!searchterm.nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
def searchresults
|
17
|
+
return [] unless searched
|
18
|
+
@results ||= @obj.site.collections['comics'].docs.select do |comic|
|
19
|
+
[
|
20
|
+
*comic.data.fetch('tags', []),
|
21
|
+
comic.content,
|
22
|
+
*comic.data.fetch('authornotes', []).flat_map {|n| n['comment'] },
|
23
|
+
].map(&:downcase).any? {|c| c.include?(searchterm.downcase) }
|
24
|
+
end.map.each_with_index do |comic, index|
|
25
|
+
drop = ComicDrop.new(comic)
|
26
|
+
{
|
27
|
+
'number' => index + 1,
|
28
|
+
**ComicDrop::PAGINATION_FIELDS.map {|f| [f.to_s, drop[f]] }.to_h,
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def foundresults
|
34
|
+
searchresults.any?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'etc'
|
2
|
+
require 'stringio'
|
3
|
+
require 'jekyll'
|
4
|
+
require 'dimensions'
|
5
|
+
require_relative 'language'
|
6
|
+
require_relative 'to_liquid'
|
7
|
+
require_relative 'date_formats'
|
8
|
+
require_relative 'jekyll/archive'
|
9
|
+
require_relative 'jekyll/blog'
|
10
|
+
require_relative 'jekyll/blog_archive'
|
11
|
+
require_relative 'jekyll/comics'
|
12
|
+
require_relative 'jekyll/chapter'
|
13
|
+
require_relative 'jekyll/overview'
|
14
|
+
require_relative 'jekyll/error'
|
15
|
+
require_relative 'jekyll/search'
|
16
|
+
require_relative 'jekyll/named_data_delegator'
|
17
|
+
|
18
|
+
def setup_collection site, label, permalink, **kwargs
|
19
|
+
site.config['collections'][label.to_s] = {
|
20
|
+
'output' => true,
|
21
|
+
'permalink' => permalink,
|
22
|
+
}
|
23
|
+
|
24
|
+
site.config['defaults'].prepend({
|
25
|
+
'scope' => {
|
26
|
+
'path' => '',
|
27
|
+
'type' => label.to_s,
|
28
|
+
},
|
29
|
+
'values' => {
|
30
|
+
'permalink' => permalink,
|
31
|
+
**kwargs.map do |k, v|
|
32
|
+
[k.to_s, v]
|
33
|
+
end.to_h,
|
34
|
+
},
|
35
|
+
})
|
36
|
+
end
|
37
|
+
|
38
|
+
Jekyll::Hooks.register :site, :after_init do |site|
|
39
|
+
# This is obviously quite naughty for many reasons,
|
40
|
+
# but it's the only way to get the theme selected
|
41
|
+
# without requiring the user to write a config file
|
42
|
+
site.config['theme'] ||= 'ragerender'
|
43
|
+
site.config['title'] ||= File.basename(site.source)
|
44
|
+
site.config['search'] ||= true
|
45
|
+
site.config = site.config
|
46
|
+
|
47
|
+
setup_collection site, :comics, '/:collection/:slug/', layout: 'comic-page', chapter: '0'
|
48
|
+
setup_collection site, :posts, '/blogarchive/:slug/', layout: 'blog-display'
|
49
|
+
setup_collection site, :chapters, '/archive/:slug/', layout: 'archive'
|
50
|
+
|
51
|
+
site.config['defaults'].push({
|
52
|
+
'scope' => {
|
53
|
+
'path' => '',
|
54
|
+
},
|
55
|
+
'values' => {
|
56
|
+
'author' => Etc.getlogin,
|
57
|
+
}
|
58
|
+
})
|
59
|
+
end
|
60
|
+
|
61
|
+
Jekyll::Hooks.register :site, :post_read do |site|
|
62
|
+
site.layouts.each do |(name, layout)|
|
63
|
+
layout.data['layout'] = 'overall' unless name == 'overall'
|
64
|
+
layout.content = RageRender.to_liquid(RageRender::Language.parse(StringIO.new(layout.content))).join
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# The index for the site can be set by configuration
|
69
|
+
class RageRender::FrontpageGenerator < Jekyll::Generator
|
70
|
+
priority :lowest
|
71
|
+
|
72
|
+
def generate site
|
73
|
+
comics = site.collections['comics']
|
74
|
+
frontpage = site.config.fetch('frontpage', 'latest')
|
75
|
+
index = case frontpage
|
76
|
+
when 'latest'
|
77
|
+
collection = site.collections['comics'].docs
|
78
|
+
comics.docs.last
|
79
|
+
when 'first'
|
80
|
+
collection = site.collections['comics'].docs
|
81
|
+
comics.docs.first
|
82
|
+
when 'chapter'
|
83
|
+
collection = site.collections['comics'].docs
|
84
|
+
chapter = comics.docs.last.data['chapter']
|
85
|
+
comics.docs.detect {|c| c.data['chapter'] == chapter }
|
86
|
+
when 'overview'
|
87
|
+
collection = site.pages
|
88
|
+
site.pages.detect {|p| p.data["permalink"] == '/overview/index.html' }
|
89
|
+
else
|
90
|
+
collection = site.pages
|
91
|
+
site.pages.detect {|p| p.data["slug"] == frontpage }
|
92
|
+
end.dup
|
93
|
+
index.instance_variable_set(:"@destination", {site.dest => File.join(site.dest, 'index.html')})
|
94
|
+
index.instance_variable_set(:"@data", index.data.dup)
|
95
|
+
index.data['slug'] = 'frontpage'
|
96
|
+
collection << index
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
Jekyll::Hooks.register :documents, :pre_render do |doc, payload|
|
101
|
+
payload.merge! RageRender::WebcomicDrop.new(doc).to_liquid
|
102
|
+
end
|
103
|
+
|
104
|
+
Jekyll::Hooks.register :pages, :pre_render do |page, payload|
|
105
|
+
payload.merge! RageRender::WebcomicDrop.new(page).to_liquid
|
106
|
+
end
|
107
|
+
|
108
|
+
class RageRender::WebcomicDrop < Jekyll::Drops::Drop
|
109
|
+
extend Forwardable
|
110
|
+
extend RageRender::NamedDataDelegator
|
111
|
+
|
112
|
+
def self.def_config_delegator source, target
|
113
|
+
define_method(target) { @obj.site.config[source.to_s] }
|
114
|
+
end
|
115
|
+
|
116
|
+
def_config_delegator :title, :webcomicname
|
117
|
+
def_config_delegator :description, :webcomicslogan
|
118
|
+
def_config_delegator :search, :searchon
|
119
|
+
%w{bannerads allowratings showpermalinks showcomments allowcomments}.each do |var|
|
120
|
+
def_config_delegator var, var
|
121
|
+
end
|
122
|
+
|
123
|
+
def webcomicurl
|
124
|
+
@obj.site.baseurl
|
125
|
+
end
|
126
|
+
|
127
|
+
def lastupdatedmy
|
128
|
+
Time.now.strftime('%d/%m/%Y')
|
129
|
+
end
|
130
|
+
|
131
|
+
def copyrights
|
132
|
+
@obj.site.config['copyrights'].gsub('[year]', Date.today.year.to_s)
|
133
|
+
end
|
134
|
+
|
135
|
+
def banner
|
136
|
+
Pathname.new(@obj.site.baseurl || '/').join(@obj.site.config['banner'] || '').to_path
|
137
|
+
end
|
138
|
+
|
139
|
+
def webcomicavatar
|
140
|
+
Pathname.new(@obj.site.baseurl || '/').join(@obj.site.config['webcomicavatar'] || '').to_path
|
141
|
+
end
|
142
|
+
|
143
|
+
def hasblogs
|
144
|
+
@obj.site.posts.docs.any?
|
145
|
+
end
|
146
|
+
|
147
|
+
def hidefromhost
|
148
|
+
false
|
149
|
+
end
|
150
|
+
|
151
|
+
def extrapages
|
152
|
+
@obj.site.pages.reject {|page| page.data['hidden'] }.map do |page|
|
153
|
+
{'link' => page.url, 'title' => page.data['title']}
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def cfscriptcode
|
158
|
+
<<~HTML
|
159
|
+
<script type="text/javascript">
|
160
|
+
function jumpTo(place) { window.location = place; }
|
161
|
+
</script>
|
162
|
+
HTML
|
163
|
+
end
|
164
|
+
|
165
|
+
def css
|
166
|
+
css_files = @obj.site.static_files.select {|f| f.extname == '.css'}.map(&:path).to_a
|
167
|
+
css_files << Pathname.new(@obj.site.theme.includes_path).join('layout.css') unless css_files.any?
|
168
|
+
css_files.map {|f| File.read f }.join
|
169
|
+
end
|
170
|
+
|
171
|
+
delegate_method_as :url, :permalink
|
172
|
+
def_data_delegator :title, :pagetitle
|
173
|
+
|
174
|
+
def iscomicpage
|
175
|
+
@obj.type == :comics
|
176
|
+
end
|
177
|
+
|
178
|
+
def isextrapage
|
179
|
+
@obj.type == :pages && @obj.data['hidden'] != true
|
180
|
+
end
|
181
|
+
|
182
|
+
def fallback_data
|
183
|
+
{}
|
184
|
+
end
|
185
|
+
end
|