jekyll-spaceship 0.4.0 → 0.5.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 +4 -4
- data/.codeclimate.yml +38 -0
- data/.github/FUNDING.yml +12 -0
- data/.travis.yml +32 -0
- data/README.md +111 -11
- data/Rakefile +8 -0
- data/jekyll-spaceship.gemspec +4 -4
- data/lib/jekyll-spaceship.rb +2 -0
- data/lib/jekyll-spaceship/cores/logger.rb +12 -0
- data/lib/jekyll-spaceship/cores/manager.rb +118 -0
- data/lib/jekyll-spaceship/cores/processor.rb +83 -200
- data/lib/jekyll-spaceship/cores/register.rb +1 -5
- data/lib/jekyll-spaceship/cores/type.rb +41 -0
- data/lib/jekyll-spaceship/processors/emoji-processor.rb +65 -0
- data/lib/jekyll-spaceship/processors/mathjax-processor.rb +9 -3
- data/lib/jekyll-spaceship/processors/plantuml-processor.rb +2 -0
- data/lib/jekyll-spaceship/processors/polyfill-processor.rb +1 -1
- data/lib/jekyll-spaceship/processors/table-processor.rb +56 -57
- data/lib/jekyll-spaceship/processors/video-processor.rb +15 -7
- data/lib/jekyll-spaceship/version.rb +1 -1
- data/logos/jekyll-spaceship-logo.png +0 -0
- data/script/cibuild +6 -0
- data/script/test +4 -0
- metadata +34 -17
@@ -1,54 +1,46 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'nokogiri'
|
4
|
-
|
5
3
|
module Jekyll::Spaceship
|
6
4
|
class Processor
|
7
|
-
@@_hooks = {}
|
8
|
-
@@_registers = []
|
9
|
-
@@_processers = []
|
10
|
-
@@_priority = nil
|
11
|
-
|
12
|
-
attr_accessor :priority
|
13
|
-
attr_accessor :page
|
14
|
-
attr_accessor :handled
|
15
|
-
|
16
5
|
DEFAULT_PRIORITY = 20
|
17
6
|
|
18
7
|
PRIORITY_MAP = {
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
8
|
+
:lowest => 0,
|
9
|
+
:low => 10,
|
10
|
+
:normal => 20,
|
11
|
+
:high => 30,
|
12
|
+
:highest => 40,
|
22
13
|
}.freeze
|
23
14
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
.htm
|
28
|
-
).freeze
|
15
|
+
@@_registers = []
|
16
|
+
@@_exclusions = []
|
17
|
+
@@_priority = nil
|
29
18
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
19
|
+
attr_reader :page
|
20
|
+
attr_reader :logger
|
21
|
+
attr_reader :priority
|
22
|
+
attr_reader :registers
|
23
|
+
attr_reader :exclusions
|
24
|
+
attr_accessor :handled
|
34
25
|
|
35
|
-
|
36
|
-
.
|
37
|
-
|
38
|
-
).freeze
|
26
|
+
def name
|
27
|
+
self.class.name.split('::').last
|
28
|
+
end
|
39
29
|
|
40
30
|
def initialize()
|
41
31
|
self.initialize_priority
|
42
32
|
self.initialize_register
|
33
|
+
self.initialize_exclusions
|
34
|
+
@logger = Logger.new(self.name)
|
43
35
|
end
|
44
36
|
|
45
37
|
def initialize_priority
|
46
|
-
@@_priority = DEFAULT_PRIORITY if @@_priority.nil?
|
47
38
|
@priority = @@_priority
|
39
|
+
unless @priority.nil? or @priority.is_a? Numeric
|
40
|
+
@priority = PRIORITY_MAP[@priority.to_sym]
|
41
|
+
end
|
42
|
+
@priority = DEFAULT_PRIORITY if @priority.nil?
|
48
43
|
@@_priority = nil
|
49
|
-
|
50
|
-
@@_processers.push(self)
|
51
|
-
@@_processers = @@_processers.sort { |a, b| b.priority <=> a.priority }
|
52
44
|
end
|
53
45
|
|
54
46
|
def initialize_register
|
@@ -56,224 +48,115 @@ module Jekyll::Spaceship
|
|
56
48
|
self.class.register :pages, :pre_render, :post_render
|
57
49
|
self.class.register :posts, :pre_render, :post_render
|
58
50
|
end
|
51
|
+
@registers = Array.new @@_registers
|
52
|
+
@@_registers.clear
|
53
|
+
end
|
59
54
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
events = events.select do |event|
|
64
|
-
next true if event.match(/^post/)
|
65
|
-
next !events.any?(event.to_s.gsub(/^pre/, 'post').to_sym)
|
66
|
-
end
|
67
|
-
events.each do |event|
|
68
|
-
self.class.hook container, event
|
69
|
-
end
|
55
|
+
def initialize_exclusions
|
56
|
+
if @@_exclusions.size.zero?
|
57
|
+
self.class.exclude :code, :block_quotes
|
70
58
|
end
|
71
|
-
@@
|
59
|
+
@exclusions = @@_exclusions.uniq
|
60
|
+
@@_exclusions.clear
|
72
61
|
end
|
73
62
|
|
74
63
|
def self.priority(value)
|
75
|
-
|
76
|
-
if PRIORITY_MAP.has_key? value
|
77
|
-
@@_priority = PRIORITY_MAP[value]
|
78
|
-
elsif value.nil?
|
79
|
-
@@_priority = DEFAULT_PRIORITY
|
80
|
-
else
|
81
|
-
@@_priority = value
|
82
|
-
end
|
64
|
+
@@_priority = value.to_sym
|
83
65
|
end
|
84
66
|
|
85
67
|
def self.register(container, *events)
|
86
68
|
@@_registers << [container, events]
|
87
69
|
end
|
88
70
|
|
89
|
-
def self.
|
90
|
-
|
91
|
-
return false if @@_hooks.has_key? hook_name
|
92
|
-
@@_hooks[hook_name] = true
|
71
|
+
def self.exclude(*types)
|
72
|
+
@@_exclusions = types
|
93
73
|
end
|
94
74
|
|
95
|
-
def
|
96
|
-
|
75
|
+
def process?
|
76
|
+
Type.html?(output_ext) or Type.markdown?(ext)
|
77
|
+
end
|
97
78
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
processor.page = instance
|
102
|
-
processor.handled = false
|
103
|
-
next if not processor.process?
|
104
|
-
processor.dispatch container, event
|
105
|
-
end
|
106
|
-
if event.to_s.start_with?('post') and self.html? output_ext(instance)
|
107
|
-
self.handle_html_block(instance)
|
108
|
-
end
|
109
|
-
@@_processers.each do |processor|
|
110
|
-
processor.page = instance
|
111
|
-
if processor.handled
|
112
|
-
processor.on_handled
|
113
|
-
end
|
114
|
-
end
|
115
|
-
block.call if block
|
116
|
-
}
|
79
|
+
def ext
|
80
|
+
Manager.ext @page
|
81
|
+
end
|
117
82
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
end
|
122
|
-
elsif event.to_s.start_with?('post')
|
123
|
-
Jekyll::Hooks.register container, event do |instance|
|
124
|
-
dispatch.call instance
|
125
|
-
end
|
83
|
+
def output_ext
|
84
|
+
Manager.output_ext @page
|
85
|
+
end
|
126
86
|
|
127
|
-
|
128
|
-
|
129
|
-
elsif event.to_s.start_with?('pre')
|
130
|
-
Jekyll::Hooks.register container, event do |instance|
|
131
|
-
dispatch.call instance
|
132
|
-
end
|
133
|
-
end
|
87
|
+
def converter(name)
|
88
|
+
Manager.converter @page, name
|
134
89
|
end
|
135
90
|
|
136
|
-
def dispatch(container, event)
|
91
|
+
def dispatch(page, container, event)
|
92
|
+
@page = page
|
93
|
+
@handled = false
|
94
|
+
return unless self.process?
|
137
95
|
method = "on_#{container}_#{event}"
|
138
96
|
self.send method, @page if self.respond_to? method
|
139
|
-
|
97
|
+
method = ''
|
140
98
|
if event.to_s.start_with?('pre')
|
141
|
-
if markdown? ext
|
99
|
+
if Type.markdown? ext
|
142
100
|
method = 'on_handle_markdown'
|
143
|
-
else
|
144
|
-
method = ''
|
145
101
|
end
|
146
|
-
|
147
102
|
if self.respond_to? method
|
103
|
+
@page.content = self.pre_exclude @page.content
|
148
104
|
@page.content = self.send method, @page.content
|
105
|
+
@page.content = self.after_exclude @page.content
|
149
106
|
end
|
150
107
|
else
|
151
|
-
if html? output_ext
|
108
|
+
if Type.html? output_ext
|
152
109
|
method = 'on_handle_html'
|
153
110
|
elsif css? output_ext
|
154
111
|
method = 'on_handle_css'
|
155
|
-
else
|
156
|
-
method = ''
|
157
112
|
end
|
158
|
-
|
159
113
|
if self.respond_to? method
|
160
114
|
@page.output = self.send method, @page.output
|
161
115
|
end
|
162
116
|
end
|
163
117
|
end
|
164
118
|
|
165
|
-
def
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
def css?(_ext)
|
170
|
-
self.class.css? _ext
|
171
|
-
end
|
172
|
-
|
173
|
-
def markdown?(_ext)
|
174
|
-
self.class.markdown? _ext
|
175
|
-
end
|
176
|
-
|
177
|
-
def self.html?(_ext)
|
178
|
-
HTML_EXTENSIONS.include?(_ext)
|
179
|
-
end
|
180
|
-
|
181
|
-
def self.css?(_ext)
|
182
|
-
CSS_EXTENSIONS.include?(_ext)
|
183
|
-
end
|
184
|
-
|
185
|
-
def self.markdown?(_ext)
|
186
|
-
MD_EXTENSIONS.include?(_ext)
|
187
|
-
end
|
188
|
-
|
189
|
-
def converter(name)
|
190
|
-
self.class.converter(@page, name)
|
191
|
-
end
|
192
|
-
|
193
|
-
def self.converter(instance, name)
|
194
|
-
instance.site.converters.each do |converter|
|
195
|
-
class_name = converter.class.to_s.downcase
|
196
|
-
return converter if class_name.end_with?(name.downcase)
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
def ext
|
201
|
-
self.class.ext @page
|
119
|
+
def on_handle_html_block(content, type)
|
120
|
+
# default handle method
|
121
|
+
content
|
202
122
|
end
|
203
123
|
|
204
|
-
def
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
def self.ext(instance)
|
209
|
-
instance.data['ext']
|
210
|
-
end
|
211
|
-
|
212
|
-
def self.output_ext(instance)
|
213
|
-
instance.url_placeholders[:output_ext]
|
214
|
-
end
|
215
|
-
|
216
|
-
def process?
|
217
|
-
html?(output_ext) or markdown?(ext)
|
124
|
+
def on_handle_html(content)
|
125
|
+
# default handle method
|
126
|
+
content
|
218
127
|
end
|
219
128
|
|
220
129
|
def on_handled
|
221
|
-
processor = self.class.name.split('::').last
|
222
130
|
file = page.path.gsub(/.*_posts\//, '')
|
223
|
-
|
131
|
+
logger.log file
|
224
132
|
end
|
225
133
|
|
226
|
-
def
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
cvter = nil
|
234
|
-
method = ''
|
235
|
-
block_method = 'on_handle_html_block'
|
236
|
-
|
237
|
-
case blk_type
|
238
|
-
when 'text/markdown'
|
239
|
-
method = 'on_handle_markdown'
|
240
|
-
cvter = self.converter(instance, 'markdown')
|
134
|
+
def pre_exclude(content)
|
135
|
+
@exclusion_store = []
|
136
|
+
@exclusions.each do |type|
|
137
|
+
regex = nil
|
138
|
+
if type == :code
|
139
|
+
regex = /(`{3}\s*(\w*)((?:.|\n)*?)`{3})/
|
241
140
|
end
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
if processor.respond_to? block_method
|
249
|
-
blk_content = processor.send block_method blk_content, blk_type
|
250
|
-
end
|
251
|
-
|
252
|
-
# dispatch to other handlers
|
253
|
-
if processor.respond_to? method
|
254
|
-
blk_content = processor.send method, blk_content
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
if not cvter.nil?
|
259
|
-
blk_content = cvter.convert blk_content
|
141
|
+
next if regex.nil?
|
142
|
+
content.scan(regex) do |match_data|
|
143
|
+
match = match_data[0]
|
144
|
+
id = @exclusion_store.size
|
145
|
+
content = content.gsub(match, "[//]: JEKYLL_EXCLUDE_##{id}")
|
146
|
+
@exclusion_store.push match
|
260
147
|
end
|
261
|
-
|
262
|
-
next if method == ''
|
263
|
-
|
264
|
-
method = 'on_handle_html'
|
265
|
-
@@_processers.each do |processor|
|
266
|
-
processor.page = instance
|
267
|
-
next if not processor.process?
|
268
|
-
if processor.respond_to? method
|
269
|
-
blk_content = processor.send method, blk_content
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
node.replace Nokogiri::HTML.fragment(blk_content)
|
274
148
|
end
|
149
|
+
content
|
150
|
+
end
|
275
151
|
|
276
|
-
|
152
|
+
def after_exclude(content)
|
153
|
+
while @exclusion_store.size > 0
|
154
|
+
match = @exclusion_store.pop
|
155
|
+
id = @exclusion_store.size
|
156
|
+
content = content.gsub("[//]: JEKYLL_EXCLUDE_##{id}", match)
|
157
|
+
end
|
158
|
+
@exclusion_store = []
|
159
|
+
content
|
277
160
|
end
|
278
161
|
end
|
279
162
|
end
|
@@ -25,20 +25,16 @@ module Jekyll::Spaceship
|
|
25
25
|
next if filename.gsub(/-/, '').downcase != name
|
26
26
|
|
27
27
|
Logger.log "use #{filename}"
|
28
|
-
|
29
28
|
require path
|
30
|
-
|
31
29
|
constants = Jekyll::Spaceship.constants.select do |c|
|
32
30
|
c.downcase.to_s == name
|
33
31
|
end
|
34
32
|
|
35
33
|
next if constants.first.nil?
|
36
|
-
|
37
34
|
_class = Jekyll::Spaceship.const_get(constants.first)
|
38
|
-
|
39
35
|
next unless _class.is_a? Class
|
40
36
|
|
41
|
-
_class.new
|
37
|
+
Manager.add _class.new
|
42
38
|
end
|
43
39
|
end
|
44
40
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jekyll::Spaceship
|
4
|
+
class Type
|
5
|
+
HTML_EXTENSIONS = %w(
|
6
|
+
.html
|
7
|
+
.xhtml
|
8
|
+
.htm
|
9
|
+
).freeze
|
10
|
+
|
11
|
+
CSS_EXTENSIONS = %w(
|
12
|
+
.css
|
13
|
+
.scss
|
14
|
+
).freeze
|
15
|
+
|
16
|
+
MD_EXTENSIONS = %w(
|
17
|
+
.md
|
18
|
+
.markdown
|
19
|
+
).freeze
|
20
|
+
|
21
|
+
HTML_BLOCK_TYPE_MAP = {
|
22
|
+
'text/markdown' => 'markdown',
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
def self.html?(_ext)
|
26
|
+
HTML_EXTENSIONS.include?(_ext)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.css?(_ext)
|
30
|
+
CSS_EXTENSIONS.include?(_ext)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.markdown?(_ext)
|
34
|
+
MD_EXTENSIONS.include?(_ext)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.html_block_type(type)
|
38
|
+
HTML_BLOCK_TYPE_MAP[type]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'uri'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
module Jekyll::Spaceship
|
8
|
+
class EmojiProcessor < Processor
|
9
|
+
EMOJI_MARKUP_HOST = 'https://api.github.com/emojis'
|
10
|
+
EMOJI_MARKUP_DATA = {}
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
super()
|
14
|
+
self.initialize_emoji_data
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize_emoji_data
|
18
|
+
EMOJI_MARKUP_DATA.update get_emoji_markup_data
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_handle_html(content)
|
22
|
+
return content if EMOJI_MARKUP_DATA.size.zero?
|
23
|
+
# handle emoji markup
|
24
|
+
content.scan(/:([\w+-]+):/) do |match_data|
|
25
|
+
emoji_markup = match_data[0]
|
26
|
+
emoji_image = EMOJI_MARKUP_DATA[emoji_markup]
|
27
|
+
next if emoji_image.nil?
|
28
|
+
self.handled = true
|
29
|
+
|
30
|
+
# convert hex string to unicode
|
31
|
+
unicode = emoji_image.match(/unicode\/([\d\w]+)/)
|
32
|
+
if unicode[1]
|
33
|
+
unicode = "0x#{unicode[1]}".to_i(16)
|
34
|
+
alt = [unicode].pack('U*')
|
35
|
+
end
|
36
|
+
alt = emoji_markup if alt.nil?
|
37
|
+
|
38
|
+
content = content.gsub(
|
39
|
+
":#{emoji_markup}:",
|
40
|
+
"<image class=\"emoji\" \
|
41
|
+
title=\"#{emoji_markup}\" \
|
42
|
+
alt=\"#{alt}\" \
|
43
|
+
src=\"#{emoji_image}\" \
|
44
|
+
style=\"vertical-align: middle; \
|
45
|
+
max-width: 1em; visibility: hidden;\" \
|
46
|
+
onload=\"this.style.visibility='visible'\" \
|
47
|
+
onerror=\"this.replaceWith(this.alt)\"> \
|
48
|
+
</image>"
|
49
|
+
)
|
50
|
+
end
|
51
|
+
content
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_emoji_markup_data
|
55
|
+
data = {}
|
56
|
+
begin
|
57
|
+
source = Net::HTTP.get URI(EMOJI_MARKUP_HOST)
|
58
|
+
data = JSON.parse(source)
|
59
|
+
rescue StandardError => msg
|
60
|
+
logger.log msg
|
61
|
+
end
|
62
|
+
data
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|