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 +4 -4
- data/README.md +7 -0
- data/assets/js/search-bundle.js.gz +0 -0
- data/bin/jekyll_pages_api_search +89 -0
- data/lib/jekyll_pages_api_search/assets.rb +17 -0
- data/lib/jekyll_pages_api_search/compressor.rb +15 -0
- data/lib/jekyll_pages_api_search/js_copier.rb +21 -7
- data/lib/jekyll_pages_api_search/sass.rb +8 -1
- data/lib/jekyll_pages_api_search/search.rb +3 -1
- data/lib/jekyll_pages_api_search/search_hook.rb +3 -4
- data/lib/jekyll_pages_api_search/site.rb +29 -0
- data/lib/jekyll_pages_api_search/standalone.rb +36 -0
- data/lib/jekyll_pages_api_search/tags.rb +7 -3
- data/lib/jekyll_pages_api_search/version.rb +1 -1
- data/lib/jekyll_pages_api_search.rb +3 -0
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63e2ed79ef91f5ef84da6ddee3dcf31392715499
|
4
|
+
data.tar.gz: 1910b3230c724c1d508fefef542300d0bf320be8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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,
|
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
|
-
|
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, '',
|
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
|
-
|
39
|
-
|
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 =
|
24
|
-
|
25
|
-
|
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,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.
|
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-
|
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
|