jekyll-spaceship 0.2.2 → 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
  SHA256:
3
- metadata.gz: 379152712b0a1373687d9dd83d5e0ed002ba62c891d6746a5dd0968006794023
4
- data.tar.gz: e98e3c2d3819d86132393a63030b1913083373f15fb9cca5ba664c465c078ea0
3
+ metadata.gz: 1eb92f8cf62c528dec112c2cd8a00c7721751942d635065fbfb6c73736c3df9a
4
+ data.tar.gz: 3c6a315b49882a071dfd0b85bf55197023156855bd618360f33e27564b77823c
5
5
  SHA512:
6
- metadata.gz: 28199f722743b52508263c323c75eed9a014ec3abf567803bfbdf72aa7823fe4a28a4b8f486093e043b05e6e398f8badc988640e649c7d62eb930e9c161cab9e
7
- data.tar.gz: b13bed955b451fa8c807f4cc85cb6293a89b01b199d6fcb4a195907caa649560b3cf7efe8838e44e904749386a23c32222a46ff3b154b00f183fa00e2429464b
6
+ metadata.gz: bb0565056cbdb3df43cab239326364e680bba9ef87068ca1e823c24cfc03a77495c8e29efb4d2df0c51b68a0c9cc95fa1a450860cc1bdeaf91ffd3d164118733
7
+ data.tar.gz: a033c89fbda99d63221689e07089cc3875304e74b08332bb1c91599476302ebbaa8ce91876072996811191bcaf84dc92e5f8bc5864153bdd953b588aa4e9831d
@@ -9,4 +9,5 @@ module Jekyll::Spaceship
9
9
  Register.use 'table-processor'
10
10
  Register.use 'mathjax-processor'
11
11
  Register.use 'plantuml-processor'
12
+ Register.use 'polyfill-processor'
12
13
  end
@@ -6,12 +6,12 @@ module Jekyll::Spaceship
6
6
  class Logger
7
7
  def self.display_info
8
8
  self.log "Jekyll-Spaceship #{Jekyll::Spaceship::VERSION}"
9
- self.log "A Jekyll plugin to provide powerful supports."
10
- self.log "https://github.com/jeffreytse/jekyll-spaceship"
9
+ self.log 'A Jekyll plugin to provide powerful supports.'
10
+ self.log 'https://github.com/jeffreytse/jekyll-spaceship'
11
11
  end
12
12
 
13
13
  def self.log(content)
14
- self.output "Jekyll Spaceship", content
14
+ self.output 'Jekyll Spaceship', content
15
15
  end
16
16
 
17
17
  def self.output(title, content)
@@ -1,10 +1,62 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'nokogiri'
4
+
3
5
  module Jekyll::Spaceship
4
6
  class Processor
7
+ @@_hooks = {}
5
8
  @@_registers = []
9
+ @@_processers = []
10
+ @@_priority = nil
11
+
12
+ attr_accessor :priority
13
+ attr_accessor :page
14
+ attr_accessor :handled
15
+
16
+ DEFAULT_PRIORITY = 20
17
+
18
+ PRIORITY_MAP = {
19
+ :low => 10,
20
+ :normal => 20,
21
+ :high => 30,
22
+ }.freeze
23
+
24
+ HTML_EXTENSIONS = %w(
25
+ .html
26
+ .xhtml
27
+ .htm
28
+ ).freeze
29
+
30
+ CSS_EXTENSIONS = %w(
31
+ .css
32
+ .scss
33
+ ).freeze
34
+
35
+ MD_EXTENSIONS = %w(
36
+ .md
37
+ .markdown
38
+ ).freeze
6
39
 
7
40
  def initialize()
41
+ self.initialize_priority
42
+ self.initialize_register
43
+ end
44
+
45
+ def initialize_priority
46
+ @@_priority = DEFAULT_PRIORITY if @@_priority.nil?
47
+ @priority = @@_priority
48
+ @@_priority = nil
49
+
50
+ @@_processers.push(self)
51
+ @@_processers = @@_processers.sort { |a, b| b.priority <=> a.priority }
52
+ end
53
+
54
+ def initialize_register
55
+ if @@_registers.size.zero?
56
+ self.class.register :pages, :pre_render, :post_render
57
+ self.class.register :posts, :pre_render, :post_render
58
+ end
59
+
8
60
  @@_registers.each do |_register|
9
61
  container = _register.first
10
62
  events = _register.last.uniq
@@ -13,57 +65,215 @@ module Jekyll::Spaceship
13
65
  next !events.any?(event.to_s.gsub(/^pre/, 'post').to_sym)
14
66
  end
15
67
  events.each do |event|
16
- register container, event
68
+ self.class.hook container, event
17
69
  end
18
70
  end
19
71
  @@_registers.clear
20
72
  end
21
73
 
22
- def content_tag(post)
23
- # pre-handle content
24
- content_tag = "<content_tag id=\"#{post.url}\" />"
74
+ def self.priority(value)
75
+ value = value.to_sym
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
25
83
  end
26
84
 
27
85
  def self.register(container, *events)
28
86
  @@_registers << [container, events]
29
87
  end
30
88
 
31
- def register(container, event, &block)
32
- # define handle proc
33
- handle = ->(post) {
34
- method = "on_#{container}_#{event}"
35
- self.send method, post if self.respond_to? method
36
- block.call(post) if block
89
+ def self.hook_register(container, event)
90
+ hook_name = "#{container}_#{event}".to_sym
91
+ return false if @@_hooks.has_key? hook_name
92
+ @@_hooks[hook_name] = true
93
+ end
94
+
95
+ def self.hook(container, event, &block)
96
+ return if not hook_register container, event
97
+
98
+ # define dispatch proc
99
+ dispatch = ->(instance) {
100
+ @@_processers.each do |processor|
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
37
116
  }
38
117
 
39
- if event.to_s.start_with?("after")
40
- Jekyll::Hooks.register container, event do |post|
41
- handle.call post
118
+ if event.to_s.start_with?('after')
119
+ Jekyll::Hooks.register container, event do |instance|
120
+ dispatch.call instance
121
+ end
122
+ elsif event.to_s.start_with?('post')
123
+ Jekyll::Hooks.register container, event do |instance|
124
+ dispatch.call instance
125
+ end
126
+
127
+ # auto add pre-event
128
+ register container, event.to_s.sub('post', 'pre').to_sym
129
+ elsif event.to_s.start_with?('pre')
130
+ Jekyll::Hooks.register container, event do |instance|
131
+ dispatch.call instance
42
132
  end
43
- elsif event.to_s.start_with?("post")
44
- Jekyll::Hooks.register container, event do |post|
45
- # remove content tags
46
- tag = self.content_tag(post)
47
- post.content = post.content.gsub(tag, "")
133
+ end
134
+ end
48
135
 
49
- handle.call post
136
+ def dispatch(container, event)
137
+ method = "on_#{container}_#{event}"
138
+ self.send method, @page if self.respond_to? method
50
139
 
51
- # replace output content
52
- post.output = post.output.gsub(/#{tag}.*#{tag}/m, post.content)
140
+ if event.to_s.start_with?('pre')
141
+ if markdown? ext
142
+ method = 'on_handle_markdown'
143
+ else
144
+ method = ''
53
145
  end
54
146
 
55
- # auto add pre-event
56
- register container, event.to_s.sub("post", "pre").to_sym
57
- elsif event.to_s.start_with?("pre")
58
- Jekyll::Hooks.register container, event do |post|
59
- # wrap post content with tags
60
- tag = self.content_tag(post)
147
+ if self.respond_to? method
148
+ @page.content = self.send method, @page.content
149
+ end
150
+ else
151
+ if html? output_ext
152
+ method = 'on_handle_html'
153
+ elsif css? output_ext
154
+ method = 'on_handle_css'
155
+ else
156
+ method = ''
157
+ end
158
+
159
+ if self.respond_to? method
160
+ @page.output = self.send method, @page.output
161
+ end
162
+ end
163
+ end
164
+
165
+ def html?(_ext)
166
+ self.class.html? _ext
167
+ end
168
+
169
+ def css?(_ext)
170
+ self.class.css? _ext
171
+ end
61
172
 
62
- handle.call post
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
202
+ end
203
+
204
+ def output_ext
205
+ self.class.output_ext @page
206
+ end
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)
218
+ end
219
+
220
+ def on_handled
221
+ processor = self.class.name.split('::').last
222
+ file = page.path.gsub(/.*_posts\//, '')
223
+ Logger.log "[#{processor}] #{file}"
224
+ end
63
225
 
64
- post.content = "#{tag}\n#{post.content}\n#{tag}"
226
+ def self.handle_html_block(instance)
227
+ doc = Nokogiri::HTML(instance.output)
228
+
229
+ doc.css('script').each do |node|
230
+ blk_type = node['type']
231
+ blk_content = node.content
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')
65
241
  end
242
+
243
+ @@_processers.each do |processor|
244
+ processor.page = instance
245
+ next if not processor.process?
246
+
247
+ # dispatch to on_handle_html_block
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
260
+ 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)
66
274
  end
275
+
276
+ instance.output = doc.to_html
67
277
  end
68
278
  end
69
279
  end
@@ -5,10 +5,10 @@ module Jekyll::Spaceship
5
5
  def self.walk(start, &block)
6
6
  Dir.foreach start do |x|
7
7
  path = File.join(start, x)
8
- if x == "." or x == ".."
8
+ if x == '.' or x == '..'
9
9
  next
10
10
  elsif File.directory?(path)
11
- block.call(path + "/")
11
+ block.call(path + '/')
12
12
  walk path
13
13
  else
14
14
  block.call(path)
@@ -1,20 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'nokogiri'
3
+ require "nokogiri"
4
4
 
5
5
  module Jekyll::Spaceship
6
6
  class MathjaxProcessor < Processor
7
- register :posts, :post_render
7
+ def process?
8
+ return true if html?(output_ext)
9
+ end
8
10
 
9
- def on_posts_post_render(post)
11
+ def on_handle_html(content)
10
12
  # use nokogiri to parse html
11
- doc = Nokogiri::HTML(post.output)
13
+ doc = Nokogiri::HTML(content)
14
+
15
+ head = doc.at('head')
16
+ return content if head.nil?
17
+ return content if not self.has_mathjax_expression? doc
18
+
19
+ self.handled = true
12
20
 
13
21
  params = "config=TeX-AMS-MML_HTMLorMML"
14
22
  src = "//cdn.mathjax.org/mathjax/latest/MathJax.js?#{params}"
15
- doc.at('head').add_child("<script src=\"#{src}\"></script>")
23
+ config = "MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});"
24
+ head.add_child("<script src=\"#{src}\">#{config}</script>")
25
+
26
+ doc.to_html
27
+ end
28
+
29
+ def has_mathjax_expression?(doc)
30
+ doc.css('p').each do |node|
31
+ if node.content.match(/\$.+\$/)
32
+ return true
33
+ end
34
+ end
16
35
 
17
- post.output = doc.to_s
36
+ doc.css('script').each do |node|
37
+ type = node['type']
38
+ if type and type.match(/math\/tex/)
39
+ return true
40
+ end
41
+ end
42
+ false
18
43
  end
19
44
  end
20
45
  end
@@ -2,16 +2,14 @@
2
2
 
3
3
  module Jekyll::Spaceship
4
4
  class PlantUMLProcessor < Processor
5
- register :posts, :pre_render
6
-
7
- def on_posts_pre_render(post)
5
+ def on_handle_markdown(content)
8
6
  # match default plantuml block and code block
9
7
  pattern = Regexp.union(
10
8
  /(\\?@startuml((?:.|\n)*?)@enduml)/,
11
9
  /(`{3}\s*plantuml((?:.|\n)*?)`{3})/
12
10
  )
13
11
 
14
- post.content.scan pattern do |match|
12
+ content.scan pattern do |match|
15
13
  match = match.select { |m| not m.nil? }
16
14
  block = match[0]
17
15
  code = match[1]
@@ -21,16 +19,16 @@ module Jekyll::Spaceship
21
19
  next
22
20
  end
23
21
 
24
- Logger.log "handle plantuml block - #{post.path.gsub(/.*_posts\//, '')}"
22
+ self.handled = true
25
23
 
26
- post.content = post.content.gsub(
24
+ content = content.gsub(
27
25
  block,
28
26
  handle_plantuml(code)
29
27
  )
30
28
  end
31
29
 
32
30
  # handle escape default plantuml block
33
- post.content = post.content.gsub(/\\(@startuml|@enduml)/, '\1')
31
+ content.gsub(/\\(@startuml|@enduml)/, '\1')
34
32
  end
35
33
 
36
34
  def handle_plantuml(code)
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll::Spaceship
4
+ class PolyfillProcessor < Processor
5
+ priority :high
6
+
7
+ def on_handle_markdown(content)
8
+ # escape ordered list.
9
+ rexp = /(\s*)(?<!\\)\\(?=\d+\.)/
10
+ self.handled = true if content.match?(rexp)
11
+ content.gsub(rexp, '\1&#8291;')
12
+ end
13
+ end
14
+ end
@@ -1,23 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "ostruct"
4
- require 'nokogiri'
4
+ require "nokogiri"
5
5
 
6
6
  module Jekyll::Spaceship
7
7
  class TableProcessor < Processor
8
- register :posts, :pre_render, :post_render
9
-
10
- def on_posts_pre_render(post)
11
- # pre-handle table in markdown
12
- post.content = post.content
13
- .gsub(/\|(?=\|)/, '\\|')
8
+ def on_handle_markdown(content)
9
+ # escape | and :
10
+ content = content.gsub(/\|(?=\|)/, '\\|')
14
11
  .gsub(/\\:(?=.*?(?<!\\)\|)/, '\\\\\\\\:')
15
12
  .gsub(/((?<!\\)\|.*?)(\\:)/, '\1\\\\\\\\:')
13
+
14
+ # escape * and _ and $ etc.
15
+ content.scan(/.*(?<!\\)\|.*/) do |result|
16
+ replace = result.gsub(
17
+ /(?<!(?<!\\)\\)(\*|\$|\[|\(|\"|_)/,
18
+ '\\\\\\\\\1'
19
+ )
20
+ if result != replace
21
+ content = content.gsub(result, replace)
22
+ end
23
+ end
24
+
25
+ content
16
26
  end
17
27
 
18
- def on_posts_post_render(post)
28
+ def on_handle_html(content)
19
29
  # use nokogiri to parse html content
20
- doc = Nokogiri::HTML(post.content)
30
+ doc = Nokogiri::HTML(content)
21
31
 
22
32
  data = OpenStruct.new(_: OpenStruct.new)
23
33
  data.reset = ->(scope, namespace = nil) {
@@ -40,7 +50,7 @@ module Jekyll::Spaceship
40
50
  # handle each table
41
51
  doc.css('table').each do |table|
42
52
  rows = table.css('tr')
43
- data.table= table
53
+ data.table = table
44
54
  data.rows = rows
45
55
  data.reset.call :table
46
56
  rows.each do |row|
@@ -56,9 +66,17 @@ module Jekyll::Spaceship
56
66
  handle_rowspan(data)
57
67
  end
58
68
  end
69
+ rows.each do |row|
70
+ cells = row.css('th, td')
71
+ cells.each do |cell|
72
+ data.cell = cell
73
+ handle_format(data)
74
+ end
75
+ end
76
+ self.handled = true
59
77
  end
60
78
 
61
- post.content = doc.at('body').inner_html
79
+ doc.to_html
62
80
  end
63
81
 
64
82
  def handle_colspan(data)
@@ -84,8 +102,8 @@ module Jekyll::Spaceship
84
102
  if result
85
103
  result = result[0]
86
104
  scope_row.colspan += result.scan(/\|/).count
87
- cell.content = cell.content.gsub(/(\s*\|)+$/, "")
88
- cell.set_attribute("colspan", scope_row.colspan + 1)
105
+ cell.content = cell.content.gsub(/(\s*\|)+$/, '')
106
+ cell.set_attribute('colspan', scope_row.colspan + 1)
89
107
  end
90
108
  end
91
109
 
@@ -116,7 +134,8 @@ module Jekyll::Spaceship
116
134
 
117
135
  if scope_table.multi_row_cells != cells and scope_table.multi_row_start
118
136
  for i in 0...scope_table.multi_row_cells.count do
119
- scope_table.multi_row_cells[i].inner_html += "<br>#{cells[i].content}"
137
+ multi_row_cell = scope_table.multi_row_cells[i]
138
+ multi_row_cell.content += " \n#{cells[i].content}"
120
139
  end
121
140
  row.remove
122
141
  end
@@ -143,11 +162,11 @@ module Jekyll::Spaceship
143
162
  # handle rowspan
144
163
  span_cell = scope_table.span_row_cells[scope_row.col_index]
145
164
  if span_cell and cell.content.match(/^\^{2}/)
146
- cell.content = cell.content.gsub(/^\^{2}/, "")
147
- span_cell.inner_html += "<br>#{cell.content}"
148
- rowspan = span_cell.get_attribute("rowspan") || 1
165
+ cell.content = cell.content.gsub(/^\^{2}/, '')
166
+ span_cell.content += " \n#{cell.content}"
167
+ rowspan = span_cell.get_attribute('rowspan') || 1
149
168
  rowspan = rowspan.to_i + 1
150
- span_cell.set_attribute("rowspan", "#{rowspan}")
169
+ span_cell.set_attribute('rowspan', "#{rowspan}")
151
170
  cell.remove
152
171
  else
153
172
  scope_table.span_row_cells[scope_row.col_index] = cell
@@ -162,27 +181,27 @@ module Jekyll::Spaceship
162
181
  # pre-handle text align
163
182
  align = 0
164
183
  if cell.content.match(/^:(?!:)/)
165
- cell.content = cell.content.gsub(/^:/, "")
184
+ cell.content = cell.content.gsub(/^:/, '')
166
185
  align += 1
167
186
  end
168
187
  if cell.content.match(/(?<!\\):$/)
169
- cell.content = cell.content.gsub(/:$/, "")
188
+ cell.content = cell.content.gsub(/:$/, '')
170
189
  align += 2
171
190
  end
172
191
 
173
192
  # handle escape colon
174
- cell.content = cell.content.gsub(/\\:/, ":")
193
+ cell.content = cell.content.gsub(/\\:/, ':')
175
194
 
176
195
  # handle text align
177
196
  return if align == 0
178
197
 
179
- style = cell.get_attribute("style")
198
+ style = cell.get_attribute('style')
180
199
  if align == 1
181
- align = "text-align: left"
200
+ align = 'text-align: left'
182
201
  elsif align == 2
183
- align = "text-align: right"
202
+ align = 'text-align: right'
184
203
  elsif align == 3
185
- align = "text-align: center"
204
+ align = 'text-align: center'
186
205
  end
187
206
 
188
207
  # handle existed inline-style
@@ -191,7 +210,16 @@ module Jekyll::Spaceship
191
210
  else
192
211
  style = align
193
212
  end
194
- cell.set_attribute("style", style)
213
+ cell.set_attribute('style', style)
214
+ end
215
+
216
+ def handle_format(data)
217
+ cell = data.cell
218
+ cvter = self.converter('markdown')
219
+ return if cvter.nil?
220
+ content = cell.content.gsub(/(?<!\\)\|/, '\\|')
221
+ content = cvter.convert(content.strip)
222
+ cell.inner_html = Nokogiri::HTML.fragment(content)
195
223
  end
196
224
  end
197
225
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Jekyll
4
4
  module Spaceship
5
- VERSION = "0.2.2"
5
+ VERSION = "0.3.0"
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.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - jeffreytse
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-07 00:00:00.000000000 Z
11
+ date: 2020-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -98,6 +98,7 @@ files:
98
98
  - lib/jekyll-spaceship/cores/register.rb
99
99
  - lib/jekyll-spaceship/processors/mathjax-processor.rb
100
100
  - lib/jekyll-spaceship/processors/plantuml-processor.rb
101
+ - lib/jekyll-spaceship/processors/polyfill-processor.rb
101
102
  - lib/jekyll-spaceship/processors/table-processor.rb
102
103
  - lib/jekyll-spaceship/utils/plantuml/plantuml.jar
103
104
  - lib/jekyll-spaceship/version.rb