jekyll-spaceship 0.2.2 → 0.3.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 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