jekyll_pages_api_search 0.2.1 → 0.3.0

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
  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