ragerender 0.1.7 → 0.1.9
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/README.rdoc +44 -0
- data/inspector/.gitignore +2 -0
- data/inspector/Rakefile +51 -0
- data/inspector/_includes/field_row.html +8 -0
- data/inspector/_includes/field_rows.html +15 -0
- data/inspector/_includes/field_table.html +22 -0
- data/inspector/_templates/archive.html +3 -0
- data/inspector/_templates/blog-archive.html +3 -0
- data/inspector/_templates/blog-display.html +3 -0
- data/inspector/_templates/comic-page.html +6 -0
- data/inspector/_templates/error-page.html +3 -0
- data/inspector/_templates/overall.html +90 -0
- data/inspector/_templates/overview.html +3 -0
- data/inspector/_templates/search.html +10 -0
- data/inspector/layout.css +50 -0
- data/lib/ragerender/jekyll/archive.rb +10 -16
- data/lib/ragerender/jekyll/blog.rb +5 -0
- data/lib/ragerender/jekyll/blog_archive.rb +6 -21
- data/lib/ragerender/jekyll/chapter.rb +12 -15
- data/lib/ragerender/jekyll/comics.rb +211 -47
- data/lib/ragerender/jekyll/image.rb +78 -0
- data/lib/ragerender/jekyll/pagination.rb +28 -0
- data/lib/ragerender/jekyll/pipettes.rb +58 -1
- data/lib/ragerender/jekyll/search.rb +68 -13
- data/lib/ragerender/jekyll.rb +102 -9
- metadata +61 -2
|
@@ -7,8 +7,15 @@ require 'jekyll/document'
|
|
|
7
7
|
require 'jekyll/drops/drop'
|
|
8
8
|
require 'jekyll/drops/document_drop'
|
|
9
9
|
require_relative '../date_formats'
|
|
10
|
+
require_relative 'chapter'
|
|
11
|
+
require_relative 'image'
|
|
12
|
+
require_relative 'setup_collection'
|
|
10
13
|
require_relative 'pipettes'
|
|
11
14
|
|
|
15
|
+
Jekyll::Hooks.register :site, :after_init do |site|
|
|
16
|
+
setup_collection site, :comics, '/:collection/:slug/', layout: 'comic-page', chapter: '0'
|
|
17
|
+
end
|
|
18
|
+
|
|
12
19
|
Jekyll::Hooks.register :comics, :pre_render do |page, payload|
|
|
13
20
|
RageRender::Pipettes.clean_payload payload
|
|
14
21
|
payload.merge! RageRender::ComicDrop.new(page).to_liquid
|
|
@@ -19,16 +26,40 @@ module RageRender
|
|
|
19
26
|
|
|
20
27
|
BASE_DIR = File.join(File.dirname(__FILE__), '..', '..', '..')
|
|
21
28
|
|
|
29
|
+
# If there are any HTML pages in the /images directory, we treat these as
|
|
30
|
+
# HTML-comics where the author has specified their own HTML to use instead of
|
|
31
|
+
# a comic image. We turn these into static files so that they don't appear as
|
|
32
|
+
# extra pages.
|
|
33
|
+
class ComicHTMLToStaticFileGenerator < Jekyll::Generator
|
|
34
|
+
priority :highest
|
|
35
|
+
|
|
36
|
+
def generate site
|
|
37
|
+
site.pages.select {|f| f.relative_path.start_with? 'images' }.each do |html|
|
|
38
|
+
site.pages.delete html
|
|
39
|
+
static_file = Jekyll::StaticFile.new(
|
|
40
|
+
site,
|
|
41
|
+
html.instance_variable_get(:"@base"),
|
|
42
|
+
# Jekyll::Pages have their leading slash removed, but we need it
|
|
43
|
+
html.instance_variable_get(:"@dir").gsub(/^([^\/])/) {|s| '/' + s},
|
|
44
|
+
html.instance_variable_get(:"@name"),
|
|
45
|
+
)
|
|
46
|
+
static_file.data['content'] = html.content
|
|
47
|
+
static_file.defaults['published'] = false
|
|
48
|
+
site.static_files.append static_file
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
22
53
|
# Creates comics for each file found in the 'images' directory
|
|
23
54
|
# that does not already have an associated comic object.
|
|
24
55
|
class ComicFromImageGenerator < Jekyll::Generator
|
|
25
|
-
priority :
|
|
56
|
+
priority :high
|
|
26
57
|
|
|
27
58
|
def generate site
|
|
28
59
|
images = site.static_files.select {|f| f.relative_path.start_with? '/images' }.map {|f| [f.basename, f] }.to_h
|
|
29
60
|
comics = site.collections['comics'].docs.map {|c| [c.basename_without_ext, c] }.to_h
|
|
30
61
|
missing = Set.new(images.keys) - Set.new(comics.keys)
|
|
31
|
-
missing -= Set.new(comics.
|
|
62
|
+
missing -= Set.new(comics.flat_map {|k, c| (c.data['images'] || []) + [c.data['image']] }.reject(&:nil?).map {|img| File.basename(img, '.*') })
|
|
32
63
|
missing.each do |slug|
|
|
33
64
|
comic = Jekyll::Document.new(images[slug].relative_path, site: site, collection: site.collections['comics'])
|
|
34
65
|
comic.send(:merge_defaults)
|
|
@@ -65,12 +96,16 @@ module RageRender
|
|
|
65
96
|
|
|
66
97
|
def generate site
|
|
67
98
|
site.collections['comics'].docs.each do |comic|
|
|
68
|
-
comic.data['image'] ||= default_image_path(comic)
|
|
99
|
+
comic.data['image'] ||= default_image_path(site, comic)
|
|
69
100
|
end
|
|
70
101
|
end
|
|
71
102
|
|
|
72
|
-
def
|
|
73
|
-
|
|
103
|
+
def images site
|
|
104
|
+
@images ||= site.static_files.select {|f| f.relative_path.start_with? '/images' }.map {|f| [f.basename, f] }.to_h
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def default_image_path site, comic
|
|
108
|
+
images(site)[comic.data['slug']].relative_path
|
|
74
109
|
end
|
|
75
110
|
end
|
|
76
111
|
|
|
@@ -88,27 +123,99 @@ module RageRender
|
|
|
88
123
|
end
|
|
89
124
|
end
|
|
90
125
|
|
|
91
|
-
class
|
|
126
|
+
class PaginatedComicDrop < Jekyll::Drops::DocumentDrop
|
|
92
127
|
extend Pipettes
|
|
93
128
|
|
|
94
|
-
|
|
129
|
+
THUMBNAIL_MAX_HEIGHT = 420
|
|
130
|
+
THUMBNAIL_MAX_WIDTH = 400
|
|
131
|
+
THUMBNAIL_SMALL_MAX_HEIGHT = 210
|
|
132
|
+
THUMBNAIL_SMALL_MAX_WIDTH = 200
|
|
133
|
+
|
|
134
|
+
def initialize obj, all
|
|
135
|
+
super(obj)
|
|
136
|
+
@all = all
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def_delegators :comicdrop, :comicurl, :comictitle, :posttime
|
|
140
|
+
def_safe_delegator :chapterdrop, :chaptername, :chaptername
|
|
141
|
+
def_safe_delegator :chapterdrop, :chapterdescription, :chapterdescription
|
|
142
|
+
def_safe_delegator :chapterdrop, :chapterid, :chapterid
|
|
143
|
+
|
|
144
|
+
def number
|
|
145
|
+
@all.index(@obj) + 1
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def newchapter
|
|
149
|
+
@all.select {|c| c.data['chapter'] == @obj.data['chapter'] }.first == @obj
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def chapterend
|
|
153
|
+
@all.select {|c| c.data['chapter'] == @obj.data['chapter'] }.last == @obj
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def_delegator :comicdrop, :comicimageurl, :thumbnail_url
|
|
157
|
+
|
|
158
|
+
def thumbnail_width
|
|
159
|
+
scaled_width(comicdrop.comicwidth, comicdrop.comicheight, THUMBNAIL_MAX_WIDTH, THUMBNAIL_MAX_HEIGHT) || 0
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def thumbnail_height
|
|
163
|
+
scaled_height(comicdrop.comicwidth, comicdrop.comicheight, THUMBNAIL_MAX_WIDTH, THUMBNAIL_MAX_HEIGHT) || 0
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def thumbnail_width_small
|
|
167
|
+
scaled_width(comicdrop.comicwidth, comicdrop.comicheight, THUMBNAIL_SMALL_MAX_WIDTH, THUMBNAIL_SMALL_MAX_HEIGHT) || 0
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def thumbnail_height_small
|
|
171
|
+
scaled_height(comicdrop.comicwidth, comicdrop.comicheight, THUMBNAIL_SMALL_MAX_WIDTH, THUMBNAIL_SMALL_MAX_HEIGHT) || 0
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
private
|
|
175
|
+
def comicdrop
|
|
176
|
+
@comicdrop ||= ComicDrop.new(@obj)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def chapterdrop
|
|
180
|
+
comicdrop.send(:chapterdrop)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def index
|
|
184
|
+
@index ||= chapterdrop.send(:comics).index(@obj)
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
class ComicDrop < Jekyll::Drops::DocumentDrop
|
|
189
|
+
extend Pipettes
|
|
95
190
|
|
|
96
191
|
delegate_method_as :id, :comicid
|
|
97
192
|
def_delegator :@obj, :url, :comicurl
|
|
98
|
-
def_delegator :@obj, :url, :permalink
|
|
99
193
|
data_delegator 'rating'
|
|
100
194
|
data_delegator 'votecount'
|
|
101
195
|
|
|
196
|
+
def permalink
|
|
197
|
+
URI.join(@obj.site.config["url"], @obj.site.baseurl || '/', @obj.url).to_s
|
|
198
|
+
end
|
|
199
|
+
data_delegator 'comments'
|
|
200
|
+
|
|
102
201
|
def comictitle
|
|
103
202
|
escape @obj.data['title']
|
|
104
203
|
end
|
|
105
204
|
|
|
106
|
-
def
|
|
107
|
-
|
|
205
|
+
def comicdescription
|
|
206
|
+
escape @obj.data['description']
|
|
108
207
|
end
|
|
109
208
|
|
|
110
|
-
def
|
|
111
|
-
|
|
209
|
+
def transcript
|
|
210
|
+
escape @obj.data['transcript']
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def comickeywords
|
|
214
|
+
(@obj.data['keywords'] || []).map {|k| escape k }.join(', ')
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def comicnumber
|
|
218
|
+
1 + all_comics.index(@obj)
|
|
112
219
|
end
|
|
113
220
|
|
|
114
221
|
def posttime
|
|
@@ -123,20 +230,24 @@ module RageRender
|
|
|
123
230
|
@obj.date.month
|
|
124
231
|
end
|
|
125
232
|
|
|
126
|
-
def usechapters
|
|
127
|
-
all_comics.any? {|comic| comic.data.include? 'chapter' }
|
|
128
|
-
end
|
|
129
|
-
|
|
130
233
|
def haschapter
|
|
131
234
|
@obj.data.include? 'chapter'
|
|
132
235
|
end
|
|
133
236
|
|
|
134
|
-
|
|
135
|
-
|
|
237
|
+
def_safe_delegator :chapterdrop, :chapterid, :chapterid
|
|
238
|
+
def_safe_delegator :chapterdrop, :chaptername, :chaptername
|
|
239
|
+
def_safe_delegator :chapterdrop, :chapterdescription, :chapterdescription
|
|
240
|
+
def_safe_delegator :chapter, :url, :chapterlink
|
|
241
|
+
|
|
242
|
+
def_safe_delegator :prevchapterdrop, :url, :prevchapter
|
|
243
|
+
def_safe_delegator :nextchapterdrop, :url, :nextchapter
|
|
244
|
+
|
|
245
|
+
def isfirstcomicinchapter
|
|
246
|
+
(chapterdrop&.send(:comics) || []).first == @obj
|
|
136
247
|
end
|
|
137
248
|
|
|
138
|
-
def
|
|
139
|
-
|
|
249
|
+
def islastcomicinchapter
|
|
250
|
+
(chapterdrop&.send(:comics) || []).last == @obj
|
|
140
251
|
end
|
|
141
252
|
|
|
142
253
|
def_loop :dropdown, :is_selected, :is_disabled, :title, :grouplabel, :newgroup, :endgroup, :url
|
|
@@ -204,41 +315,67 @@ module RageRender
|
|
|
204
315
|
all_comics.last == @obj
|
|
205
316
|
end
|
|
206
317
|
|
|
207
|
-
|
|
208
|
-
|
|
318
|
+
def_safe_delegator :prevcomicdrop, :url, :prevcomic
|
|
319
|
+
def_safe_delegator :prevcomicdrop, :permalink, :prevcomicpermalink
|
|
320
|
+
def_safe_delegator :prevcomicdrop, :title, :prevcomictitle
|
|
321
|
+
|
|
322
|
+
def_safe_delegator :nextcomicdrop, :url, :nextcomic
|
|
323
|
+
def_safe_delegator :nextcomicdrop, :permalink, :nextcomicpermalink
|
|
324
|
+
def_safe_delegator :nextcomicdrop, :title, :nextcomictitle
|
|
325
|
+
|
|
326
|
+
def prevcomicbychapter
|
|
327
|
+
if isfirstcomicinchapter
|
|
328
|
+
(prevchapterdrop&.send(:comics) || []).last
|
|
329
|
+
else
|
|
330
|
+
(chapterdrop&.send(:comics) || []).each_cons(2).detect {|_, this| this == @obj }&.first
|
|
331
|
+
end&.url
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def nextcomicbychapter
|
|
335
|
+
if islastcomicinchapter
|
|
336
|
+
nextchapterdrop&.send(:first_comic)
|
|
337
|
+
else
|
|
338
|
+
(chapterdrop&.send(:comics) || []).each_cons(2).detect {|this, _| this == @obj }&.last
|
|
339
|
+
end&.url
|
|
209
340
|
end
|
|
210
341
|
|
|
211
|
-
def
|
|
212
|
-
|
|
213
|
-
|
|
342
|
+
def comicimagetype
|
|
343
|
+
if imagedrops.size > 1
|
|
344
|
+
'multiimage'
|
|
345
|
+
elsif imagedrop.send(:image_obj).extname == '.html'
|
|
346
|
+
'html'
|
|
347
|
+
else
|
|
348
|
+
'image'
|
|
214
349
|
end
|
|
215
350
|
end
|
|
216
351
|
|
|
217
|
-
def
|
|
218
|
-
|
|
352
|
+
def isimage
|
|
353
|
+
comicimagetype == 'image'
|
|
219
354
|
end
|
|
220
355
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
end
|
|
356
|
+
def_loop :comicparts, *(RageRender::ImageDrop.invokable_methods - Jekyll::Drops::DocumentDrop.invokable_methods)
|
|
357
|
+
def comicparts
|
|
358
|
+
imagedrops.map(&:to_liquid)
|
|
225
359
|
end
|
|
226
360
|
|
|
227
361
|
# An HTML tag to print for the comic image. If there is a future image, then
|
|
228
362
|
# this is also a link to the next comic page.
|
|
229
363
|
def comicimage
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
[linkopen, image, linkclose].join
|
|
364
|
+
if comicimagetype == 'multiimage'
|
|
365
|
+
<<~HTML
|
|
366
|
+
<div class="comicsegments">
|
|
367
|
+
#{imagedrops.map(&:html).join}
|
|
368
|
+
</div>
|
|
369
|
+
HTML
|
|
370
|
+
else
|
|
371
|
+
imagedrop.html
|
|
372
|
+
end
|
|
240
373
|
end
|
|
241
374
|
|
|
375
|
+
def_safe_delegator :imagedrop, :imageurl, :comicimageurl
|
|
376
|
+
def_safe_delegator :imagedrop, :width, :comicwidth, default=0
|
|
377
|
+
def_safe_delegator :imagedrop, :height, :comicheight, default=0
|
|
378
|
+
|
|
242
379
|
def keys
|
|
243
380
|
super.reject {|k| private_methods.include? k.to_sym }
|
|
244
381
|
end
|
|
@@ -258,13 +395,40 @@ module RageRender
|
|
|
258
395
|
@obj.site.collections['chapters'].docs.detect {|c| c.data['slug'] == @obj.data['chapter'] }
|
|
259
396
|
end
|
|
260
397
|
|
|
398
|
+
def nextcomicdrop
|
|
399
|
+
@obj.next_doc.nil? ? nil : ComicDrop.new(@obj.next_doc)
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
def prevcomicdrop
|
|
403
|
+
@obj.previous_doc.nil? ? nil : ComicDrop.new(@obj.previous_doc)
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
def chapterdrop
|
|
407
|
+
chapter.nil? ? nil : ChapterDrop.new(chapter)
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
def prevchapterdrop
|
|
411
|
+
chapter&.previous_doc.nil? ? nil : ChapterDrop.new(chapter.previous_doc)
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
def nextchapterdrop
|
|
415
|
+
chapter&.next_doc.nil? ? nil : ChapterDrop.new(chapter.next_doc)
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
data_delegator 'images'
|
|
261
419
|
data_delegator 'image'
|
|
262
|
-
def_image_metadata :image
|
|
263
|
-
private :image, :image_url, :image_width, :image_height
|
|
264
420
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
421
|
+
def imagedrops
|
|
422
|
+
paths = (images || []) + [image]
|
|
423
|
+
paths.reject(&:nil?).map do |image|
|
|
424
|
+
relative_path = Pathname.new('/').join(image).to_path
|
|
425
|
+
obj = @obj.site.static_files.detect {|f| f.relative_path == relative_path }
|
|
426
|
+
(paths.size > 1 ? MultiImageDrop : ImageDrop).new(obj, self)
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
def imagedrop
|
|
431
|
+
imagedrops.first
|
|
432
|
+
end
|
|
269
433
|
end
|
|
270
434
|
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require 'forwardable'
|
|
2
|
+
require 'jekyll/drops/drop'
|
|
3
|
+
require_relative 'pipettes'
|
|
4
|
+
|
|
5
|
+
module RageRender
|
|
6
|
+
class ImageDrop < Jekyll::Drops::Drop
|
|
7
|
+
extend Forwardable
|
|
8
|
+
extend Pipettes
|
|
9
|
+
|
|
10
|
+
def initialize(obj, comicdrop)
|
|
11
|
+
super(obj)
|
|
12
|
+
@comic = comicdrop
|
|
13
|
+
@image_obj = obj
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# an <img> tag containing the image, without surrounding link
|
|
17
|
+
def imageonlyhtml
|
|
18
|
+
filehtml || <<~HTML
|
|
19
|
+
<img id="comicimage" src="#{imageurl}" alt="#{comictitle}"
|
|
20
|
+
width="#{width}" height="#{height}"
|
|
21
|
+
title="#{comicdescription}">
|
|
22
|
+
HTML
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# the html contents of this loop iteration. this includes stuff like a
|
|
26
|
+
# surrounding link to the next page
|
|
27
|
+
def html
|
|
28
|
+
filehtml || [
|
|
29
|
+
nextcomic ? "<a href=\"#{nextcomic}\">" : '',
|
|
30
|
+
imageonlyhtml,
|
|
31
|
+
nextcomic ? '</a>' : '',
|
|
32
|
+
].join
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
def image
|
|
37
|
+
@obj.relative_path
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def filehtml
|
|
41
|
+
image_obj.data['content']
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def_delegators :@comic, :nextcomic, :comictitle, :comicdescription
|
|
45
|
+
private :nextcomic, :comictitle, :comicdescription
|
|
46
|
+
|
|
47
|
+
def_image_metadata :image
|
|
48
|
+
private :image_url, :image_width, :image_height
|
|
49
|
+
|
|
50
|
+
def imageurl
|
|
51
|
+
image_url unless filehtml
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
alias width image_width
|
|
55
|
+
alias height image_height
|
|
56
|
+
public :imageurl, :width, :height
|
|
57
|
+
|
|
58
|
+
def fallback_data; {}; end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
class MultiImageDrop < ImageDrop
|
|
62
|
+
def imageonlyhtml
|
|
63
|
+
<<~HTML
|
|
64
|
+
<img src="#{imageurl}" alt="#{comictitle}"
|
|
65
|
+
width="#{width}" height="#{height}"
|
|
66
|
+
title="#{comicdescription}" class="comicsegmentimage">
|
|
67
|
+
HTML
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def html
|
|
71
|
+
<<~HTML
|
|
72
|
+
<div class="segmentcontainer">
|
|
73
|
+
#{super}
|
|
74
|
+
</div>
|
|
75
|
+
HTML
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require_relative 'pipettes'
|
|
2
|
+
|
|
1
3
|
module RageRender
|
|
2
4
|
module PaginationGenerator
|
|
3
5
|
def handle_page page
|
|
@@ -27,4 +29,30 @@ module RageRender
|
|
|
27
29
|
end
|
|
28
30
|
end
|
|
29
31
|
end
|
|
32
|
+
|
|
33
|
+
class PaginatedPageDrop < Jekyll::Drops::Drop
|
|
34
|
+
extend Pipettes
|
|
35
|
+
|
|
36
|
+
def initialize obj, current_page, prev_page
|
|
37
|
+
super(obj)
|
|
38
|
+
@current = current_page
|
|
39
|
+
@prev = prev_page
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def page
|
|
43
|
+
@obj.data['number']
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def pagelink
|
|
47
|
+
@obj.permalink
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def is_current
|
|
51
|
+
page == @current.data['number']
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def skipped_ahead
|
|
55
|
+
page - @prev.data['number'] > 1
|
|
56
|
+
end
|
|
57
|
+
end
|
|
30
58
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Pipettes help you make drops.
|
|
2
2
|
require 'cgi'
|
|
3
3
|
require 'dimensions'
|
|
4
|
+
require 'jekyll/drops/document_drop'
|
|
4
5
|
|
|
5
6
|
module RageRender
|
|
6
7
|
module Pipettes
|
|
@@ -11,6 +12,16 @@ module RageRender
|
|
|
11
12
|
payload.send(:fallback_data).delete_if {|k| methods.include? k}
|
|
12
13
|
end
|
|
13
14
|
|
|
15
|
+
def own_methods
|
|
16
|
+
invokable_methods - Jekyll::Drops::DocumentDrop.invokable_methods
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def def_safe_delegator obj, key, aliaz, default=nil
|
|
20
|
+
define_method(aliaz.to_sym) do
|
|
21
|
+
send(obj.to_sym)&.send(key.to_sym) || default
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
14
25
|
def def_data_delegator key, aliaz
|
|
15
26
|
define_method(aliaz.to_sym) do
|
|
16
27
|
@obj.data[key.to_s]
|
|
@@ -35,6 +46,28 @@ module RageRender
|
|
|
35
46
|
Pathname.new(@obj.path).extname != '.html' ? escape(str) : str
|
|
36
47
|
end
|
|
37
48
|
mod.send(:private, :maybe_escape)
|
|
49
|
+
|
|
50
|
+
mod.define_method(:scaled_width) do |width, height, max_width, max_height|
|
|
51
|
+
return nil if width.nil? || height.zero?
|
|
52
|
+
|
|
53
|
+
if (height.to_f / max_height) > (width.to_f / max_width)
|
|
54
|
+
(scaled_height(width, height, max_width, max_height) * width) / height
|
|
55
|
+
else
|
|
56
|
+
[max_width, width].min
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
mod.send(:private, :scaled_width)
|
|
60
|
+
|
|
61
|
+
mod.define_method(:scaled_height) do |width, height, max_width, max_height|
|
|
62
|
+
return nil if height.nil? || width.zero?
|
|
63
|
+
|
|
64
|
+
if (height.to_f / max_height) > (width.to_f / max_width)
|
|
65
|
+
[max_height, height].min
|
|
66
|
+
else
|
|
67
|
+
(scaled_width(width, height, max_width, max_height) * height) / width
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
mod.send(:private, :scaled_height)
|
|
38
71
|
end
|
|
39
72
|
|
|
40
73
|
def def_image_metadata prefix
|
|
@@ -44,7 +77,8 @@ module RageRender
|
|
|
44
77
|
private :"#{prefix}_relative_path"
|
|
45
78
|
|
|
46
79
|
define_method(:"#{prefix}_url") do
|
|
47
|
-
|
|
80
|
+
site = @obj.instance_variable_get(:"@site") || @obj.send(:site)
|
|
81
|
+
File.join (site.baseurl || ''), send(:"#{prefix}_relative_path")
|
|
48
82
|
end
|
|
49
83
|
|
|
50
84
|
define_method(:"#{prefix}_obj") do
|
|
@@ -68,5 +102,28 @@ module RageRender
|
|
|
68
102
|
send(:"#{prefix}_obj") && (send(:"#{prefix}_obj").data['height'] ||= Dimensions.height(send(:"#{prefix}_path")) rescue nil)
|
|
69
103
|
end
|
|
70
104
|
end
|
|
105
|
+
|
|
106
|
+
def def_pages all_pages
|
|
107
|
+
define_method(:lastpagenumber) do
|
|
108
|
+
send(all_pages).size
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Objects used for laying out page numbers.
|
|
112
|
+
#
|
|
113
|
+
# The page numbers always include:
|
|
114
|
+
# - the first page
|
|
115
|
+
# - the last page
|
|
116
|
+
# - two pages around the current page
|
|
117
|
+
define_method(:pages) do
|
|
118
|
+
pages = send(all_pages)
|
|
119
|
+
[1].chain([1, pages.size, *(number-2..number+2).to_a].uniq).select {|i| i >= 1 && i <= pages.size }.sort.map do |i|
|
|
120
|
+
pages[i-1]
|
|
121
|
+
end.each_cons(2).map do |prev, page|
|
|
122
|
+
PaginatedPageDrop.new(page, @obj, prev)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def_loop :pages, *PaginatedBlogDrop.own_methods
|
|
127
|
+
end
|
|
71
128
|
end
|
|
72
129
|
end
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
require 'jekyll/generator'
|
|
2
|
+
require 'jekyll/drops/drop'
|
|
3
|
+
require_relative 'pagination'
|
|
4
|
+
|
|
1
5
|
Jekyll::Hooks.register :pages, :pre_render do |page, payload|
|
|
2
6
|
if page.data['layout'] == 'search'
|
|
3
7
|
RageRender::Pipettes.clean_payload payload
|
|
@@ -6,36 +10,87 @@ Jekyll::Hooks.register :pages, :pre_render do |page, payload|
|
|
|
6
10
|
end
|
|
7
11
|
|
|
8
12
|
module RageRender
|
|
13
|
+
RESULTS_PER_PAGE = 60
|
|
14
|
+
|
|
15
|
+
class SearchPaginationGenerator < Jekyll::Generator
|
|
16
|
+
priority :low
|
|
17
|
+
|
|
18
|
+
def generate site
|
|
19
|
+
site.pages.select {|p| p.data['layout'] == 'search' }.each do |page|
|
|
20
|
+
SearchPaginator.new(page).generate(site)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class SearchPaginator
|
|
26
|
+
include PaginationGenerator
|
|
27
|
+
|
|
28
|
+
def initialize page
|
|
29
|
+
@page = page
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def source_page site
|
|
33
|
+
@page
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def searchterm
|
|
37
|
+
@page.data['searchterm']
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def num_pages site
|
|
41
|
+
RageRender::search(site, searchterm).each_slice(RESULTS_PER_PAGE).size
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def permalink
|
|
45
|
+
"/search/id/#{searchterm.hash}/:number"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.search site, searchterm
|
|
50
|
+
return [] unless searchterm
|
|
51
|
+
site.collections['comics'].docs.reject {|c| SPECIAL_COMIC_SLUGS.include? c.data['slug'] }.select do |comic|
|
|
52
|
+
[
|
|
53
|
+
*comic.data.fetch('tags', []),
|
|
54
|
+
comic.content,
|
|
55
|
+
*comic.data.fetch('authornotes', []).flat_map {|n| n['comment'] },
|
|
56
|
+
].map(&:downcase).any? {|c| c.include?(searchterm.downcase) }
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
9
60
|
class SearchDrop < Jekyll::Drops::Drop
|
|
10
61
|
extend Pipettes
|
|
11
62
|
|
|
12
63
|
private delegate_method_as :data, :fallback_data
|
|
13
64
|
data_delegator 'searchterm'
|
|
65
|
+
data_delegator 'number'
|
|
66
|
+
private :number
|
|
14
67
|
|
|
15
68
|
def searched
|
|
16
69
|
!searchterm.nil?
|
|
17
70
|
end
|
|
18
71
|
|
|
19
|
-
def_loop :searchresults,
|
|
72
|
+
def_loop :searchresults, *PaginatedComicDrop.own_methods
|
|
20
73
|
def searchresults
|
|
21
74
|
return [] unless searched
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
comic.content,
|
|
26
|
-
*comic.data.fetch('authornotes', []).flat_map {|n| n['comment'] },
|
|
27
|
-
].map(&:downcase).any? {|c| c.include?(searchterm.downcase) }
|
|
28
|
-
end.map.each_with_index do |comic, index|
|
|
29
|
-
drop = ComicDrop.new(comic)
|
|
30
|
-
{
|
|
31
|
-
'number' => index + 1,
|
|
32
|
-
**ComicDrop::PAGINATION_FIELDS.map {|f| [f.to_s, drop[f]] }.to_h,
|
|
33
|
-
}
|
|
75
|
+
comics = all_results[number-1]
|
|
76
|
+
comics.map do |comic|
|
|
77
|
+
PaginatedComicDrop.new(comic, comics)
|
|
34
78
|
end
|
|
35
79
|
end
|
|
36
80
|
|
|
37
81
|
def foundresults
|
|
38
82
|
searchresults.any?
|
|
39
83
|
end
|
|
84
|
+
|
|
85
|
+
def_pages :all_pages
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
def all_results
|
|
89
|
+
@all_results ||= RageRender::search(@obj.site, searchterm).each_slice(RESULTS_PER_PAGE).to_a
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def all_pages
|
|
93
|
+
@obj.site.pages.select {|p| p.data['searchterm'] == searchterm && p.permalink =~ /id/ }
|
|
94
|
+
end
|
|
40
95
|
end
|
|
41
96
|
end
|