jekyll-spaceship 0.9.2 → 0.9.7

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: 604e55f37a3597c851c56fd267f316eea0a180adcb8613c0908efa9f5ea87869
4
- data.tar.gz: a32c960d432a348eb583d2e5d114f66564de56e2726b680765166bce86adbd6f
3
+ metadata.gz: bf1f9c38de511a38ca120048c76fa129f9052acb224eed310ceaada9e94421a0
4
+ data.tar.gz: 7fb2cf77d779023e060d25950e0edf466b6e23e7b30994fba8a656239cd6c100
5
5
  SHA512:
6
- metadata.gz: 4f8383046d4a550ddacd859e14699b90b7a92d3759ebddf34430a8cbe421bfe1334f9a80186b80942aaff96a5802415ff7d01b78ec70939719aa483686238778
7
- data.tar.gz: c9c98d831503df109e943d49030c7a6b7d0a37cd0d1eb0dba6fe39f555ee05ceaf5550d8cbcab10ec8160eb7bdc559db9ca8bcd6a7ec3ddefc813b97ecb7a585
6
+ metadata.gz: 412b791444ca4a08219a8d9e8099ab3f695e435466d27bd7810c368bf6dfe2039cfc5c2275af04db3495cd7d06547283ed49d30a613884fa0a10b65f55a841ea
7
+ data.tar.gz: e399f4b1175694f91b00c1504b6ecb89dc43799ff77f600962f2ebbf45043708fc7c82bb3bbfb4728738e6ccf202a6d1be4b260f8e10b52b24523180f8f2ef1a
data/README.md CHANGED
@@ -177,8 +177,15 @@ jekyll-spaceship:
177
177
  inlineMath:
178
178
  - ['$','$']
179
179
  - ['\(','\)']
180
+ displayMath:
181
+ - ['$$','$$']
182
+ - ['\[','\]']
180
183
  svg:
181
184
  fontCache: 'global'
185
+ optimize: # optimization on building stage to check and add mathjax scripts
186
+ enabled: true # value `false` for adding to all pages
187
+ include: [] # include patterns for math expressions checking (regexp)
188
+ exclude: [] # exclude patterns for math expressions checking (regexp)
182
189
  plantuml-processor:
183
190
  mode: default # mode value 'pre-fetch' for fetching image at building stage
184
191
  css:
@@ -966,7 +973,7 @@ Automatically adds a `target="_blank" rel="noopener noreferrer"` attribute to al
966
973
  jekyll-spaceship:
967
974
  element-processor:
968
975
  css:
969
- - a: # Replce all `a` tags
976
+ - a: # Replace all `a` tags
970
977
  props:
971
978
  class: ['(^.*$)', '\0 ext-link'] # Add `ext-link` to class by regex pattern
972
979
  target: _blank # Replace `target` value to `_blank`
@@ -982,7 +989,7 @@ Automatically adds `loading="lazy"` to `img` and `iframe` tags to natively load
982
989
  jekyll-spaceship:
983
990
  element-processor:
984
991
  css:
985
- - a: # Replce all `a` tags
992
+ - a: # Replace all `a` tags
986
993
  props: #
987
994
  loading: lazy # Replace `loading` value to `lazy`
988
995
  ```
@@ -997,7 +1004,7 @@ See the following examples to prevent lazy loading.
997
1004
  jekyll-spaceship:
998
1005
  element-processor:
999
1006
  css:
1000
- - a: # Replce all `a` tags
1007
+ - a: # Replace all `a` tags
1001
1008
  props: #
1002
1009
  loading: eager # Replace `loading` value to `eager`
1003
1010
  ```
@@ -31,6 +31,16 @@ module Jekyll::Spaceship
31
31
  first.merge(second.to_h, &merger)
32
32
  end
33
33
 
34
+ def self.deep_dig(obj, key)
35
+ if obj.respond_to?(:key?) && obj.key?(key)
36
+ obj[key]
37
+ elsif obj.respond_to?(:each)
38
+ result = nil
39
+ obj.find { |*a| result = self.deep_dig(a.last, key) }
40
+ result
41
+ end
42
+ end
43
+
34
44
  def self.store(section, default)
35
45
  return @@store[section] if default.nil?
36
46
  @@store[section] = deep_merge(default, @@store[section])
@@ -25,7 +25,11 @@ module Jekyll::Spaceship
25
25
  attr_accessor :handled
26
26
 
27
27
  def name
28
- self.class.name.split('::').last
28
+ self.class.class_name
29
+ end
30
+
31
+ def self.class_name
32
+ self.name.split('::').last
29
33
  end
30
34
 
31
35
  def filename
@@ -116,7 +120,7 @@ module Jekyll::Spaceship
116
120
  if self.respond_to? method
117
121
  @page.content = self.pre_exclude @page.content
118
122
  @page.content = self.send method, @page.content
119
- @page.content = self.after_exclude @page.content
123
+ @page.content = self.post_exclude @page.content
120
124
  end
121
125
  else
122
126
  if Type.html? output_ext
@@ -151,8 +155,8 @@ module Jekyll::Spaceship
151
155
  logger.log file
152
156
  end
153
157
 
154
- def pre_exclude(content)
155
- @exclusion_store = []
158
+ def exclusion_regexs()
159
+ regexs = []
156
160
  @exclusions.each do |type|
157
161
  regex = nil
158
162
  if type == :code
@@ -162,7 +166,14 @@ module Jekyll::Spaceship
162
166
  elsif type == :liquid_filter
163
167
  regex = /((?<!\\)((\{\{[^\n]*?\}\})|(\{%[^\n]*?%\})))/
164
168
  end
165
- next if regex.nil?
169
+ regexs.push regex unless regex.nil?
170
+ end
171
+ regexs
172
+ end
173
+
174
+ def pre_exclude(content, regexs = self.exclusion_regexs())
175
+ @exclusion_store = []
176
+ regexs.each do |regex|
166
177
  content.scan(regex) do |match_data|
167
178
  match = match_data[0]
168
179
  id = @exclusion_store.size
@@ -173,7 +184,7 @@ module Jekyll::Spaceship
173
184
  content
174
185
  end
175
186
 
176
- def after_exclude(content)
187
+ def post_exclude(content)
177
188
  while @exclusion_store.size > 0
178
189
  match = @exclusion_store.pop
179
190
  id = @exclusion_store.size
@@ -205,6 +216,7 @@ module Jekyll::Spaceship
205
216
  'body' => content_body
206
217
  }
207
218
  rescue StandardError => msg
219
+ logger = Logger.new(self.class_name)
208
220
  logger.log msg
209
221
  end
210
222
  end
@@ -11,14 +11,45 @@ module Jekyll::Spaceship
11
11
  'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js',
12
12
  ],
13
13
  'config' => {
14
- 'tex' => { 'inlineMath' => [['$','$'], ['\\(','\\)']] },
14
+ 'tex' => {
15
+ 'inlineMath' => [['$','$'], ['\\(','\\)']],
16
+ 'displayMath' => [['$$','$$'], ['\\[','\\]']]
17
+ },
15
18
  'svg': { 'fontCache': 'global' }
19
+ },
20
+ 'optimize' => {
21
+ 'enabled' => true,
22
+ 'include' => [],
23
+ 'exclude' => []
16
24
  }
17
25
  }
18
26
  end
19
27
 
20
28
  def process?
21
- return true if Type.html?(output_ext)
29
+ return true if Type.html?(output_ext) or Type.markdown?(output_ext)
30
+ end
31
+
32
+ def on_handle_markdown(content)
33
+ # pre-handle mathjax expressions in markdown
34
+ patterns = get_math_patterns()
35
+ patterns['include'].each do |pattern|
36
+ content.scan(pattern) do |result|
37
+ expr = result[0]
38
+ body = result[1]
39
+ next if body.size.zero?
40
+ is_excluded = false
41
+ patterns['exclude'].each do |pe|
42
+ break is_excluded = true if expr.match(/#{pe}/)
43
+ end
44
+ next if is_excluded
45
+ escaped_expr = expr
46
+ .gsub(/(?<!^)\\(?!\S$)/, '\\\\\\\\')
47
+ .gsub(/(?<!\\)\$/, '\\\$')
48
+ .gsub(/\\ /, '\\\\\\ ')
49
+ content = content.gsub(expr, escaped_expr)
50
+ end
51
+ end
52
+ content
22
53
  end
23
54
 
24
55
  def on_handle_html(content)
@@ -45,22 +76,62 @@ module Jekyll::Spaceship
45
76
  end
46
77
 
47
78
  def has_mathjax_expression?(doc)
48
- doc.css('*').each do |node|
49
- if node.content.match(/(?<!\\)\$.+(?<!\\)\$/)
50
- return true
51
- end
52
- if node.content.match(/(?<!\\)\\\(.+(?<!\\)\\\)/)
53
- return true
79
+ return true unless config['optimize']['enabled'] == true
80
+ scan_mathjax_expression(doc) do
81
+ return true
82
+ end
83
+ false
84
+ end
85
+
86
+ def get_math_patterns()
87
+ patterns = []
88
+ math_patterns = []
89
+ ['tex', 'tex2jax'].each do |t|
90
+ ['inlineMath', 'displayMath'].each do |m|
91
+ r = config.dig('config', t, m)
92
+ r&.each do |i|
93
+ btag = Regexp.escape(i[0])
94
+ etag = Regexp.escape(i[1])
95
+ patterns <<= /((?<!\\\\)#{btag}(.*?)(?<!\\\\)#{etag})/
96
+ end
54
97
  end
55
98
  end
99
+ config['optimize']['include'].each do |pattern|
100
+ patterns <<= /(#{pattern})/
101
+ end
102
+ {
103
+ 'include' => patterns,
104
+ 'exclude' => config['optimize']['exclude']
105
+ }
106
+ end
56
107
 
57
- doc.css('script').each do |node|
58
- type = node['type']
59
- if type and type.match(/math\/tex/)
60
- return true
108
+ def scan_mathjax_expression(doc, &block)
109
+ patterns = get_math_patterns()
110
+ doc.css('*').each do |node|
111
+ next if ['code', 'pre', 'figure'].include? node.name
112
+ next if node.ancestors('code, pre, figure').size > 0
113
+ next if node.children.size > 1
114
+ patterns['include'].each do |pattern|
115
+ # check scripting mathjax expression
116
+ if node.name == 'script'
117
+ type = node['type']
118
+ next unless type
119
+ next unless type.match(/math\/tex/)
120
+ end
121
+ # check normal mathjax expression
122
+ node.content.scan(pattern) do |result|
123
+ expr = result[0]
124
+ body = result[1]
125
+ next if body.size.zero?
126
+ is_excluded = false
127
+ patterns['exclude'].each do |pe|
128
+ break is_excluded = true if expr.match(/#{pe}/)
129
+ end
130
+ next if is_excluded
131
+ block.call(node, expr)
132
+ end
61
133
  end
62
134
  end
63
- false
64
135
  end
65
136
  end
66
137
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'uri'
4
+ require "nokogiri"
4
5
 
5
6
  module Jekyll::Spaceship
6
7
  class MediaProcessor < Processor
@@ -18,23 +19,29 @@ module Jekyll::Spaceship
18
19
  }
19
20
  end
20
21
 
21
- def on_handle_markdown(content)
22
- content = handle_normal_audio(content)
23
- content = handle_normal_video(content)
24
- content = handle_youtube(content)
25
- content = handle_vimeo(content)
26
- content = handle_dailymotion(content)
27
- content = handle_spotify(content)
28
- content = handle_soundcloud(content)
22
+ def on_handle_html(content)
23
+ # use nokogiri to parse html content
24
+ doc = Nokogiri::HTML(content)
25
+ # handle each img tag
26
+ doc.css('img').each do |element|
27
+ handle_normal_audio(element)
28
+ handle_normal_video(element)
29
+ handle_youtube(element)
30
+ handle_vimeo(element)
31
+ handle_dailymotion(element)
32
+ handle_spotify(element)
33
+ handle_soundcloud(element)
34
+ end
35
+ doc.to_html
29
36
  end
30
37
 
31
38
  # Examples:
32
39
  # ![audio](//www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3)
33
40
  # ![audio](//www.expample.com/examples/t-rex-roar.mp3?autoplay=true&loop=true)
34
- def handle_normal_audio(content)
35
- handle_media(content, {
41
+ def handle_normal_audio(element)
42
+ handle_media(element, {
36
43
  media_type: 'audio',
37
- host: '(https?:)?\\/\\/.*\\/',
44
+ host: '(https?:\\/\\/)?.*\\/',
38
45
  id: '(.+?\\.(mp3|wav|ogg|mid|midi|aac|wma))',
39
46
  })
40
47
  end
@@ -44,10 +51,10 @@ module Jekyll::Spaceship
44
51
  # ![video](//www.html5rocks.com/en/tutorials/video/basics/devstories.webm)
45
52
  # ![video](//techslides.com/demos/sample-videos/small.ogv?allow=autoplay)
46
53
  # ![video](//techslides.com/demos/sample-videos/small.mp4?width=400)
47
- def handle_normal_video(content)
48
- handle_media(content, {
54
+ def handle_normal_video(element)
55
+ handle_media(element, {
49
56
  media_type: 'iframe',
50
- host: '(https?:)?\\/\\/.*\\/',
57
+ host: '(https?:\\/\\/)?.*\\/',
51
58
  id: '(.+?\\.(avi|mp4|webm|ogg|ogv|flv|mkv|mov|wmv|3gp|rmvb|asf))'
52
59
  })
53
60
  end
@@ -56,8 +63,8 @@ module Jekyll::Spaceship
56
63
  # ![youtube](https://www.youtube.com/watch?v=XA2WjJbmmoM "title")
57
64
  # ![youtube](http://www.youtube.com/embed/w-m_yZCLF5Q)
58
65
  # ![youtube](//youtu.be/mEP3YXaSww8?height=100%&width=400)
59
- def handle_youtube(content)
60
- handle_media(content, {
66
+ def handle_youtube(element)
67
+ handle_media(element, {
61
68
  media_type: 'iframe',
62
69
  host: '(https?:)?\\/\\/.*youtu.*',
63
70
  id: '(?<=\\?v\\=|embed\\/|\\.be\\/)([a-zA-Z0-9\\_\\-]+)',
@@ -68,8 +75,8 @@ module Jekyll::Spaceship
68
75
  # Examples:
69
76
  # ![vimeo](https://vimeo.com/263856289)
70
77
  # ![vimeo](https://vimeo.com/263856289?height=100%&width=400)
71
- def handle_vimeo(content)
72
- handle_media(content, {
78
+ def handle_vimeo(element)
79
+ handle_media(element, {
73
80
  media_type: 'iframe',
74
81
  host: '(https?:)?\\/\\/vimeo\\.com\\/',
75
82
  id: '([0-9]+)',
@@ -80,8 +87,8 @@ module Jekyll::Spaceship
80
87
  # Examples:
81
88
  # ![dailymotion](https://www.dailymotion.com/video/x7tgcev)
82
89
  # ![dailymotion](https://dai.ly/x7tgcev?height=100%&width=400)
83
- def handle_dailymotion(content)
84
- handle_media(content, {
90
+ def handle_dailymotion(element)
91
+ handle_media(element, {
85
92
  media_type: 'iframe',
86
93
  host: '(https?:)?\\/\\/.*dai.?ly.*',
87
94
  id: '(?<=video\\/|\\/)([a-zA-Z0-9\\_\\-]+)',
@@ -92,8 +99,8 @@ module Jekyll::Spaceship
92
99
  # Examples:
93
100
  # ![spotify](//open.spotify.com/track/4Dg5moVCTqxAb7Wr8Dq2T5)
94
101
  # ![spotify](//open.spotify.com/track/37mEkAaqCE7FXMvnlVA8pp?width=400)
95
- def handle_spotify(content)
96
- handle_media(content, {
102
+ def handle_spotify(element)
103
+ handle_media(element, {
97
104
  media_type: 'iframe',
98
105
  host: '(https?:)?\\/\\/open\\.spotify\\.com\\/track\\/',
99
106
  id: '(?<=track\\/)([a-zA-Z0-9\\_\\-]+)',
@@ -104,8 +111,8 @@ module Jekyll::Spaceship
104
111
 
105
112
  # Examples:
106
113
  # ![soundcloud](//soundcloud.com/aviciiofficial/preview-avicii-vs-lenny)
107
- def handle_soundcloud(content)
108
- handle_media(content, {
114
+ def handle_soundcloud(element)
115
+ handle_media(element, {
109
116
  media_type: 'iframe',
110
117
  id_from: 'html',
111
118
  host: '(https?:)?\\/\\/soundcloud\\.com\\/.+\\/[^\\?]+',
@@ -116,71 +123,53 @@ module Jekyll::Spaceship
116
123
  })
117
124
  end
118
125
 
119
- def handle_media(content, data)
126
+ def handle_media(element, data)
120
127
  host = data[:host]
121
- return content if content.sub(/#{host}/, '').nil?
128
+ src = element.get_attribute('src')
129
+ title = element.get_attribute('title')
130
+ id = data[:id_from] === 'html' ? '()' : data[:id]
131
+ match_data = src.match(/#{host}#{id}\S*/)
132
+ return if match_data.nil?
122
133
 
123
134
  media_type = data[:media_type]
124
135
  base_url = data[:base_url]
125
- id = data[:id_from] === 'html' ? '()' : data[:id]
126
- url = "(#{host}#{id}\\S*)"
127
- title = '("(.*)".*){0,1}'
128
-
129
- # pre-handle reference-style links
130
- regex = /(\[(.*)\]:\s*(#{url}\s*#{title}))/
131
- content.scan regex do |match_data|
132
- match = match_data[0]
133
- ref_name = match_data[1]
134
- ref_value = match_data[2]
135
- content = content.gsub(match, '')
136
- .gsub(/\!\[(.*)\]\s*\[#{ref_name}\]/,
137
- "![\1](#{ref_value})")
136
+ id = data[:id_from] === 'html' \
137
+ ? get_id_from_html(src, data[:id]) \
138
+ : match_data[2]
139
+ qs = src.match(/(?<=\?)(\S*?)$/)
140
+ qs = Hash[URI.decode_www_form(qs.to_s)].reject do |k, v|
141
+ next true if v == id or v == ''
138
142
  end
139
143
 
140
- # handle inline-style links
141
- regex = /(\!\[(.*)\]\(.*#{url}\s*#{title}\))/
142
- content.scan regex do |match_data|
143
- url = match_data[2]
144
- id = data[:id_from] === 'html' \
145
- ? get_id_from_html(url, data[:id]) \
146
- : match_data[4]
147
- title = match_data[6]
148
- qs = url.match(/(?<=\?)(\S*?)$/)
149
- qs = Hash[URI.decode_www_form(qs.to_s)].reject do |k, v|
150
- next true if v == id or v == ''
151
- end
152
-
153
- cfg = self.config['default'].clone
154
- cfg['id'] = qs['id'] || cfg['id']
155
- cfg['class'] = qs['class'] || cfg['class']
156
- cfg['style'] = qs['style'] || cfg['style']
157
- cfg['id'] = cfg['id'].gsub('{id}', id)
158
- cfg['class'] = cfg['class'].gsub('{id}', id)
144
+ cfg = self.config['default'].clone
145
+ cfg['id'] = qs['id'] || cfg['id']
146
+ cfg['class'] = qs['class'] || cfg['class']
147
+ cfg['style'] = qs['style'] || cfg['style']
148
+ cfg['id'] = cfg['id'].gsub('{id}', id)
149
+ cfg['class'] = cfg['class'].gsub('{id}', id)
159
150
 
160
- cfg['src'] = URI(base_url ? "#{base_url}#{id}" : url).tap do |v|
161
- v.query = URI.encode_www_form(qs) if qs.size > 0
162
- end
151
+ cfg['src'] = URI(base_url ? "#{base_url}#{id}" : src).tap do |v|
152
+ v.query = URI.encode_www_form(qs) if qs.size > 0
153
+ end
163
154
 
164
- case media_type
165
- when 'audio'
166
- cfg['autoplay'] = qs['autoplay'] || data[:autoplay] || cfg['autoplay']
167
- cfg['loop'] = qs['loop'] || data[:loop] || cfg['loop']
168
- cfg['style'] += ';display: none;' if qs['hidden']
169
- content = handle_audio(content, { target: match_data[0], cfg: cfg })
170
- when 'iframe'
171
- cfg['title'] = title
172
- cfg['width'] = qs['width'] || data[:width] || cfg['width']
173
- cfg['height'] = qs['height'] || data[:height] || cfg['height']
174
- cfg['frameborder'] = qs['frameborder'] || cfg['frameborder']
175
- cfg['allow'] ||= cfg['allow']
176
- content = handle_iframe(content, { target: match_data[0], cfg: cfg })
177
- end
178
- self.handled = true
155
+ case media_type
156
+ when 'audio'
157
+ cfg['autoplay'] = qs['autoplay'] || data[:autoplay] || cfg['autoplay']
158
+ cfg['loop'] = qs['loop'] || data[:loop] || cfg['loop']
159
+ cfg['style'] += ';display: none;' if qs['hidden']
160
+ handle_audio(element, { cfg: cfg })
161
+ when 'iframe'
162
+ cfg['title'] = title
163
+ cfg['width'] = qs['width'] || data[:width] || cfg['width']
164
+ cfg['height'] = qs['height'] || data[:height] || cfg['height']
165
+ cfg['frameborder'] = qs['frameborder'] || cfg['frameborder']
166
+ cfg['allow'] ||= cfg['allow']
167
+ handle_iframe(element, { cfg: cfg })
179
168
  end
180
- content
169
+ self.handled = true
181
170
  end
182
171
 
183
- def handle_audio(content, data)
172
+ def handle_audio(element, data)
184
173
  cfg = data[:cfg]
185
174
  html = "<audio"\
186
175
  " id=\"#{cfg['id']}\""\
@@ -194,10 +183,11 @@ module Jekyll::Spaceship
194
183
  " Here is a <a href=\"#{cfg['src']}\">link to download the audio</a>"\
195
184
  "instead. </p>"\
196
185
  "</audio>"
197
- content.gsub(data[:target], html)
186
+ doc = Nokogiri::XML(html)
187
+ element.replace(doc.children.first)
198
188
  end
199
189
 
200
- def handle_iframe(content, data)
190
+ def handle_iframe(element, data)
201
191
  cfg = data[:cfg]
202
192
  html = "<iframe"\
203
193
  " id=\"#{cfg['id']}\""\
@@ -211,7 +201,8 @@ module Jekyll::Spaceship
211
201
  " frameborder=\"#{cfg['frameborder']}\""\
212
202
  " allowfullscreen>"\
213
203
  "</iframe>"
214
- content.gsub(data[:target], html)
204
+ doc = Nokogiri::XML(html)
205
+ element.replace(doc.children.first)
215
206
  end
216
207
 
217
208
  def get_id_from_html(url, pattern)
@@ -43,7 +43,7 @@ module Jekyll::Spaceship
43
43
  .gsub(/((?<!\\)\${1,2})[^\n]*?\1/, '')
44
44
  .match(/(?<!\\)\|/)
45
45
  replace = result.gsub(
46
- /(?<!(?<!\\)\\)(\*|\$|\[|\(|\"|_)/, '\\\\\\\\\1')
46
+ /(?<!(?<!\\)\\)(\*|\$|\[(?!\^)|\(|\"|_)/, '\\\\\\\\\1')
47
47
  next if result == replace
48
48
  content = content.gsub(result, replace)
49
49
  end
@@ -305,10 +305,12 @@ module Jekyll::Spaceship
305
305
  cvter = self.converter('markdown')
306
306
  return if cvter.nil?
307
307
  content = cell.inner_html
308
+ content = self.pre_exclude(content, [/(\<code.*\>.*\<\/code\>)/])
308
309
  .gsub(/(?<!\\)\|/, '\\|')
309
310
  .gsub(/^\s+|\s+$/, '')
310
311
  .gsub(/&lt;/, '<')
311
312
  .gsub(/&gt;/, '>')
313
+ content = self.post_exclude(content)
312
314
  content = cvter.convert(content)
313
315
  content = Nokogiri::HTML.fragment(content)
314
316
  if content.children.first&.name == 'p'
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Jekyll
4
4
  module Spaceship
5
- VERSION = "0.9.2"
5
+ VERSION = "0.9.7"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-spaceship
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - jeffreytse
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-18 00:00:00.000000000 Z
11
+ date: 2020-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll