wax_tasks 0.3.2 → 1.0.0.pre.beta
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/Gemfile +1 -1
- data/lib/tasks/derivatives_iiif.rake +21 -0
- data/lib/tasks/derivatives_simple.rake +13 -0
- data/lib/tasks/jspackage.rake +6 -3
- data/lib/tasks/pagemaster.rake +3 -3
- data/lib/tasks/push.rake +3 -3
- data/lib/wax_tasks/branch.rb +3 -0
- data/lib/wax_tasks/collection.rb +41 -14
- data/lib/wax_tasks/error.rb +8 -0
- data/lib/wax_tasks/iiif/derivatives.rb +86 -0
- data/lib/wax_tasks/iiif/manifest.rb +26 -0
- data/lib/wax_tasks/image_collection.rb +137 -0
- data/lib/wax_tasks/lunr/index.rb +82 -0
- data/lib/wax_tasks/lunr/page_set.rb +57 -0
- data/lib/wax_tasks/pagemaster_collection.rb +14 -21
- data/lib/wax_tasks/task_runner.rb +35 -23
- data/lib/wax_tasks/utils.rb +10 -13
- data/lib/wax_tasks.rb +20 -14
- data/spec/setup.rb +2 -2
- data/spec/spec_helper.rb +2 -2
- metadata +20 -16
- data/lib/tasks/iiif.rake +0 -11
- data/lib/wax_tasks/iiif_collection.rb +0 -105
- data/lib/wax_tasks/lunr_collection.rb +0 -62
- data/lib/wax_tasks/lunr_index.rb +0 -67
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6df6c21281405044f2958da14b8eda608a4a265337f684c1371612817468767a
|
4
|
+
data.tar.gz: f1a7248a2b83fa1cf34cfd15580baecdefdd91601c7328b987d9ac247316e154
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a2c5464d13a57208f0c79bbf44a4355b6fad5efd3d2e511ad30ce7a0b4075321868a906a70b680b76ced742d5394fb758a746aff42f0601ea9137ad774dd448
|
7
|
+
data.tar.gz: 87e84935bcda6fcc92bab5a5fecc7b8fec29d19e3348b6b1f0404dd3b6e47595b778a1b7a25562e0ce7b5c187c700be7c9c20a728bc7adbf98284bba26e7b691
|
data/Gemfile
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'wax_tasks'
|
2
|
+
|
3
|
+
namespace :wax do
|
4
|
+
namespace :derivatives do
|
5
|
+
desc 'generate iiif derivatives from local image files'
|
6
|
+
task :iiif do
|
7
|
+
arguments = ARGV.drop(1).each { |a| task a.to_sym }
|
8
|
+
raise WaxTasks::Error::MissingArguments, "You must specify a collection after 'wax:derivatives:iiif'" if arguments.empty?
|
9
|
+
task_runner = WaxTasks::TaskRunner.new
|
10
|
+
task_runner.derivatives_iiif(arguments)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# alias wax:iiif to wax:derivatives:iiif for backwards compatibility
|
15
|
+
task :iiif do
|
16
|
+
t = Rake::Task['wax:derivatives:iiif']
|
17
|
+
desc t.full_comment if t.full_comment
|
18
|
+
arguments = ARGV.drop(1).each { |a| task a.to_sym }
|
19
|
+
t.invoke(*arguments)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'wax_tasks'
|
2
|
+
|
3
|
+
namespace :wax do
|
4
|
+
namespace :derivatives do
|
5
|
+
desc 'generate iiif derivatives from local image files'
|
6
|
+
task :simple do
|
7
|
+
arguments = ARGV.drop(1).each { |a| task a.to_sym }
|
8
|
+
raise WaxTasks::Error::MissingArguments, "You must specify a collection after 'wax:derivatives:simple'" if arguments.empty?
|
9
|
+
task_runner = WaxTasks::TaskRunner.new
|
10
|
+
task_runner.derivatives_simple(arguments)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/tasks/jspackage.rake
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'json'
|
1
2
|
require 'wax_tasks'
|
2
3
|
|
3
4
|
namespace :wax do
|
@@ -6,9 +7,11 @@ namespace :wax do
|
|
6
7
|
task_runner = WaxTasks::TaskRunner.new
|
7
8
|
package = task_runner.js_package
|
8
9
|
unless package.empty?
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
src_dir = task_runner.site[:source_dir]
|
11
|
+
path = WaxTasks::Utils.root_path(src_dir, 'package.json')
|
12
|
+
|
13
|
+
puts "Writing javascript dependencies to #{path}".cyan
|
14
|
+
File.open(path, 'w') { |f| f.write(JSON.pretty_generate(package)) }
|
12
15
|
end
|
13
16
|
end
|
14
17
|
end
|
data/lib/tasks/pagemaster.rake
CHANGED
@@ -3,9 +3,9 @@ require 'wax_tasks'
|
|
3
3
|
namespace :wax do
|
4
4
|
desc 'generate collection md pages from yaml or csv data source'
|
5
5
|
task :pagemaster do
|
6
|
-
|
7
|
-
raise 'You must specify a collection after wax:pagemaster' if
|
6
|
+
arguments = ARGV.drop(1).each { |a| task a.to_sym }
|
7
|
+
raise WaxTasks::Error::MissingArguments, 'You must specify a collection after wax:pagemaster' if arguments.empty?
|
8
8
|
task_runner = WaxTasks::TaskRunner.new
|
9
|
-
task_runner.pagemaster(
|
9
|
+
task_runner.pagemaster(arguments)
|
10
10
|
end
|
11
11
|
end
|
data/lib/tasks/push.rake
CHANGED
@@ -3,10 +3,10 @@ require 'wax_tasks'
|
|
3
3
|
namespace :wax do
|
4
4
|
desc 'push compiled Jekyll site to git branch BRANCH'
|
5
5
|
task :push do
|
6
|
-
|
7
|
-
raise 'You must specify a branch after
|
6
|
+
arguments = ARGV.drop(1).each { |a| task a.to_sym }
|
7
|
+
raise WaxTasks::Error::MissingArguments, 'You must specify a branch after wax:push' if arguments.empty?
|
8
8
|
|
9
9
|
task_runner = WaxTasks::TaskRunner.new
|
10
|
-
task_runner.push_branch(
|
10
|
+
task_runner.push_branch(arguments.first)
|
11
11
|
end
|
12
12
|
end
|
data/lib/wax_tasks/branch.rb
CHANGED
@@ -24,9 +24,11 @@ module WaxTasks
|
|
24
24
|
|
25
25
|
# @param site [Hash] the site config from (TaskRunner.site)
|
26
26
|
# @param target [String] the name of the Git branch to deploy to
|
27
|
+
# @param time [String] message with the time of deployment
|
27
28
|
def initialize(site, target)
|
28
29
|
@site = site
|
29
30
|
@target = target
|
31
|
+
@time = Time.now.strftime('Updated at %H:%M on %Y-%m-%d')
|
30
32
|
end
|
31
33
|
|
32
34
|
# Rebuild the Jekyll site with branch @baseurl
|
@@ -54,6 +56,7 @@ module WaxTasks
|
|
54
56
|
rebuild if @target == 'gh-pages'
|
55
57
|
raise Error::MissingSite, "Cannot find #{WaxTasks::SITE_DIR}" unless Dir.exist? WaxTasks::SITE_DIR
|
56
58
|
Dir.chdir(SITE_DIR)
|
59
|
+
File.open('.info', 'w') { |f| f.write(@time) }
|
57
60
|
system 'git init && git add .'
|
58
61
|
system "git commit -m '#{@commit_msg}'"
|
59
62
|
system "git remote add origin #{@origin}"
|
data/lib/wax_tasks/collection.rb
CHANGED
@@ -3,13 +3,8 @@ module WaxTasks
|
|
3
3
|
# that cannot be created directly. Only child classes
|
4
4
|
# (IiifCollection, LunrCollection, PagemasterCollection)
|
5
5
|
# can be initialized.
|
6
|
-
#
|
7
|
-
# @attr config [Hash] the collection config within site config
|
8
|
-
# @attr name [String] the name of the collection in site:collections
|
9
|
-
# @attr page_dir [String] the directory path for generated collection pages
|
10
|
-
# @attr site [Hash] the site config
|
11
6
|
class Collection
|
12
|
-
|
7
|
+
attr_accessor :name, :site
|
13
8
|
private_class_method :new
|
14
9
|
|
15
10
|
# This method ensures child classes can be instantiated though
|
@@ -18,28 +13,41 @@ module WaxTasks
|
|
18
13
|
public_class_method :new
|
19
14
|
end
|
20
15
|
|
21
|
-
# Creates a new collection with name @name given site
|
16
|
+
# Creates a new collection with name @name given site configuration @site
|
22
17
|
#
|
23
|
-
# @param
|
24
|
-
# @param
|
18
|
+
# @param name [String] name of the collection in site:collections
|
19
|
+
# @param site [Hash] site config
|
25
20
|
def initialize(name, site)
|
26
21
|
@name = name
|
27
22
|
@site = site
|
28
|
-
@config =
|
29
|
-
@page_dir = Utils.make_path(@site[:source_dir],
|
30
|
-
@site[:collections_dir],
|
31
|
-
"_#{@name}")
|
23
|
+
@config = self.config
|
32
24
|
end
|
33
25
|
|
34
26
|
# Finds the collection config within the site config
|
35
27
|
#
|
36
28
|
# @return [Hash] the config for the collection
|
37
|
-
def
|
29
|
+
def config
|
38
30
|
@site[:collections].fetch(@name)
|
39
31
|
rescue StandardError => e
|
40
32
|
raise Error::InvalidCollection, "Cannot load collection config for #{@name}.\n#{e}"
|
41
33
|
end
|
42
34
|
|
35
|
+
# Returns the target directory for generated collection pages
|
36
|
+
#
|
37
|
+
# @return [String] path
|
38
|
+
def page_dir
|
39
|
+
WaxTasks::Utils.root_path(@site[:source_dir], @site[:collections_dir], "_#{@name}")
|
40
|
+
end
|
41
|
+
|
42
|
+
# Constructs the path to the data source file
|
43
|
+
#
|
44
|
+
# @return [String] the path to the data source file
|
45
|
+
def metadata_source_path
|
46
|
+
source = @config.dig('metadata', 'source')
|
47
|
+
raise WaxTasks::Error::MissingSource, "Missing collection source in _config.yml for #{@name}" if source.nil?
|
48
|
+
WaxTasks::Utils.root_path(@site[:source_dir], '_data', source)
|
49
|
+
end
|
50
|
+
|
43
51
|
# Ingests the collection source data as an Array of Hashes
|
44
52
|
#
|
45
53
|
# @param source [String] the path to the CSV, JSON, or YAML source file
|
@@ -61,5 +69,24 @@ module WaxTasks
|
|
61
69
|
WaxTasks::Utils.assert_pids(data)
|
62
70
|
WaxTasks::Utils.assert_unique(data)
|
63
71
|
end
|
72
|
+
|
73
|
+
# @return [Nil]
|
74
|
+
def overwrite_metadata
|
75
|
+
src = self.metadata_source_path
|
76
|
+
puts "Writing image derivative info #{src}.".cyan
|
77
|
+
case File.extname(src)
|
78
|
+
when '.csv'
|
79
|
+
keys = @metadata.map(&:keys).inject(&:|)
|
80
|
+
csv_string = keys.to_csv
|
81
|
+
@metadata.each { |h| csv_string += h.values_at(*keys).to_csv }
|
82
|
+
File.open(src, 'w') { |f| f.write(csv_string) }
|
83
|
+
when '.json'
|
84
|
+
File.open(src, 'w') { |f| f.write(JSON.pretty_generate(@metadata)) }
|
85
|
+
when /\.ya?ml/
|
86
|
+
File.open(src, 'w') { |f| f.write(@metadata.to_yaml) }
|
87
|
+
else
|
88
|
+
raise Error::InvalidSource
|
89
|
+
end
|
90
|
+
end
|
64
91
|
end
|
65
92
|
end
|
data/lib/wax_tasks/error.rb
CHANGED
@@ -8,6 +8,10 @@ module WaxTasks
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
# Custom Error:
|
12
|
+
# Rake task expects arguments, found none
|
13
|
+
class MissingArguments < WaxTasksError; end
|
14
|
+
|
11
15
|
# Custom Error:
|
12
16
|
# Site config cannot be found / parsed
|
13
17
|
class InvalidSiteConfig < WaxTasksError; end
|
@@ -67,5 +71,9 @@ module WaxTasks
|
|
67
71
|
# Custom Error:
|
68
72
|
# Cannot find _site directory to push to GitHub
|
69
73
|
class MissingSite < WaxTasksError; end
|
74
|
+
|
75
|
+
# Custom Error:
|
76
|
+
# Cannot find IIIF source image files
|
77
|
+
class MissingIiifSrc < WaxTasksError; end
|
70
78
|
end
|
71
79
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module WaxTasks
|
2
|
+
# Module of helper functions for WaxTasks::IiiifCollection class
|
3
|
+
module Iiif
|
4
|
+
# Helpers for creating Iiif derivatives for a Collection
|
5
|
+
# via `wax:derivatives:iiif` Rake task
|
6
|
+
module Derivatives
|
7
|
+
# @return [Hash] base WaxIiif::ImageRecord opts from item
|
8
|
+
def base_opts(item)
|
9
|
+
opts = { is_primary: false }
|
10
|
+
opts[:description] = item.dig(description).to_s unless description.nil?
|
11
|
+
opts[:attribution] = item.dig(attribution).to_s unless attribution.nil?
|
12
|
+
opts[:logo] = "{{ '#{logo}' | absolute_url }}" unless logo.nil?
|
13
|
+
opts
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Array] Set of WaxIiif::ImageRecords
|
17
|
+
def iiif_records(source_data)
|
18
|
+
records = []
|
19
|
+
source_data.each do |d|
|
20
|
+
item = @metadata.detect { |m| m['pid'] == d[:pid] } || {}
|
21
|
+
opts = base_opts(item)
|
22
|
+
if d[:images].length == 1
|
23
|
+
opts[:id] = d[:pid]
|
24
|
+
opts[:path] = d[:images].first
|
25
|
+
opts[:label] = item.fetch(label.to_s, d[:pid])
|
26
|
+
opts[:is_primary] = true
|
27
|
+
|
28
|
+
records << WaxIiif::ImageRecord.new(opts)
|
29
|
+
else
|
30
|
+
item_records = []
|
31
|
+
d[:images].each do |i|
|
32
|
+
img_id = File.basename(i, '.*').to_s
|
33
|
+
|
34
|
+
opts[:id] = "#{d[:pid]}_#{img_id}"
|
35
|
+
opts[:manifest_id] = d[:pid]
|
36
|
+
opts[:path] = i
|
37
|
+
opts[:label] = item.fetch(label.to_s, d[:pid])
|
38
|
+
opts[:section_label] = img_id
|
39
|
+
|
40
|
+
item_records << WaxIiif::ImageRecord.new(opts)
|
41
|
+
end
|
42
|
+
item_records.first.is_primary = true
|
43
|
+
records += item_records
|
44
|
+
end
|
45
|
+
records.flatten
|
46
|
+
end
|
47
|
+
records
|
48
|
+
end
|
49
|
+
|
50
|
+
# Opens IIIF JSON files and prepends yaml front matter
|
51
|
+
# So that liquid vars can be read by Jekyll
|
52
|
+
#
|
53
|
+
# @return [Nil]
|
54
|
+
def add_yaml_front_matter(dir)
|
55
|
+
Dir["#{dir}/**/*.json"].each do |file|
|
56
|
+
front_matter = "---\nlayout: none\n---\n"
|
57
|
+
filestring = File.read(file)
|
58
|
+
next if filestring.start_with?(front_matter)
|
59
|
+
begin
|
60
|
+
json = JSON.parse(filestring)
|
61
|
+
File.open(file, 'w') do |f|
|
62
|
+
f.puts(front_matter)
|
63
|
+
f.puts(JSON.pretty_generate(json))
|
64
|
+
end
|
65
|
+
rescue StandardError => e
|
66
|
+
raise Error::InvalidJSON, "IIIF JSON in #{file} is invalid.\n#{e}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [Nil]
|
72
|
+
def add_iiif_derivative_info_to_metadata(manifests)
|
73
|
+
manifests.map do |m|
|
74
|
+
json = JSON.parse(m.to_json)
|
75
|
+
pid = m.base_id
|
76
|
+
@metadata.find { |i| i['pid'] == pid }.tap do |hash|
|
77
|
+
hash['manifest'] = Utils.rm_liquid(json['@id'])
|
78
|
+
hash['thumbnail'] = Utils.rm_liquid(json['thumbnail'])
|
79
|
+
hash['full'] = hash['thumbnail'].sub('250,/0', '1140,/0')
|
80
|
+
end
|
81
|
+
end
|
82
|
+
overwrite_metadata
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module WaxTasks
|
2
|
+
module Iiif
|
3
|
+
# Module for handling metadata in IIIF manifests
|
4
|
+
module Manifest
|
5
|
+
# @return [String]
|
6
|
+
def label
|
7
|
+
@image_config.dig('iiif', 'label')
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [String]
|
11
|
+
def description
|
12
|
+
@image_config.dig('iiif', 'description')
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [String]
|
16
|
+
def attribution
|
17
|
+
@image_config.dig('iiif', 'attribution')
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [String]
|
21
|
+
def logo
|
22
|
+
@image_config.dig('iiif', 'logo')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'wax_iiif'
|
2
|
+
require 'mini_magick'
|
3
|
+
|
4
|
+
require_relative 'iiif/derivatives'
|
5
|
+
require_relative 'iiif/manifest'
|
6
|
+
|
7
|
+
module WaxTasks
|
8
|
+
# A Jekyll collection with image configuration + data
|
9
|
+
class ImageCollection < Collection
|
10
|
+
attr_reader :output_dir, :metadata, :data
|
11
|
+
|
12
|
+
include WaxTasks::Iiif::Derivatives
|
13
|
+
include WaxTasks::Iiif::Manifest
|
14
|
+
|
15
|
+
# Creates a new IiifCollection with name @name given site config @site
|
16
|
+
def initialize(name, site)
|
17
|
+
super(name, site)
|
18
|
+
|
19
|
+
@image_config = @config.dig('images')
|
20
|
+
|
21
|
+
raise Error::InvalidCollection, "No image configuration found for collection '#{@name}'" if @image_config.nil?
|
22
|
+
|
23
|
+
@data_source = self.image_source_directory
|
24
|
+
@output_dir = Utils.root_path(@site[:source_dir], DEFAULT_DERIVATIVE_DIR)
|
25
|
+
@data = self.image_data
|
26
|
+
@metadata = ingest_file(self.metadata_source_path)
|
27
|
+
@variants = WaxTasks::DEFAULT_IMAGE_VARIANTS
|
28
|
+
end
|
29
|
+
|
30
|
+
# Combines and described source image data including:
|
31
|
+
# single image items, items from subdirectories of images,
|
32
|
+
# and pdf documents.
|
33
|
+
#
|
34
|
+
# @return [Array] array of hashes relating item pids to image asset paths
|
35
|
+
def image_data
|
36
|
+
[single_image_items, multi_image_items, pdf_items].flatten.compact
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [String]
|
40
|
+
def image_source_directory
|
41
|
+
source = @image_config.dig('source')
|
42
|
+
raise WaxIiif::Error::InvalidImageData, 'No image source directory specified.' if source.nil?
|
43
|
+
path_to_image_source = Utils.root_path(@site[:source_dir], '_data/', source, '/')
|
44
|
+
raise Error::MissingIiifSrc, "Cannot find IIIF source directory #{path_to_image_source}" unless Dir.exist?(path_to_image_source)
|
45
|
+
raise Error::MissingIiifSrc, "No IIIF source data was found in #{path_to_image_source}" if Dir["#{path_to_image_source}/*"].empty?
|
46
|
+
path_to_image_source
|
47
|
+
end
|
48
|
+
|
49
|
+
# Gets the items with 1 image asset
|
50
|
+
#
|
51
|
+
# @return [Array] array of hashes relating pids to image paths
|
52
|
+
def single_image_items
|
53
|
+
Dir["#{@data_source}*.{jpg, jpeg, tiff, png}"].map do |d|
|
54
|
+
{ pid: File.basename(d, '.*'), images: [d] }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Gets the items with multiple image assets
|
59
|
+
#
|
60
|
+
# @return [Array] array of hashes relating pids to image paths
|
61
|
+
def multi_image_items
|
62
|
+
Dir["#{@data_source}*/"].map do |d|
|
63
|
+
images = Dir["#{d}*.{jpg, jpeg, tiff, png}"]
|
64
|
+
{ pid: File.basename(d, '.*'), images: images.sort }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Gets the items from pdf documents
|
69
|
+
#
|
70
|
+
# @return [Array] array of hashes relating pids to image paths
|
71
|
+
def pdf_items
|
72
|
+
Dir["#{@data_source}*.pdf"].map do |d|
|
73
|
+
pid = File.basename(d, '.pdf')
|
74
|
+
dir = "#{@data_source}/#{pid}"
|
75
|
+
next if Dir.exist?(dir)
|
76
|
+
{ pid: pid, images: split_pdf(d) }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
#
|
82
|
+
# @return [Array] array of image paths generated from pdf split
|
83
|
+
def split_pdf(pdf)
|
84
|
+
split_opts = { output_dir: @data_source, verbose: true }
|
85
|
+
WaxIiif::Utilities::PdfSplitter.split(pdf, split_opts).sort
|
86
|
+
end
|
87
|
+
|
88
|
+
def build_simple_derivatives
|
89
|
+
simple_output_dir = "#{@output_dir}/simple"
|
90
|
+
@data.each do |d|
|
91
|
+
d[:images].each_with_index do |img, index|
|
92
|
+
asset_id = img.gsub(@data_source, '').gsub('.jpg', '').tr('/', '_')
|
93
|
+
asset_path = "#{simple_output_dir}/#{asset_id}"
|
94
|
+
item_record = @metadata.find { |record| record['pid'] == d[:pid] }
|
95
|
+
|
96
|
+
FileUtils.mkdir_p(asset_path)
|
97
|
+
|
98
|
+
@variants.each do |label, width|
|
99
|
+
variant_path = "#{asset_path}/#{label}.jpg"
|
100
|
+
unless item_record.nil? || index.positive?
|
101
|
+
item_record[label.to_s] = variant_path.gsub(/^./, '')
|
102
|
+
end
|
103
|
+
next puts "skipping #{variant_path}" if File.exist?(variant_path)
|
104
|
+
|
105
|
+
image = MiniMagick::Image.open(img)
|
106
|
+
image.resize(width)
|
107
|
+
image.format('jpg')
|
108
|
+
image.write(variant_path)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
self.overwrite_metadata
|
113
|
+
end
|
114
|
+
|
115
|
+
# Creates a WaxIiif::Builder object,
|
116
|
+
# builds the IIIF derivatives and json, and
|
117
|
+
# makes them usable for Jekyll/Wax
|
118
|
+
#
|
119
|
+
# @return [Nil]
|
120
|
+
def build_iiif_derivatives
|
121
|
+
iiif_output_dir = "#{@output_dir}/iiif"
|
122
|
+
jekyll_prefix = "{{ '' | absolute_url }}/#{DEFAULT_DERIVATIVE_DIR}/iiif"
|
123
|
+
build_opts = {
|
124
|
+
base_url: jekyll_prefix,
|
125
|
+
output_dir: iiif_output_dir,
|
126
|
+
variants: DEFAULT_IMAGE_VARIANTS,
|
127
|
+
verbose: true,
|
128
|
+
collection_label: @name
|
129
|
+
}
|
130
|
+
builder = WaxIiif::Builder.new(build_opts)
|
131
|
+
builder.load(iiif_records(@data))
|
132
|
+
builder.process_data
|
133
|
+
add_iiif_derivative_info_to_metadata(builder.manifests)
|
134
|
+
add_yaml_front_matter(iiif_output_dir)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative 'page_set'
|
2
|
+
|
3
|
+
module WaxTasks
|
4
|
+
module Lunr
|
5
|
+
# A Lunr::Index document that combines data from all collections
|
6
|
+
# in site config that have `lunr_index` parameters.
|
7
|
+
#
|
8
|
+
# @attr collections [Array] a list of LunrCollection objects
|
9
|
+
# @attr fields [Array] shared list of fields to index among LunrCollections
|
10
|
+
class Index
|
11
|
+
attr_reader :collections, :index_path, :fields
|
12
|
+
|
13
|
+
# Creates a new LunrIndex object
|
14
|
+
def initialize(site, index_path, collections)
|
15
|
+
raise Error::NoLunrCollections, 'No collections were configured to index' if collections.nil?
|
16
|
+
raise Error::NoLunrCollections, 'No path was given for index file' if index_path.nil?
|
17
|
+
|
18
|
+
@collections = collections.keys.map! do |c|
|
19
|
+
Lunr::PageSet.new(c, collections[c], site)
|
20
|
+
end
|
21
|
+
|
22
|
+
@index_path = index_path
|
23
|
+
@fields = self.total_fields
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Array] shared list of fields to index among indexed collections
|
27
|
+
def total_fields
|
28
|
+
@collections.map { |c| c.data.map(&:keys) }.flatten.uniq
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [String] writes index as pretty JSON with YAML front-matter
|
32
|
+
def to_s
|
33
|
+
data = @collections.map(&:data).flatten
|
34
|
+
data.each_with_index.map { |m, id| m['lunr_index'] = id }
|
35
|
+
"---\nlayout: none\n---\n#{JSON.pretty_generate(data)}"
|
36
|
+
end
|
37
|
+
|
38
|
+
# Creates a default LunrUI / JS file for displaying the Index
|
39
|
+
#
|
40
|
+
# @return [String]
|
41
|
+
def default_ui
|
42
|
+
<<~HEREDOC
|
43
|
+
---
|
44
|
+
layout: none
|
45
|
+
---
|
46
|
+
$.getJSON("{{ '#{@index_path}' | absolute_url }}", function(index_json) {
|
47
|
+
window.index = new elasticlunr.Index;
|
48
|
+
window.store = index_json;
|
49
|
+
index.saveDocument(false);
|
50
|
+
index.setRef('lunr_index');
|
51
|
+
#{@fields.map { |f| "index.addField('#{f}');" }.join("\n\t")}
|
52
|
+
// add docs
|
53
|
+
for (i in store){
|
54
|
+
index.addDoc(store[i]);
|
55
|
+
}
|
56
|
+
$('input#search').on('keyup', function() {
|
57
|
+
var results_div = $('#results');
|
58
|
+
var query = $(this).val();
|
59
|
+
var results = index.search(query, { boolean: 'AND', expand: true });
|
60
|
+
results_div.empty();
|
61
|
+
for (var r in results) {
|
62
|
+
var ref = results[r].ref;
|
63
|
+
var item = store[ref];
|
64
|
+
var pid = item.pid;
|
65
|
+
var label = item.label;
|
66
|
+
var meta = `#{@fields.except(%w[pid label]).take(3).map { |f| "${item.#{f}}" }.join(' | ')}`;
|
67
|
+
if ('thumbnail' in item) {
|
68
|
+
var thumb = `<img class='sq-thumb-sm' src='{{ "" | absolute_url }}${item.thumbnail}'/> `
|
69
|
+
}
|
70
|
+
else {
|
71
|
+
var thumb = '';
|
72
|
+
}
|
73
|
+
var result = `<div class="result"><a href="${item.link}">${thumb}<p><span class="title">${item.label}</span><br>${meta}</p></a></p></div>`;
|
74
|
+
results_div.append(result);
|
75
|
+
}
|
76
|
+
});
|
77
|
+
});
|
78
|
+
HEREDOC
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module WaxTasks
|
2
|
+
module Lunr
|
3
|
+
# Class representing a directory of markdown pages
|
4
|
+
# to be indexed by a Lunr::Index
|
5
|
+
class PageSet
|
6
|
+
attr_reader :data
|
7
|
+
|
8
|
+
def initialize(name, config, site)
|
9
|
+
@name = name
|
10
|
+
@fields = config.dig('fields')
|
11
|
+
|
12
|
+
raise Error::MissingFields, "Cannot find fields to index collection #{@name}" if @fields.nil?
|
13
|
+
|
14
|
+
@content = !!config.dig('content')
|
15
|
+
@page_dir = Utils.root_path(site[:source_dir], site[:collections_dir], "_#{@name}")
|
16
|
+
@data = self.ingest_pages
|
17
|
+
end
|
18
|
+
|
19
|
+
# Finds the page_dir of markdown pages for the collection and ingests
|
20
|
+
# them as an array of hashes
|
21
|
+
#
|
22
|
+
# @return [Array] array of the loaded markdown pages loaded as hashes
|
23
|
+
def ingest_pages
|
24
|
+
data = []
|
25
|
+
pages = Dir.glob("#{@page_dir}/*.md")
|
26
|
+
puts "There are no pages in #{@page_dir} to index.".orange if pages.empty?
|
27
|
+
pages.each do |p|
|
28
|
+
begin
|
29
|
+
data << load_page(p)
|
30
|
+
rescue StandardError => e
|
31
|
+
raise Error::LunrPageLoad, "Cannot load page #{p}\n#{e}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
data
|
35
|
+
end
|
36
|
+
|
37
|
+
# Reads in a markdown file and converts it to a hash
|
38
|
+
# with the values from @fields.
|
39
|
+
# Adds the content of the file (below the YAML) if @content == true
|
40
|
+
#
|
41
|
+
# @param page [String] the path to a markdown page to load
|
42
|
+
def load_page(page)
|
43
|
+
yaml = YAML.load_file(page)
|
44
|
+
hash = {
|
45
|
+
'link' => "{{'#{yaml.fetch('permalink')}' | absolute_url }}",
|
46
|
+
'collection' => @name
|
47
|
+
}
|
48
|
+
content = WaxTasks::Utils.html_strip(File.read(page))
|
49
|
+
hash['content'] = WaxTasks::Utils.remove_diacritics(content) if @content
|
50
|
+
fields = @fields.push('pid').push('label').uniq
|
51
|
+
fields.push('thumbnail') if yaml.key?('thumbnail')
|
52
|
+
fields.each { |f| hash[f] = yaml.dig(f).lunr_normalize }
|
53
|
+
hash
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -2,29 +2,21 @@ module WaxTasks
|
|
2
2
|
# A Jekyll collection with a data source file that
|
3
3
|
# can generate markdown pages from that data.
|
4
4
|
#
|
5
|
-
# @attr
|
6
|
-
# @attr layout
|
7
|
-
# @attr
|
8
|
-
# @attr
|
5
|
+
# @attr config [Hash] the collection config
|
6
|
+
# @attr layout [String] Jekyll layout to be used by the generated pages
|
7
|
+
# @attr ordered [Boolean] whether/not the order of items should be preserved
|
8
|
+
# @attr metadata [Array] array of hashes from ingested metadata file
|
9
9
|
class PagemasterCollection < Collection
|
10
|
-
attr_reader :
|
10
|
+
attr_reader :layout, :ordered, :metadata
|
11
11
|
|
12
12
|
# Creates a new PagemasterCollection with name @name given site config @site
|
13
13
|
def initialize(name, site)
|
14
14
|
super(name, site)
|
15
15
|
|
16
|
-
@
|
16
|
+
@config = self.config
|
17
17
|
@layout = assert_layout
|
18
|
-
@data = ingest_file(@source)
|
19
18
|
@ordered = @config.fetch('keep_order', false)
|
20
|
-
|
21
|
-
|
22
|
-
# Constructs the path to the data source file
|
23
|
-
#
|
24
|
-
# @return [String] the path to the data source file
|
25
|
-
def source_path
|
26
|
-
raise WaxTasks::Error::MissingSource, "Missing collection source in _config.yml for #{@name}" unless @config.key? 'source'
|
27
|
-
WaxTasks::Utils.make_path(@site[:source_dir], '_data', @config['source'])
|
19
|
+
@metadata = ingest_file(self.metadata_source_path)
|
28
20
|
end
|
29
21
|
|
30
22
|
# Confirms + requires `layout` value in the collection @config
|
@@ -35,24 +27,25 @@ module WaxTasks
|
|
35
27
|
@config['layout']
|
36
28
|
end
|
37
29
|
|
38
|
-
# Writes markdown pages from the ingested data to
|
30
|
+
# Writes markdown pages from the ingested data to page_dir
|
39
31
|
# with layout, permalink, and order info added (if applicable)
|
40
32
|
#
|
41
33
|
# @return [Array] a copy of the pages as hashes, for testing
|
42
34
|
def generate_pages
|
43
|
-
|
35
|
+
page_dir = self.page_dir
|
36
|
+
FileUtils.mkdir_p(page_dir)
|
44
37
|
pages = []
|
45
|
-
@
|
38
|
+
@metadata.each_with_index do |item, idx|
|
46
39
|
page_slug = Utils.slug(item.fetch('pid'))
|
47
|
-
path = "#{
|
40
|
+
path = "#{page_dir}/#{page_slug}.md"
|
48
41
|
item['permalink'] = "/#{@name}/#{page_slug}#{@site[:permalink]}"
|
49
42
|
item['layout'] = @layout
|
50
|
-
item['order'] = padded_int(idx, @
|
43
|
+
item['order'] = padded_int(idx, @metadata.length) if @ordered
|
51
44
|
pages << item
|
52
45
|
next "#{page_slug}.md already exits. Skipping." if File.exist?(path)
|
53
46
|
File.open(path, 'w') { |f| f.write("#{item.to_yaml}---") }
|
54
47
|
end
|
55
|
-
puts "#{@
|
48
|
+
puts "#{@metadata.length} pages were generated to #{page_dir} directory.".cyan
|
56
49
|
pages
|
57
50
|
end
|
58
51
|
|
@@ -21,18 +21,19 @@ module WaxTasks
|
|
21
21
|
# @example use default config from file
|
22
22
|
# WaxTasks::TaskRunner.new
|
23
23
|
def initialize(config = {}, env = 'prod')
|
24
|
-
config = YAML.load_file(DEFAULT_CONFIG).symbolize_keys if config.empty?
|
24
|
+
@config = YAML.load_file(DEFAULT_CONFIG).symbolize_keys if config.empty?
|
25
25
|
@site = {
|
26
26
|
env: env,
|
27
|
-
title: config.
|
28
|
-
url: config.
|
29
|
-
baseurl: config.
|
30
|
-
repo_name: config.
|
31
|
-
source_dir: config.
|
32
|
-
collections_dir: config.
|
33
|
-
collections: config.
|
34
|
-
|
35
|
-
|
27
|
+
title: @config.dig(:title),
|
28
|
+
url: @config.dig(:url),
|
29
|
+
baseurl: @config.dig(:baseurl),
|
30
|
+
repo_name: @config.dig(:repo_name),
|
31
|
+
source_dir: @config.dig(:source),
|
32
|
+
collections_dir: @config.dig(:collections_dir),
|
33
|
+
collections: @config.dig(:collections),
|
34
|
+
lunr_index: @config.dig(:lunr_index),
|
35
|
+
js: @config.dig(:js),
|
36
|
+
permalink: Utils.construct_permalink(@config)
|
36
37
|
}
|
37
38
|
rescue StandardError => e
|
38
39
|
raise Error::InvalidSiteConfig, "Could not load _config.yml. => #{e}"
|
@@ -69,18 +70,20 @@ module WaxTasks
|
|
69
70
|
# @param generate_ui [Boolean] whether/not to generate a default lunr UI
|
70
71
|
# @return [Nil]
|
71
72
|
def lunr(generate_ui: false)
|
72
|
-
|
73
|
-
|
73
|
+
@site[:lunr_index].each do |i|
|
74
|
+
file = i.dig('file')
|
75
|
+
ui = i.dig('ui')
|
76
|
+
collections = i.dig('collections')
|
77
|
+
index = Lunr::Index.new(@site, file, collections)
|
74
78
|
|
75
|
-
|
76
|
-
|
79
|
+
index_path = Utils.root_path(@site[:source_dir], file)
|
80
|
+
FileUtils.mkdir_p(File.dirname(index_path))
|
81
|
+
File.open(index_path, 'w') { |f| f.write(index.to_s) }
|
82
|
+
puts "Writing lunr search index to #{index_path}.".cyan
|
77
83
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
if generate_ui
|
83
|
-
ui_path = Utils.make_path(@site[:source_dir], LUNR_UI_PATH)
|
84
|
+
next unless generate_ui
|
85
|
+
raise Error::WaxTasksError, 'Cannot generate default UI because no path was given' if ui.nil?
|
86
|
+
ui_path = Utils.root_path(@site[:source_dir], ui)
|
84
87
|
puts "Writing default lunr UI to #{ui_path}.".cyan
|
85
88
|
File.open(ui_path, 'w') { |f| f.write(index.default_ui) }
|
86
89
|
end
|
@@ -92,9 +95,18 @@ module WaxTasks
|
|
92
95
|
#
|
93
96
|
# @param args [Array] the arguments/collection names from wax:pagemaster
|
94
97
|
# @return [Nil]
|
95
|
-
def
|
98
|
+
def derivatives_iiif(args)
|
99
|
+
args.each do |name|
|
100
|
+
iiif_collection = ImageCollection.new(name, @site)
|
101
|
+
iiif_collection.build_iiif_derivatives
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# @return [Nil]
|
106
|
+
def derivatives_simple(args)
|
96
107
|
args.each do |name|
|
97
|
-
|
108
|
+
image_collection = ImageCollection.new(name, @site)
|
109
|
+
image_collection.build_simple_derivatives
|
98
110
|
end
|
99
111
|
end
|
100
112
|
|
@@ -107,7 +119,7 @@ module WaxTasks
|
|
107
119
|
names = []
|
108
120
|
package = {
|
109
121
|
'name' => site[:title],
|
110
|
-
'version' =>
|
122
|
+
'version' => @config.fetch(:version, ''),
|
111
123
|
'dependencies' => {}
|
112
124
|
}
|
113
125
|
site[:js].each do |dependency|
|
data/lib/wax_tasks/utils.rb
CHANGED
@@ -75,19 +75,8 @@ module WaxTasks
|
|
75
75
|
#
|
76
76
|
# @param args [Array] items to concatenate in path
|
77
77
|
# @return [String] file path
|
78
|
-
def self.
|
79
|
-
args.compact.reject(&:empty?).join('/')
|
80
|
-
end
|
81
|
-
|
82
|
-
# Finds collections in site config where `lunr_index` is enabled
|
83
|
-
#
|
84
|
-
# @param site [Hash] the site config
|
85
|
-
# @return [Array] a list of collection names
|
86
|
-
# @raise WaxTasks::Error::NoLunrCollections
|
87
|
-
def self.get_lunr_collections(site)
|
88
|
-
to_index = site[:collections].find_all { |c| c[1].key?('lunr_index') }
|
89
|
-
raise Error::NoLunrCollections, 'There are no lunr collections to index.' if to_index.nil?
|
90
|
-
to_index.map { |c| c[0] }
|
78
|
+
def self.root_path(*args)
|
79
|
+
['.'].concat(args).compact.reject(&:empty?).join('/').gsub(%r{/+}, '/')
|
91
80
|
end
|
92
81
|
|
93
82
|
# Removes YAML front matter from a string
|
@@ -96,6 +85,10 @@ module WaxTasks
|
|
96
85
|
str.to_s.gsub!(/\A---(.|\n)*?---/, '')
|
97
86
|
end
|
98
87
|
|
88
|
+
def self.rm_liquid(str)
|
89
|
+
str.gsub(/{{.*}}/, '')
|
90
|
+
end
|
91
|
+
|
99
92
|
# Cleans YAML front matter + markdown pages for lunr indexing
|
100
93
|
# @return [String]
|
101
94
|
def self.html_strip(str)
|
@@ -163,6 +156,10 @@ class Array
|
|
163
156
|
WaxTasks::Utils.remove_diacritics(self.join(', '))
|
164
157
|
end
|
165
158
|
end
|
159
|
+
|
160
|
+
def except(value)
|
161
|
+
self - value
|
162
|
+
end
|
166
163
|
end
|
167
164
|
|
168
165
|
# Monkey-patched Hash class
|
data/lib/wax_tasks.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
require_relative 'wax_tasks/branch'
|
2
2
|
require_relative 'wax_tasks/collection'
|
3
3
|
require_relative 'wax_tasks/error'
|
4
|
-
require_relative 'wax_tasks/
|
4
|
+
require_relative 'wax_tasks/image_collection'
|
5
5
|
require_relative 'wax_tasks/local_branch'
|
6
|
-
require_relative 'wax_tasks/
|
7
|
-
require_relative 'wax_tasks/lunr_index'
|
6
|
+
require_relative 'wax_tasks/lunr/index'
|
8
7
|
require_relative 'wax_tasks/pagemaster_collection'
|
9
8
|
require_relative 'wax_tasks/task_runner'
|
10
9
|
require_relative 'wax_tasks/travis_branch'
|
@@ -12,12 +11,13 @@ require_relative 'wax_tasks/utils'
|
|
12
11
|
|
13
12
|
# The WaxTasks module powers the Rake tasks in `./tasks`, including:
|
14
13
|
#
|
15
|
-
# wax:pagemaster
|
16
|
-
# wax:lunr
|
17
|
-
# wax:
|
18
|
-
# wax:
|
19
|
-
# wax:
|
20
|
-
# wax:
|
14
|
+
# wax:pagemaster :: generate collection md pages from csv, json, or yaml file
|
15
|
+
# wax:lunr :: build lunr search index (with default UI if UI=true)
|
16
|
+
# wax:derivatives:simple :: generate simple image derivatives from local image files
|
17
|
+
# wax:derivatves:iiif :: generate iiif derivatives from local image files
|
18
|
+
# wax:jspackage :: write a simple package.json for monitoring js dependencies
|
19
|
+
# wax:push :: push compiled Jekyll site to git branch
|
20
|
+
# wax:test :: run htmlproofer, rspec if .rspec file exists
|
21
21
|
#
|
22
22
|
# Tasks are run by a WaxTasks::TaskRunner object which is resposible
|
23
23
|
# for reading in site config from `_config.yml`
|
@@ -27,11 +27,17 @@ module WaxTasks
|
|
27
27
|
# ----------
|
28
28
|
|
29
29
|
# @return [String] The path to load Jekyll site config
|
30
|
-
DEFAULT_CONFIG
|
31
|
-
|
32
|
-
LUNR_INDEX_PATH = 'js/lunr-index.json'.freeze
|
30
|
+
DEFAULT_CONFIG = '_config.yml'.freeze
|
31
|
+
|
33
32
|
# @return [String] The path to write default LunrUI
|
34
|
-
LUNR_UI_PATH
|
33
|
+
LUNR_UI_PATH = 'js/lunr-ui.js'.freeze
|
34
|
+
|
35
35
|
# @return [String] The path to the compiled Jekyll site
|
36
|
-
SITE_DIR
|
36
|
+
SITE_DIR = '_site'.freeze
|
37
|
+
|
38
|
+
# @return [String] Default image variant/derivative widths to generate
|
39
|
+
DEFAULT_IMAGE_VARIANTS = { thumbnail: 250, full: 1140 }.freeze
|
40
|
+
|
41
|
+
# @return [String] The path where image derivatives should be generated
|
42
|
+
DEFAULT_DERIVATIVE_DIR = 'img/derivatives'.freeze
|
37
43
|
end
|
data/spec/setup.rb
CHANGED
@@ -3,7 +3,7 @@ require 'fileutils'
|
|
3
3
|
#constants
|
4
4
|
ROOT = `pwd`.strip.freeze
|
5
5
|
SAMPLE = "#{ROOT}/spec/sample_site".freeze
|
6
|
-
BUILD = "#{ROOT}/
|
6
|
+
BUILD = "#{ROOT}/test_build".freeze
|
7
7
|
|
8
8
|
# helper methods
|
9
9
|
def quiet_stdout
|
@@ -32,7 +32,7 @@ module WaxTasks::Test
|
|
32
32
|
def self.reset
|
33
33
|
Dir.chdir(ROOT)
|
34
34
|
FileUtils.rm_r(BUILD) if File.directory?(BUILD)
|
35
|
-
FileUtils.copy_entry
|
35
|
+
FileUtils.copy_entry(SAMPLE, BUILD)
|
36
36
|
Dir.chdir(BUILD)
|
37
37
|
end
|
38
38
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -18,6 +18,6 @@ shared_context 'shared', :shared_context => :metadata do
|
|
18
18
|
let(:task_runner) { WaxTasks::TaskRunner.new }
|
19
19
|
let(:default_site) { task_runner.site }
|
20
20
|
let(:args) { default_site[:collections].map{ |c| c[0] } }
|
21
|
-
let(:index_path) {
|
22
|
-
let(:ui_path) {
|
21
|
+
let(:index_path) { "#{BUILD}/js/lunr-index.json" }
|
22
|
+
let(:ui_path) { "#{BUILD }/js/lunr-ui.js" }
|
23
23
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wax_tasks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.pre.beta
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marii Nyrop
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: html-proofer
|
@@ -16,56 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '3'
|
19
|
+
version: '3.9'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '3'
|
26
|
+
version: '3.9'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: jekyll
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '3'
|
33
|
+
version: '3.8'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '3'
|
40
|
+
version: '3.8'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '12'
|
47
|
+
version: '12.3'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '12'
|
54
|
+
version: '12.3'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: wax_iiif
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.0
|
61
|
+
version: 0.1.0
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.0
|
68
|
+
version: 0.1.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,7 +102,8 @@ extensions: []
|
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
104
|
- Gemfile
|
105
|
-
- lib/tasks/
|
105
|
+
- lib/tasks/derivatives_iiif.rake
|
106
|
+
- lib/tasks/derivatives_simple.rake
|
106
107
|
- lib/tasks/jspackage.rake
|
107
108
|
- lib/tasks/lunr.rake
|
108
109
|
- lib/tasks/pagemaster.rake
|
@@ -112,10 +113,12 @@ files:
|
|
112
113
|
- lib/wax_tasks/branch.rb
|
113
114
|
- lib/wax_tasks/collection.rb
|
114
115
|
- lib/wax_tasks/error.rb
|
115
|
-
- lib/wax_tasks/
|
116
|
+
- lib/wax_tasks/iiif/derivatives.rb
|
117
|
+
- lib/wax_tasks/iiif/manifest.rb
|
118
|
+
- lib/wax_tasks/image_collection.rb
|
116
119
|
- lib/wax_tasks/local_branch.rb
|
117
|
-
- lib/wax_tasks/
|
118
|
-
- lib/wax_tasks/
|
120
|
+
- lib/wax_tasks/lunr/index.rb
|
121
|
+
- lib/wax_tasks/lunr/page_set.rb
|
119
122
|
- lib/wax_tasks/pagemaster_collection.rb
|
120
123
|
- lib/wax_tasks/task_runner.rb
|
121
124
|
- lib/wax_tasks/travis_branch.rb
|
@@ -137,11 +140,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
140
|
version: '0'
|
138
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
142
|
requirements:
|
140
|
-
- - "
|
143
|
+
- - ">"
|
141
144
|
- !ruby/object:Gem::Version
|
142
|
-
version:
|
145
|
+
version: 1.3.1
|
143
146
|
requirements:
|
144
147
|
- imagemagick
|
148
|
+
- ghostscript
|
145
149
|
rubyforge_project:
|
146
150
|
rubygems_version: 2.7.6
|
147
151
|
signing_key:
|
data/lib/tasks/iiif.rake
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
require 'wax_tasks'
|
2
|
-
|
3
|
-
namespace :wax do
|
4
|
-
desc 'generate iiif derivatives from local image files'
|
5
|
-
task :iiif do
|
6
|
-
ARGS = ARGV.drop(1).each { |a| task a.to_sym }
|
7
|
-
abort "You must specify a collection after 'wax:iiif'" if ARGS.empty?
|
8
|
-
task_runner = WaxTasks::TaskRunner.new
|
9
|
-
task_runner.iiif(ARGS)
|
10
|
-
end
|
11
|
-
end
|
@@ -1,105 +0,0 @@
|
|
1
|
-
require 'wax_iiif'
|
2
|
-
|
3
|
-
module WaxTasks
|
4
|
-
# A Jekyll collection with IIIF configuration + data
|
5
|
-
#
|
6
|
-
# @attr src_data [String] the path to the data source file
|
7
|
-
# @attr iiif_config [Hash] the iiif configuration for the collection
|
8
|
-
# @attr meta [Array] metadata k,v rules
|
9
|
-
# @attr variants [Hash] image variants to generate e.g. { med: 650 }
|
10
|
-
# @attr src_dir [String] path to existing iiif source images
|
11
|
-
# @attr target_dir [String] target path for iiif derivatives
|
12
|
-
class IiifCollection < Collection
|
13
|
-
attr_reader :variants, :meta, :target_dir
|
14
|
-
|
15
|
-
# Creates a new IiifCollection with name @name given site config @site
|
16
|
-
def initialize(name, site)
|
17
|
-
super(name, site)
|
18
|
-
|
19
|
-
@src_data = @config.fetch('source', nil)
|
20
|
-
@iiif_config = @config.fetch('iiif', {})
|
21
|
-
@meta = @iiif_config.fetch('meta', nil)
|
22
|
-
@variants = validated_variants
|
23
|
-
@src_dir = Utils.make_path(@site[:source_dir],
|
24
|
-
'_data/iiif',
|
25
|
-
@name)
|
26
|
-
@target_dir = Utils.make_path(@site[:source_dir],
|
27
|
-
'iiif',
|
28
|
-
@name)
|
29
|
-
end
|
30
|
-
|
31
|
-
# Main method for generating iiif derivatives and json
|
32
|
-
# @return [Nil]
|
33
|
-
def process
|
34
|
-
raise Error::MissingIiifSrc, "Cannot find IIIF source directory #{@src_dir}" unless Dir.exist?(@src_dir)
|
35
|
-
FileUtils.mkdir_p(@target_dir, verbose: false)
|
36
|
-
builder = iiif_builder
|
37
|
-
builder.load(iiif_records)
|
38
|
-
builder.process_data(true)
|
39
|
-
end
|
40
|
-
|
41
|
-
# Creates a IiifS3::Builder object from collection config
|
42
|
-
# @return [Object]
|
43
|
-
def iiif_builder
|
44
|
-
build_opts = {
|
45
|
-
base_url: "#{@site[:baseurl]}/iiif/#{@name}",
|
46
|
-
output_dir: @target_dir,
|
47
|
-
verbose: true,
|
48
|
-
variants: @variants
|
49
|
-
}
|
50
|
-
IiifS3::Builder.new(build_opts)
|
51
|
-
end
|
52
|
-
|
53
|
-
# Gets custom image variants from collection config if available
|
54
|
-
# Else returns default variants { med: 600, lg: 1140 } to Builder
|
55
|
-
#
|
56
|
-
# @return [Hash]
|
57
|
-
def validated_variants
|
58
|
-
vars = @iiif_config.fetch('variants', false)
|
59
|
-
if vars.is_a?(Array) && vars.all? { |v| v.is_a?(Integer) }
|
60
|
-
variants = {}
|
61
|
-
vars.each_with_index do |v, i|
|
62
|
-
variants["custom_variant_#{i}".to_sym] = v
|
63
|
-
end
|
64
|
-
else
|
65
|
-
variants = { med: 600, lg: 1140 }
|
66
|
-
end
|
67
|
-
variants
|
68
|
-
end
|
69
|
-
|
70
|
-
# Creates an array of IIIfS3 ImageRecords from the collection config
|
71
|
-
# for the IiifS3 Builder to process
|
72
|
-
#
|
73
|
-
# @return [Array]
|
74
|
-
def iiif_records
|
75
|
-
records = []
|
76
|
-
source_images = Dir["#{@src_dir}/*"].sort!
|
77
|
-
if @meta && @src_data
|
78
|
-
src_path = Utils.make_path(@site[:source_dir], '_data', @src_data)
|
79
|
-
metadata = ingest_file(src_path)
|
80
|
-
else
|
81
|
-
metadata = false
|
82
|
-
end
|
83
|
-
source_images.each { |src_img| records << iiif_record(src_img, metadata) }
|
84
|
-
records
|
85
|
-
end
|
86
|
-
|
87
|
-
# Creates an individual IiifS3 ImageRecord
|
88
|
-
# with metadata from source data file if available
|
89
|
-
#
|
90
|
-
# @param src_img [String] path to the original source image
|
91
|
-
# @param metadata [Hash] metadata to add to the item if available
|
92
|
-
# @return [Object]
|
93
|
-
def iiif_record(src_img, metadata)
|
94
|
-
basename = File.basename(src_img, '.*').to_s
|
95
|
-
record_opts = { id: basename, path: src_img, label: basename }
|
96
|
-
if metadata
|
97
|
-
src_item = metadata.find { |i| i['pid'].to_s == basename }
|
98
|
-
@meta.each do |i|
|
99
|
-
record_opts[i.first[0].to_sym] = src_item.fetch(i.first[1], '')
|
100
|
-
end
|
101
|
-
end
|
102
|
-
IiifS3::ImageRecord.new(record_opts)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
module WaxTasks
|
2
|
-
# A Jekyll collection to be Indexed in a Lunr Index / JSON file
|
3
|
-
# for client-side search.
|
4
|
-
#
|
5
|
-
# @attr index_config [Hash] the collection's lunr_index config
|
6
|
-
# @attr content [Boolean] whether/not page content should be indexed
|
7
|
-
# @attr fields [Array] the fields (i.e., keys) that should be indexed
|
8
|
-
# @attr data [Array] hash array of data from the ingested pages
|
9
|
-
class LunrCollection < Collection
|
10
|
-
attr_accessor :fields, :data
|
11
|
-
|
12
|
-
# Creates a new LunrCollection with name @name given site config @site
|
13
|
-
def initialize(name, site)
|
14
|
-
super(name, site)
|
15
|
-
|
16
|
-
@index_config = @config['lunr_index']
|
17
|
-
@content = @index_config.fetch('content', false)
|
18
|
-
@fields = @index_config.fetch('fields', [])
|
19
|
-
@data = ingest_pages
|
20
|
-
|
21
|
-
raise Error::MissingFields, "There are no fields for #{@name}.".magenta if @fields.empty?
|
22
|
-
end
|
23
|
-
|
24
|
-
# Finds the @page_dir of markdown pages for the collection and ingests
|
25
|
-
# them as an array of hashes
|
26
|
-
#
|
27
|
-
# @return [Array] array of the loaded markdown pages loaded as hashes
|
28
|
-
def ingest_pages
|
29
|
-
data = []
|
30
|
-
pages = Dir.glob("#{@page_dir}/*.md")
|
31
|
-
puts "There are no pages in #{@page_dir} to index.".cyan if pages.empty?
|
32
|
-
pages.each do |p|
|
33
|
-
begin
|
34
|
-
data << load_page(p)
|
35
|
-
rescue StandardError => e
|
36
|
-
raise Error::LunrPageLoad, "Cannot load page #{p}\n#{e}"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
data
|
40
|
-
end
|
41
|
-
|
42
|
-
# Reads in a markdown file and converts it to a hash
|
43
|
-
# with the values from @fields.
|
44
|
-
# Adds the content of the file (below the YAML) if @content == true
|
45
|
-
#
|
46
|
-
# @param page [String] the path to a markdown page to load
|
47
|
-
def load_page(page)
|
48
|
-
yaml = YAML.load_file(page)
|
49
|
-
hash = {
|
50
|
-
'link' => "{{'#{yaml.fetch('permalink')}' | relative_url }}",
|
51
|
-
'collection' => @name
|
52
|
-
}
|
53
|
-
if @content
|
54
|
-
content = WaxTasks::Utils.html_strip(File.read(page))
|
55
|
-
hash['content'] = WaxTasks::Utils.remove_diacritics(content)
|
56
|
-
end
|
57
|
-
fields = @fields.push('pid').uniq
|
58
|
-
fields.each { |f| hash[f] = yaml[f].lunr_normalize }
|
59
|
-
hash
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
data/lib/wax_tasks/lunr_index.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
module WaxTasks
|
2
|
-
# A LunrIndex document that combines data from all collections
|
3
|
-
# in site config that have `lunr_index` parameters.
|
4
|
-
#
|
5
|
-
# @attr collections [Array] a list of LunrCollection objects
|
6
|
-
# @attr fields [Array] shared list of fields to index among LunrCollections
|
7
|
-
class LunrIndex
|
8
|
-
attr_accessor :collections, :fields
|
9
|
-
|
10
|
-
# Creates a new LunrIndex object
|
11
|
-
def initialize(collections)
|
12
|
-
@collections = collections
|
13
|
-
@fields = total_fields
|
14
|
-
end
|
15
|
-
|
16
|
-
# @return [Array] shared list of fields to index among LunrCollections
|
17
|
-
def total_fields
|
18
|
-
total_fields = @collections.map(&:fields).reduce([], :concat)
|
19
|
-
total_fields.uniq
|
20
|
-
end
|
21
|
-
|
22
|
-
# @return [String] writes index data as pretty JSON with YAML front-matter
|
23
|
-
def to_s
|
24
|
-
data = @collections.map(&:data).flatten
|
25
|
-
data.each_with_index.map { |d, id| d['lunr_index'] = id }
|
26
|
-
"---\nlayout: none\n---\n#{JSON.pretty_generate(data)}"
|
27
|
-
end
|
28
|
-
|
29
|
-
# Creates a default LunrUI / JS file for displaying the Index
|
30
|
-
#
|
31
|
-
# @return [String]
|
32
|
-
def default_ui
|
33
|
-
<<~HEREDOC
|
34
|
-
---
|
35
|
-
layout: none
|
36
|
-
---
|
37
|
-
$.getJSON({{ site.baseurl }}/js/lunr-index.json, function(index_json) {
|
38
|
-
window.index = new elasticlunr.Index;
|
39
|
-
window.store = index_json;
|
40
|
-
index.saveDocument(false);
|
41
|
-
index.setRef('lunr_id');
|
42
|
-
#{@fields.map { |f| "index.addField('#{f}');" }.join("\n")}
|
43
|
-
// add docs
|
44
|
-
for (i in store){
|
45
|
-
index.addDoc(store[i]);
|
46
|
-
}
|
47
|
-
$('input#search').on('keyup', function() {
|
48
|
-
var results_div = $('#results');
|
49
|
-
var query = $(this).val();
|
50
|
-
var results = index.search(query, { boolean: 'AND', expand: true });
|
51
|
-
results_div.empty();
|
52
|
-
if (results.length > 10) {
|
53
|
-
results_div.prepend("<p><small>Displaying 10 of " + results.length + " results.</small></p>");
|
54
|
-
}
|
55
|
-
for (var r in results.slice(0, 9)) {
|
56
|
-
var ref = results[r].ref;
|
57
|
-
var item = store[ref];
|
58
|
-
#{@fields.map { |f| "var #{f} = item.#{f};" }.join("\n")}
|
59
|
-
var result = '<div class="result"><b><a href="' + item.link + '">' + title + '</a></b></p></div>';
|
60
|
-
results_div.append(result);
|
61
|
-
}
|
62
|
-
});
|
63
|
-
});
|
64
|
-
HEREDOC
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|