wax_tasks 0.3.2 → 1.0.0.pre.beta

Sign up to get free protection for your applications and to get access to all the features.
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