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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d88624cfe6327eb5449dda2246712718f4bdfb2fea155e12e1593b6a5e10af08
4
- data.tar.gz: d6aa6846dedcbaa295d4ae3f909c1f22fa68c55db1524b7aea1e7a958ef241ad
3
+ metadata.gz: 6df6c21281405044f2958da14b8eda608a4a265337f684c1371612817468767a
4
+ data.tar.gz: f1a7248a2b83fa1cf34cfd15580baecdefdd91601c7328b987d9ac247316e154
5
5
  SHA512:
6
- metadata.gz: b3c8dd46e8631bbff1bcdb2792255882ac37cb1afd4b8ed9e193e24e0625c934eeda807d56417832df1fbfbdc9dec435df02df5058c3907794761bf704734fcc
7
- data.tar.gz: 954bbf0a5a9561ad4b74bf751de5e45e6cc5ec7de21a5fd82720789483470c29f1efc161fa62af1e69c2b4b8479956f82a4acd73277d3efd42bf36cfb0a2ef97
6
+ metadata.gz: 2a2c5464d13a57208f0c79bbf44a4355b6fad5efd3d2e511ad30ce7a0b4075321868a906a70b680b76ced742d5394fb758a746aff42f0601ea9137ad774dd448
7
+ data.tar.gz: 87e84935bcda6fcc92bab5a5fecc7b8fec29d19e3348b6b1f0404dd3b6e47595b778a1b7a25562e0ce7b5c187c700be7c9c20a728bc7adbf98284bba26e7b691
data/Gemfile CHANGED
@@ -3,6 +3,6 @@ gemspec
3
3
 
4
4
  # dev/test utilities
5
5
  gem 'diane', require: false
6
- gem 'rubocop', require: false
6
+ gem 'rubocop', '0.59.0', require: false
7
7
  gem 'simplecov', require: false
8
8
  gem 'yard', require: false
@@ -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
@@ -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
- path = WaxTasks::Utils.make_path(task_runner.site[:source_dir],
10
- 'package.json')
11
- File.open(path, 'w') { |f| f.write(package.to_json) }
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
@@ -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
- ARGS = ARGV.drop(1).each { |a| task a.to_sym }
7
- raise 'You must specify a collection after wax:pagemaster' if ARGS.empty?
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(ARGS)
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
- ARGS = ARGV.drop(1).each { |a| task a.to_sym }
7
- raise 'You must specify a branch after \'wax:push:branch\'' if ARGS.empty?
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(ARGS.first)
10
+ task_runner.push_branch(arguments.first)
11
11
  end
12
12
  end
@@ -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}"
@@ -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
- attr_reader :name, :page_dir
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 config @site
16
+ # Creates a new collection with name @name given site configuration @site
22
17
  #
23
- # @param name [String] the name of the collection in site:collections
24
- # @param site [Hash] the site config
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 = collection_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 collection_config
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
@@ -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}'/>&nbsp;&nbsp;&nbsp;`
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 source [String] the path to the data source file
6
- # @attr layout [String] the Jekyll layout to be used by the generated pages
7
- # @attr data [Array] array of hashes representing the ingested data file
8
- # @attr ordered [Boolean] whether/not the order of items should be preserved
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 :source, :layout, :data, :ordered
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
- @source = source_path
16
+ @config = self.config
17
17
  @layout = assert_layout
18
- @data = ingest_file(@source)
19
18
  @ordered = @config.fetch('keep_order', false)
20
- end
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 @page_dir
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
- FileUtils.mkdir_p(@page_dir)
35
+ page_dir = self.page_dir
36
+ FileUtils.mkdir_p(page_dir)
44
37
  pages = []
45
- @data.each_with_index do |item, idx|
38
+ @metadata.each_with_index do |item, idx|
46
39
  page_slug = Utils.slug(item.fetch('pid'))
47
- path = "#{@page_dir}/#{page_slug}.md"
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, @data.length) if @ordered
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 "#{@data.length} pages were generated to #{@page_dir} directory.".cyan
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.fetch(:title, ''),
28
- url: config.fetch(:url, ''),
29
- baseurl: config.fetch(:baseurl, ''),
30
- repo_name: config.fetch(:repo_name, ''),
31
- source_dir: config.fetch(:source, nil),
32
- collections_dir: config.fetch(:collections_dir, nil),
33
- collections: config.fetch(:collections, {}),
34
- js: config.fetch(:js, false),
35
- permalink: Utils.construct_permalink(config)
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
- lunr_collections = Utils.get_lunr_collections(@site)
73
- lunr_collections.map! { |name| LunrCollection.new(name, @site) }
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
- index = LunrIndex.new(lunr_collections)
76
- index_path = Utils.make_path(@site[:source_dir], LUNR_INDEX_PATH)
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
- FileUtils.mkdir_p(File.dirname(index_path))
79
- File.open(index_path, 'w') { |f| f.write(index) }
80
- puts "Writing lunr search index to #{index_path}.".cyan
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 iiif(args)
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
- IiifCollection.new(name, @site).process
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' => '1.0.0',
122
+ 'version' => @config.fetch(:version, ''),
111
123
  'dependencies' => {}
112
124
  }
113
125
  site[:js].each do |dependency|
@@ -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.make_path(*args)
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/iiif_collection'
4
+ require_relative 'wax_tasks/image_collection'
5
5
  require_relative 'wax_tasks/local_branch'
6
- require_relative 'wax_tasks/lunr_collection'
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 :: generate collection md pages from csv, json, or yaml file
16
- # wax:lunr :: build lunr search index (with default UI if UI=true)
17
- # wax: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
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 = '_config.yml'.freeze
31
- # @return [String] The path to write WaxTasks::LunrIndex
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 = 'js/lunr-ui.js'.freeze
33
+ LUNR_UI_PATH = 'js/lunr-ui.js'.freeze
34
+
35
35
  # @return [String] The path to the compiled Jekyll site
36
- SITE_DIR = './_site'.freeze
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}/build".freeze
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 SAMPLE, BUILD
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) { WaxTasks::LUNR_INDEX_PATH }
22
- let(:ui_path) { WaxTasks::LUNR_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.3.2
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-09-21 00:00:00.000000000 Z
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.2
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.2
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/iiif.rake
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/iiif_collection.rb
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/lunr_collection.rb
118
- - lib/wax_tasks/lunr_index.rb
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: '0'
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
@@ -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