jekyll_pages_api_search 0.2.1 → 0.3.0

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
  SHA1:
3
- metadata.gz: 8239797ba1fff01d7e2f64df6a53ecd2d709b825
4
- data.tar.gz: 6b89bcc36263908530ca3808d903ed42ca737152
3
+ metadata.gz: 63e2ed79ef91f5ef84da6ddee3dcf31392715499
4
+ data.tar.gz: 1910b3230c724c1d508fefef542300d0bf320be8
5
5
  SHA512:
6
- metadata.gz: 17b20c84f82856ea31c6f51d3aae1fde6146570ee62d98917984ed18a75c2b87f3ca30d95ff30bee9074f80ad27d0c7b74562199f4c502b3d4f89bc934117e03
7
- data.tar.gz: 638296b6d9fc3f9eaf1c5c5ad4b85223343988b8192bd3696f4f4773913fffe8a1168323ac4bc343a38a817a01c944567b7e49b68f9977b6c100934c3480e7c8
6
+ metadata.gz: 412c4e6e4f2969626cd75cbfd56dc47869e77183bb70bfed6d7a85071db474afcf89532e7321f68e06bb4509ac3ec065d855c1f47b2452e80076581d3516e06e
7
+ data.tar.gz: 37788d78914545a337f04fb10c3d8f04134a2ec0813631aedc9e86e73b0ed7352e2fe343c2823b13d30ab419eb707f09e77f3dd1b6bb8c6c22f4659d0473078e
data/README.md CHANGED
@@ -82,6 +82,13 @@ Alternately, you can inspect the code of this Gem (all paths relative to
82
82
  - `@import "jekyll_pages_api_search";`: includes
83
83
  `sass/jekyll_pages_api_search.scss`
84
84
 
85
+ ### Running standalone
86
+
87
+ If you wish to generate a `search-index.json` file (and optionaly a
88
+ `pages.json` file) when using a site generation tool other than Jekyll, you
89
+ can run the `jekyll_pages_api_search` executable as a post-generation step.
90
+ Run `jekyll_pages_api -h` for instructions.
91
+
85
92
  ### Under the hood
86
93
 
87
94
  This plugin depends on [jQuery](https://jquery.com/),
Binary file
@@ -0,0 +1,89 @@
1
+ #! /usr/bin/env ruby
2
+ # Author: Mike Bland <michael.bland@gsa.gov>
3
+ # Date: 2015-06-21
4
+
5
+ require_relative '../lib/jekyll_pages_api_search'
6
+ require 'fileutils'
7
+ require 'jekyll_pages_api'
8
+ require 'zlib'
9
+
10
+ ASSETS_DIR = ::JekyllPagesApiSearch::JavascriptCopier::ASSETS_DIR
11
+
12
+ USAGE=<<END_USAGE
13
+ #{$0}: generate a lunr.js index from Jekyll Pages API output
14
+
15
+ Usage:
16
+ #{$0} basedir config.yml pages.json
17
+ uses an existing pages.json to build the index
18
+ #{$0} basedir config.yml pages.json baseURL title_prefix body_element_tag
19
+ produces pages.json and pages.json.gz in addition to the index
20
+ #{$0} --assets baseURL interface.scss interface.html load.js
21
+ produce assets for search interface provided by each {scss,html,js} path
22
+ #{$0} -h
23
+
24
+ The resulting index will be saved in basedir/search-index.json. A gzipped
25
+ version will be produced as well. The JavaScript bundle containing the search
26
+ integration code will be stored in basedir/#{ASSETS_DIR}.
27
+
28
+ Arguments:
29
+ -h
30
+ Print this help message
31
+ --assets
32
+ Produces individual search interface assets:
33
+ interface.scss: style for search-interface.html
34
+ interface.html: HTML fragment containing search interface element
35
+ load.js: <script> element that loads the search code bundle
36
+ basedir
37
+ Path to the generated site's root directory
38
+ config.yml
39
+ Path to the site's config.yml containing a `jekyll_pages_api_search` entry
40
+ pages.json
41
+ Path to the output file generated by `jekyll_pages_api`
42
+ baseURL
43
+ URL prefix of every page of the generated site
44
+ title_prefix
45
+ Prefix to strip from page titles
46
+ body_element_tag
47
+ Tag (or tag prefix) identifying the main content element within the <body>
48
+ element of each document. Can be a complete tag (ending in '>'), or the
49
+ prefix of a longer tag. Used to strip boilerplate out of the content
50
+ exported via the API.
51
+ END_USAGE
52
+
53
+ if ARGV.length == 1 && ARGV[0] == '-h'
54
+ puts USAGE
55
+ exit
56
+ end
57
+
58
+ if ARGV.length == 5
59
+ if ARGV[0] == '--assets'
60
+ baseURL, scss, html, js = ARGV[1..ARGV.size]
61
+ ::JekyllPagesApiSearch::Assets::write_to_files baseURL, scss, html, js
62
+ exit
63
+ else
64
+ $stderr.puts "Wrong number of arguments: #{ARGV.length}"
65
+ $stderr.puts USAGE
66
+ exit 1
67
+ end
68
+ end
69
+
70
+ unless [3, 6].include? ARGV.length
71
+ $stderr.puts "Wrong number of arguments: #{ARGV.length}"
72
+ $stderr.puts USAGE
73
+ exit 1
74
+ end
75
+
76
+ basedir, config, pages_json, baseURL, title_prefix, body_element_tag = ARGV
77
+
78
+ unless File.exist? basedir
79
+ $stderr.puts "#{basedir} does not exist"
80
+ exit 1
81
+ end
82
+
83
+ if ARGV.length == 3 && !File.exist?(pages_json)
84
+ $stderr.puts "#{pages_json} does not exist"
85
+ exit 1
86
+ end
87
+
88
+ ::JekyllPagesApiSearch::Standalone.generate_index(basedir, config, pages_json,
89
+ baseURL, title_prefix, body_element_tag)
@@ -0,0 +1,17 @@
1
+ # @author Mike Bland (michael.bland@gsa.gov)
2
+
3
+ require_relative 'sass'
4
+ require_relative 'tags'
5
+
6
+ require 'fileutils'
7
+
8
+ module JekyllPagesApiSearch
9
+ class Assets
10
+ def self.write_to_files(baseurl, scss, html, js)
11
+ [scss, html, js].each {|i| FileUtils.mkdir_p File.dirname(i)}
12
+ FileUtils.cp Sass::INTERFACE_FILE, scss
13
+ File.open(html, 'w') {|f| f << SearchInterfaceTag::CODE}
14
+ File.open(js, 'w') {|f| f << LoadSearchTag::generate_script(baseurl)}
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ # @author Mike Bland (michael.bland@gsa.gov)
2
+
3
+ require 'zlib'
4
+
5
+ module JekyllPagesApiSearch
6
+ class Compressor
7
+ def self.gzip_in_memory_content(file_to_content_hash)
8
+ file_to_content_hash.each do |file, content|
9
+ ::Zlib::GzipWriter.open("#{file}.gz", Zlib::BEST_COMPRESSION) do |gz|
10
+ gz.write content
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,18 +1,32 @@
1
1
  # @author Mike Bland (michael.bland@gsa.gov)
2
2
 
3
+ require 'fileutils'
3
4
  require 'jekyll/static_file'
4
5
 
5
6
  module JekyllPagesApiSearch
6
7
  class JavascriptCopier
8
+ SOURCE = File.realpath(File.join(File.dirname(__FILE__), '..', '..'))
9
+ ASSETS_DIR = File.join('assets', 'js')
10
+ BEGIN_PATH = SOURCE.size + File::SEPARATOR.size
11
+
7
12
  def self.copy_to_site(site)
8
- assets_path = File.join('assets', 'js')
9
- source = File.realpath(File.join(File.dirname(__FILE__), '..', '..'))
10
- begin_path = source.size + File::SEPARATOR.size
11
- Dir[File.join(source, assets_path, '**', '*.js*')].each do |f|
12
- next unless File.file? f
13
- f = f[begin_path..-1]
13
+ self.search_bundle_paths do |f|
14
14
  site.static_files << ::Jekyll::StaticFile.new(
15
- site, source, File.dirname(f), File.basename(f))
15
+ site, SOURCE, File.dirname(f), File.basename(f))
16
+ end
17
+ end
18
+
19
+ def self.copy_to_basedir(basedir)
20
+ target_path = File.join basedir, ASSETS_DIR
21
+ FileUtils.mkdir_p target_path
22
+ self.search_bundle_paths {|f| FileUtils.cp f, target_path}
23
+ end
24
+
25
+ private
26
+
27
+ def self.search_bundle_paths
28
+ Dir.glob(File.join(SOURCE, ASSETS_DIR, 'search-bundle.js*')) do |f|
29
+ yield f[BEGIN_PATH..-1]
16
30
  end
17
31
  end
18
32
  end
@@ -2,4 +2,11 @@
2
2
 
3
3
  require 'sass'
4
4
 
5
- Sass.load_paths << File.join(File.dirname(__FILE__), 'sass')
5
+ module JekyllPagesApiSearch
6
+ class Sass
7
+ DIR = File.join File.dirname(__FILE__), 'sass'
8
+ INTERFACE_FILE = File.join DIR, 'jekyll_pages_api_search.scss'
9
+ end
10
+ end
11
+
12
+ Sass.load_paths << ::JekyllPagesApiSearch::Sass::DIR
@@ -5,6 +5,8 @@ require 'v8'
5
5
 
6
6
  module JekyllPagesApiSearch
7
7
  class SearchIndexBuilder
8
+ INDEX_FILE = 'search-index.json'
9
+
8
10
  def self.build_index(site)
9
11
  corpus_page = find_corpus_page(site.pages)
10
12
  raise 'Pages API corpus not found' if corpus_page == nil
@@ -18,7 +20,7 @@ module JekyllPagesApiSearch
18
20
  cxt.load(File.join(dirname, 'search.js'))
19
21
 
20
22
  index_page = JekyllPagesApi::PageWithoutAFile.new(
21
- site, site.source, '', 'search-index.json')
23
+ site, site.source, '', INDEX_FILE)
22
24
  index_page.output = cxt[:result]
23
25
  return index_page
24
26
  end
@@ -1,5 +1,6 @@
1
1
  # @author Mike Bland (michael.bland@gsa.gov)
2
2
 
3
+ require_relative 'compressor'
3
4
  require_relative 'js_copier'
4
5
 
5
6
  require 'jekyll/site'
@@ -35,10 +36,8 @@ module Jekyll
35
36
  def pages_api_search_after_write
36
37
  index = pages.find {|p| p.name == 'search-index.json'}
37
38
  raise 'Search index not found' if index.nil?
38
- compressed = "#{index.destination self.dest}.gz"
39
- Zlib::GzipWriter.open(compressed, Zlib::BEST_COMPRESSION) do |gz|
40
- gz.write index.output
41
- end
39
+ JekyllPagesApiSearch::Compressor.gzip_in_memory_content(
40
+ "#{index.destination self.dest}" => index.output)
42
41
  end
43
42
  end
44
43
  end
@@ -0,0 +1,29 @@
1
+ # @author Mike Bland (michael.bland@gsa.gov)
2
+
3
+ require 'jekyll_pages_api'
4
+ require 'safe_yaml'
5
+
6
+ module JekyllPagesApiSearch
7
+ class Site
8
+ attr_reader :source, :config
9
+ attr_accessor :pages
10
+
11
+ def initialize(basedir, config)
12
+ @source = basedir
13
+ @config = SafeYAML.load_file(config, :safe => true)
14
+ @pages = []
15
+ end
16
+
17
+ # TODO(mbland): comment on how a pages.json file can be transfered from
18
+ # JekyllPagesApi::GeneratedSite
19
+ def load_pages_json(pages_json_path)
20
+ basename = File.basename pages_json_path
21
+ rel_dir = File.dirname pages_json_path
22
+ rel_dir = rel_dir[self.source.size..rel_dir.size]
23
+ page = ::JekyllPagesApi::PageWithoutAFile.new(
24
+ self, self.source, rel_dir, basename)
25
+ page.output = File.read(pages_json_path)
26
+ self.pages << page
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,36 @@
1
+ # @author Mike Bland (michael.bland@gsa.gov)
2
+
3
+ require_relative 'compressor'
4
+ require_relative 'site'
5
+ require 'fileutils'
6
+ require 'jekyll_pages_api'
7
+
8
+ module JekyllPagesApiSearch
9
+ class Standalone
10
+ def self.generate_index(basedir, config, pages_json, baseURL,
11
+ title_prefix, body_element_tag)
12
+ site = Site.new basedir, config
13
+
14
+ # Generate pages.json if it doesn't already exist.
15
+ if baseURL.nil?
16
+ site.load_pages_json pages_json
17
+ else
18
+ site.pages << ::JekyllPagesApi::Generator.new(
19
+ ::JekyllPagesApi::GeneratedSite.new(
20
+ baseURL, basedir, title_prefix, body_element_tag)).page
21
+ end
22
+
23
+ # Build the index; output pages_json if necessary; gzip outputs.
24
+ index = SearchIndexBuilder.build_index site
25
+ index_outfile = File.join site.source, index.name
26
+ output = { index_outfile => index.output.to_s }
27
+ output[pages_json] = site.pages.first.output unless File.exist? pages_json
28
+ output.each do |outfile, content|
29
+ FileUtils.mkdir_p File.dirname(outfile)
30
+ File.open(outfile, 'w') {|f| f << content}
31
+ end
32
+ Compressor::gzip_in_memory_content output
33
+ JavascriptCopier::copy_to_basedir site.source
34
+ end
35
+ end
36
+ end
@@ -20,9 +20,13 @@ module JekyllPagesApiSearch
20
20
  def render(context)
21
21
  return @code if @code
22
22
  baseurl = context.registers[:site].config['baseurl']
23
- @code = ("<script>SEARCH_BASEURL = '#{baseurl}';</script>\n" +
24
- "<script async src=\"#{baseurl}/assets/js/search-bundle.js\">" +
25
- "</script>")
23
+ @code = LoadSearchTag.generate_script baseurl
24
+ end
25
+
26
+ def self.generate_script(baseurl)
27
+ "<script>SEARCH_BASEURL = '#{baseurl}';</script>\n" +
28
+ "<script async src=\"#{baseurl}/assets/js/search-bundle.js\">" +
29
+ "</script>"
26
30
  end
27
31
  end
28
32
  end
@@ -1,5 +1,5 @@
1
1
  # @author Mike Bland (michael.bland@gsa.gov)
2
2
 
3
3
  module JekyllPagesApiSearch
4
- VERSION = '0.2.1'
4
+ VERSION = '0.3.0'
5
5
  end
@@ -1,8 +1,11 @@
1
1
  # @author Mike Bland (michael.bland@gsa.gov)
2
2
 
3
+ require 'jekyll_pages_api_search/assets'
3
4
  require 'jekyll_pages_api_search/js_copier'
4
5
  require 'jekyll_pages_api_search/sass'
5
6
  require 'jekyll_pages_api_search/search'
6
7
  require 'jekyll_pages_api_search/search_hook'
8
+ require 'jekyll_pages_api_search/site'
9
+ require 'jekyll_pages_api_search/standalone'
7
10
  require 'jekyll_pages_api_search/tags'
8
11
  require 'jekyll_pages_api_search/version'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll_pages_api_search
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Bland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-12 00:00:00.000000000 Z
11
+ date: 2015-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll_pages_api
@@ -154,7 +154,8 @@ description: Contains a Jekyll plugin and associated files that facilitate addin
154
154
  client-side search features to a site using the jekyll_pages_api gem.
155
155
  email:
156
156
  - michael.bland@gsa.gov
157
- executables: []
157
+ executables:
158
+ - jekyll_pages_api_search
158
159
  extensions: []
159
160
  extra_rdoc_files: []
160
161
  files:
@@ -164,7 +165,10 @@ files:
164
165
  - assets/js/search-bundle.js
165
166
  - assets/js/search-bundle.js.gz
166
167
  - assets/js/search.js
168
+ - bin/jekyll_pages_api_search
167
169
  - lib/jekyll_pages_api_search.rb
170
+ - lib/jekyll_pages_api_search/assets.rb
171
+ - lib/jekyll_pages_api_search/compressor.rb
168
172
  - lib/jekyll_pages_api_search/js_copier.rb
169
173
  - lib/jekyll_pages_api_search/lunr.min.js
170
174
  - lib/jekyll_pages_api_search/sass.rb
@@ -173,6 +177,8 @@ files:
173
177
  - lib/jekyll_pages_api_search/search.js
174
178
  - lib/jekyll_pages_api_search/search.rb
175
179
  - lib/jekyll_pages_api_search/search_hook.rb
180
+ - lib/jekyll_pages_api_search/site.rb
181
+ - lib/jekyll_pages_api_search/standalone.rb
176
182
  - lib/jekyll_pages_api_search/tags.rb
177
183
  - lib/jekyll_pages_api_search/version.rb
178
184
  homepage: https://github.com/18F/jekyll_pages_api_search