jekyll-wikilinks 0.0.7 → 0.0.8
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/lib/jekyll-wikilinks/config.rb +17 -13
- data/lib/jekyll-wikilinks/patch/doc_manager.rb +43 -19
- data/lib/jekyll-wikilinks/patch/site.rb +1 -1
- data/lib/jekyll-wikilinks/plugins/filter.rb +23 -21
- data/lib/jekyll-wikilinks/plugins/generator.rb +4 -4
- data/lib/jekyll-wikilinks/util/link_index.rb +42 -65
- data/lib/jekyll-wikilinks/util/parser.rb +70 -364
- data/lib/jekyll-wikilinks/util/regex.rb +36 -30
- data/lib/jekyll-wikilinks/util/wikilink.rb +278 -0
- data/lib/jekyll-wikilinks/version.rb +1 -1
- data/lib/jekyll-wikilinks.rb +3 -22
- metadata +3 -2
@@ -1,4 +1,6 @@
|
|
1
|
+
require "nokogiri"
|
1
2
|
require_relative "regex"
|
3
|
+
require_relative "wikilink"
|
2
4
|
|
3
5
|
module Jekyll
|
4
6
|
module WikiLinks
|
@@ -14,145 +16,55 @@ module Jekyll
|
|
14
16
|
|
15
17
|
def initialize(site)
|
16
18
|
@context ||= Jekyll::WikiLinks::Context.new(site)
|
19
|
+
# do not use @dm in parser -- it is only meant to be passed down into wikilink classes.
|
17
20
|
@doc_manager ||= site.doc_mngr
|
18
21
|
@markdown_converter ||= site.find_converter_instance(CONVERTER_CLASS)
|
19
|
-
@wikilink_blocks, @wikilink_inlines = [], []
|
22
|
+
@wikilink_blocks, @wikilink_inlines = [], []
|
20
23
|
end
|
21
24
|
|
22
25
|
# parsing
|
23
26
|
|
24
|
-
def parse(doc_content)
|
25
|
-
@wikilink_blocks, @wikilink_inlines = [], []
|
27
|
+
def parse(doc_filename, doc_content)
|
28
|
+
@wikilink_blocks, @wikilink_inlines = [], []
|
26
29
|
if !$wiki_conf.disabled_attributes?
|
27
|
-
self.
|
28
|
-
self.parse_block_lists_mkdn(doc_content)
|
29
|
-
self.parse_block_lists_comma(doc_content)
|
30
|
+
self.parse_blocks(doc_filename, doc_content)
|
30
31
|
end
|
31
|
-
self.parse_inlines(doc_content)
|
32
|
-
end
|
33
|
-
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
link_type
|
43
|
-
bullet_type
|
44
|
-
filename,
|
32
|
+
self.parse_inlines(doc_filename, doc_content)
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_blocks(doc_filename, doc_content)
|
36
|
+
block_matches = doc_content.scan(REGEX_WIKI_LINK_BLOCKS)
|
37
|
+
if !block_matches.nil? && block_matches.size != 0
|
38
|
+
block_matches.each do |wl_match|
|
39
|
+
# init block wikilink
|
40
|
+
wikilink_block = WikiLinkBlock.new(
|
41
|
+
@doc_manager,
|
42
|
+
doc_filename,
|
43
|
+
wl_match[0], # link_type
|
44
|
+
wl_match[2], # bullet_type
|
45
45
|
)
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
def parse_block_lists_comma(doc_content)
|
53
|
-
processing_link_type = nil
|
54
|
-
processing_wikilink_list = nil
|
55
|
-
bullet_type = ","
|
56
|
-
typed_link_block_list_item_matches = doc_content.scan(REGEX_TYPED_LINK_BLOCK_LIST_COMMA)
|
57
|
-
if !typed_link_block_list_item_matches.nil? && typed_link_block_list_item_matches.size != 0
|
58
|
-
# Match 1
|
59
|
-
# link-type-txt link-type
|
60
|
-
# filename link
|
61
|
-
# 3. alink
|
62
|
-
# Match 2
|
63
|
-
# link-type-txt
|
64
|
-
# filename
|
65
|
-
# 3. blink
|
66
|
-
# Match 3
|
67
|
-
# link-type-txt
|
68
|
-
# filename
|
69
|
-
# 3. clink
|
70
|
-
typed_link_block_list_item_matches.each do |wl_match|
|
71
|
-
link_type = wl_match[0]
|
72
|
-
link_filename_1 = wl_match[1]
|
73
|
-
link_filename_2 = wl_match[2]
|
74
|
-
if !link_type.nil?
|
75
|
-
# process previous wikilink_list
|
76
|
-
if !processing_wikilink_list.nil? && processing_wikilink_list.has_items?
|
77
|
-
@wikilink_blocks << processing_wikilink_list
|
78
|
-
doc_content.gsub!(processing_wikilink_list.md_regex, "\n")
|
79
|
-
end
|
80
|
-
processing_link_type = link_type
|
81
|
-
processing_wikilink_list = WikiLinkBlock.new(processing_link_type, bullet_type, link_filename_1)
|
82
|
-
processing_wikilink_list.add_item(bullet_type, link_filename_2) if !link_filename_2.nil?
|
83
|
-
else
|
84
|
-
Jekyll.logger.error("'processing_wikilink_list' was nil") if processing_wikilink_list.nil?
|
85
|
-
processing_wikilink_list.add_item(bullet_type, link_filename_2)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
# process previous wikilink_list
|
89
|
-
if !processing_wikilink_list.nil? && processing_wikilink_list.has_items?
|
90
|
-
@wikilink_blocks << processing_wikilink_list
|
91
|
-
doc_content.gsub!(processing_wikilink_list.md_regex, "\n")
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def parse_block_lists_mkdn(doc_content)
|
97
|
-
processing_link_type = nil
|
98
|
-
processing_wikilink_list = nil
|
99
|
-
bullet_type = nil
|
100
|
-
typed_link_block_list_item_matches = doc_content.scan(REGEX_TYPED_LINK_BLOCK_LIST_MKDN)
|
101
|
-
if !typed_link_block_list_item_matches.nil? && typed_link_block_list_item_matches.size != 0
|
102
|
-
# Match 1
|
103
|
-
# link-type-txt more-types
|
104
|
-
# bullet
|
105
|
-
# filename
|
106
|
-
# Match 2
|
107
|
-
# link-type-txt
|
108
|
-
# bullet *
|
109
|
-
# filename alink
|
110
|
-
# Match 3
|
111
|
-
# link-type-txt
|
112
|
-
# bullet *
|
113
|
-
# filename blink
|
114
|
-
# Match 4
|
115
|
-
# link-type-txt more-types
|
116
|
-
# bullet
|
117
|
-
# filename
|
118
|
-
# Match 5
|
119
|
-
# link-type-txt
|
120
|
-
# bullet +
|
121
|
-
# filename alink
|
122
|
-
# Match 6
|
123
|
-
# link-type-txt
|
124
|
-
# bullet +
|
125
|
-
# filename blink
|
126
|
-
typed_link_block_list_item_matches.each do |wl_match|
|
127
|
-
link_type = wl_match[0]
|
128
|
-
bullet_type = wl_match[1]
|
129
|
-
link_filename = wl_match[2]
|
130
|
-
if !link_type.nil?
|
131
|
-
# process previous wikilink_list
|
132
|
-
if !processing_wikilink_list.nil? && processing_wikilink_list.has_items?
|
133
|
-
@wikilink_blocks << processing_wikilink_list
|
134
|
-
doc_content.gsub!(processing_wikilink_list.md_regex, "\n")
|
46
|
+
# extract + add filenames
|
47
|
+
items = wl_match[1]
|
48
|
+
filename_matches = items.scan(/#{REGEX_LINK_LEFT}#{REGEX_FILENAME}#{REGEX_LINK_RIGHT}/i)
|
49
|
+
filename_matches.each do |match|
|
50
|
+
match.each do |fname|
|
51
|
+
wikilink_block.add_item(fname)
|
135
52
|
end
|
136
|
-
processing_link_type = link_type
|
137
|
-
processing_wikilink_list = WikiLinkBlock.new(processing_link_type)
|
138
|
-
else
|
139
|
-
Jekyll.logger.error("'processing_wikilink_list' was nil") if processing_wikilink_list.nil?
|
140
|
-
processing_wikilink_list.add_item(bullet_type, link_filename)
|
141
53
|
end
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
@wikilink_blocks << processing_wikilink_list
|
146
|
-
doc_content.gsub!(processing_wikilink_list.md_regex, "\n")
|
54
|
+
# replace text
|
55
|
+
doc_content.gsub!(wikilink_block.md_regex, "\n")
|
56
|
+
@wikilink_blocks << wikilink_block
|
147
57
|
end
|
148
58
|
end
|
149
59
|
end
|
150
60
|
|
151
|
-
def parse_inlines(doc_content)
|
152
|
-
|
153
|
-
if !
|
154
|
-
|
61
|
+
def parse_inlines(doc_filename, doc_content)
|
62
|
+
inline_matches = doc_content.scan(REGEX_WIKI_LINK_INLINES)
|
63
|
+
if !inline_matches.nil? && inline_matches.size != 0
|
64
|
+
inline_matches.each do |wl_match|
|
155
65
|
@wikilink_inlines << WikiLinkInline.new(
|
66
|
+
@doc_manager,
|
67
|
+
doc_filename,
|
156
68
|
wl_match[0],
|
157
69
|
wl_match[1],
|
158
70
|
wl_match[2],
|
@@ -167,7 +79,7 @@ module Jekyll
|
|
167
79
|
self.sort_typed_first
|
168
80
|
@wikilink_inlines.each do |wikilink|
|
169
81
|
doc_content.gsub!(
|
170
|
-
wikilink.
|
82
|
+
wikilink.md_regex,
|
171
83
|
self.build_html(wikilink)
|
172
84
|
)
|
173
85
|
end
|
@@ -198,50 +110,43 @@ module Jekyll
|
|
198
110
|
end
|
199
111
|
return "<p><span class=\"#{$wiki_conf.css_name("embed_image_wrapper")}\">#{svg_content}</span></p>"
|
200
112
|
else
|
201
|
-
return "<p><span class=\"#{$wiki_conf.css_name("embed_image_wrapper")}\"><img class=\"#{$wiki_conf.css_name("embed_image")}\" src=\"#{relative_url(static_doc.relative_path)}\"
|
113
|
+
return "<p><span class=\"#{$wiki_conf.css_name("embed_image_wrapper")}\"><img class=\"#{$wiki_conf.css_name("embed_image")}\" src=\"#{relative_url(static_doc.relative_path)}\"></span></p>"
|
202
114
|
end
|
203
115
|
end
|
204
116
|
|
205
117
|
def build_html(wikilink)
|
206
|
-
if wikilink.
|
207
|
-
|
208
|
-
if wikilink.embedded? && wikilink.is_img?
|
209
|
-
return build_html_img_embed(linked_static_doc, is_svg=wikilink.is_img_svg?)
|
210
|
-
end
|
118
|
+
if !wikilink.is_valid?
|
119
|
+
return '<span class="' + $wiki_conf.css_name("invalid_wiki") + '">' + wikilink.md_str + '</span>'
|
211
120
|
end
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
return '<a class="' + $wiki_conf.css_name("wiki") + link_type + '" href="' + lnk_doc_rel_url + '">' + wikilink_inner_txt + '</a>'
|
242
|
-
else
|
243
|
-
return '<span class="' + $wiki_conf.css_name("invalid_wiki") + '">' + wikilink.md_link_str + '</span>'
|
244
|
-
end
|
121
|
+
# image processing
|
122
|
+
if wikilink.embedded? && wikilink.is_img?
|
123
|
+
return build_html_img_embed(wikilink.linked_img, is_svg=wikilink.is_img_svg?)
|
124
|
+
end
|
125
|
+
# markdown file processing
|
126
|
+
linked_doc = wikilink.linked_doc
|
127
|
+
link_type_txt = wikilink.is_typed? ? " #{$wiki_conf.css_name("typed")} #{wikilink.link_type}" : ""
|
128
|
+
|
129
|
+
inner_txt = wikilink.label_txt if wikilink.labelled?
|
130
|
+
lnk_doc_rel_url = relative_url(linked_doc.url)
|
131
|
+
|
132
|
+
if (wikilink.level == "file")
|
133
|
+
inner_txt = "#{linked_doc['title'].downcase}" if inner_txt.nil?
|
134
|
+
return build_html_embed(
|
135
|
+
linked_doc['title'],
|
136
|
+
linked_doc.content,
|
137
|
+
lnk_doc_rel_url
|
138
|
+
) if wikilink.embedded?
|
139
|
+
elsif (wikilink.level == "header")
|
140
|
+
# from: https://github.com/jekyll/jekyll/blob/6855200ebda6c0e33f487da69e4e02ec3d8286b7/Rakefile#L74
|
141
|
+
lnk_doc_rel_url += "\#" + Jekyll::Utils.slugify(wikilink.header_txt)
|
142
|
+
inner_txt = "#{linked_doc['title'].downcase} > #{wikilink.header_txt.downcase}" if inner_txt.nil?
|
143
|
+
elsif (wikilink.level == "block")
|
144
|
+
lnk_doc_rel_url += "\#" + wikilink.block_id
|
145
|
+
inner_txt = "#{linked_doc['title'].downcase} > ^#{wikilink.block_id}" if inner_txt.nil?
|
146
|
+
else
|
147
|
+
Jekyll.logger.error("Jekyll-Wikilinks: Invalid wikilink level")
|
148
|
+
end
|
149
|
+
return '<a class="' + $wiki_conf.css_name("wiki") + link_type_txt + '" href="' + lnk_doc_rel_url + '">' + inner_txt + '</a>'
|
245
150
|
end
|
246
151
|
|
247
152
|
# helpers
|
@@ -254,210 +159,11 @@ module Jekyll
|
|
254
159
|
# appears as both untyped and typed in a document)
|
255
160
|
temp = @wikilink_inlines.dup
|
256
161
|
@wikilink_inlines.clear()
|
257
|
-
typed_wikilinks = temp.select { |wl| wl.
|
258
|
-
untyped_wikilinks = temp.select { |wl| !wl.
|
162
|
+
typed_wikilinks = temp.select { |wl| wl.is_typed? }
|
163
|
+
untyped_wikilinks = temp.select { |wl| !wl.is_typed? }
|
259
164
|
@wikilink_inlines = typed_wikilinks.concat(untyped_wikilinks)
|
260
165
|
end
|
261
166
|
end
|
262
167
|
|
263
|
-
# validation
|
264
|
-
|
265
|
-
def has_target_attr?(attribute)
|
266
|
-
attribute.list_item.each do |li|
|
267
|
-
return false if @doc_manager.get_doc_by_fname(li[1]).nil?
|
268
|
-
end
|
269
|
-
return true
|
270
|
-
end
|
271
|
-
|
272
|
-
def has_target_wl?(wikilink)
|
273
|
-
level = wikilink.describe['level']
|
274
|
-
linked_doc = @doc_manager.get_doc_by_fname(wikilink.filename)
|
275
|
-
return false if linked_doc.nil?
|
276
|
-
return false if level == "header" && !DocManager.doc_has_header?(linked_doc, wikilink.header_txt)
|
277
|
-
return false if level == "block" && !DocManager.doc_has_block_id?(linked_doc, wikilink.block_id)
|
278
|
-
return true
|
279
|
-
end
|
280
|
-
|
281
|
-
# wikilinks
|
282
|
-
|
283
|
-
class WikiLinkBlock
|
284
|
-
attr_accessor :link_type, :list_items
|
285
|
-
|
286
|
-
# parameters ordered by appearance in regex
|
287
|
-
def initialize(link_type, bullet_type=nil, filename=nil)
|
288
|
-
@link_type ||= link_type
|
289
|
-
@list_items = [] # li[0] = bullet_type; li[1] = filename
|
290
|
-
@list_items << [ bullet_type, filename ] if !bullet_type.nil? && !filename.nil?
|
291
|
-
end
|
292
|
-
|
293
|
-
def add_item(bullet_type, filename)
|
294
|
-
return if bullet_type.nil? || bullet_type.empty? || filename.nil? || filename.empty?
|
295
|
-
@list_items << [ bullet_type, filename ]
|
296
|
-
end
|
297
|
-
|
298
|
-
def md_regex
|
299
|
-
if typed? && has_items?
|
300
|
-
# single
|
301
|
-
if bullet_type?.empty?
|
302
|
-
link_type = %r{#{@link_type}#{REGEX_LINK_TYPE}}
|
303
|
-
list_item_strs = @list_items.map { |li| /#{REGEX_LINK_LEFT}#{li[1]}#{REGEX_LINK_RIGHT}\n/i }
|
304
|
-
md_link_regex = /#{link_type}#{list_item_strs.join("")}/i
|
305
|
-
# list (comma)
|
306
|
-
elsif bullet_type? == ","
|
307
|
-
tmp_list_items = @list_items.dup
|
308
|
-
first_item = tmp_list_items.shift()
|
309
|
-
link_type = /#{@link_type}#{REGEX_LINK_TYPE}#{REGEX_LINK_LEFT}#{first_item[1]}#{REGEX_LINK_RIGHT}\s*/i
|
310
|
-
list_item_strs = tmp_list_items.map { |li| /#{li[0]}\s*#{REGEX_LINK_LEFT}#{li[1]}#{REGEX_LINK_RIGHT}\s*/i }
|
311
|
-
md_link_regex = /#{link_type}#{list_item_strs.join('')}/i
|
312
|
-
# list (md)
|
313
|
-
elsif !bullet_type?.match(REGEX_BULLET).nil?
|
314
|
-
link_type = %r{#{@link_type}#{REGEX_LINK_TYPE}\n}
|
315
|
-
list_item_strs = @list_items.map { |li| /#{Regexp.escape(li[0])}\s#{REGEX_LINK_LEFT}#{li[1]}#{REGEX_LINK_RIGHT}\n/i }
|
316
|
-
md_link_regex = /#{link_type}#{list_item_strs.join("")}/i
|
317
|
-
else
|
318
|
-
Jekyll.logger.error("bullet_types not uniform or invalid: #{bullet_type?}")
|
319
|
-
end
|
320
|
-
return md_link_regex
|
321
|
-
else
|
322
|
-
Jekyll.logger.error("WikiLinkBlockList.md_regex error")
|
323
|
-
end
|
324
|
-
end
|
325
|
-
|
326
|
-
def md_str
|
327
|
-
if typed? && has_items?
|
328
|
-
if bullet_type? == ","
|
329
|
-
link_type = "#{@link_type}::"
|
330
|
-
list_item_strs = @list_items.map { |li| "\[\[#{li[1]}\]\]#{li[0]}" }
|
331
|
-
md_link_str = (link_type + list_item_strs.join('')).delete_suffix(",")
|
332
|
-
elsif "+*-".include?(bullet_type?)
|
333
|
-
link_type = "#{@link_type}::\n"
|
334
|
-
list_item_strs = @list_items.map { |li| li[0] + " \[\[#{li[1]}\]\]\n" }
|
335
|
-
md_link_str = link_type + list_item_strs.join('')
|
336
|
-
else
|
337
|
-
Jekyll.logger.error("Not a valid bullet_type: #{bullet_type?}")
|
338
|
-
end
|
339
|
-
return md_link_str
|
340
|
-
else
|
341
|
-
Jekyll.logger.error("WikiLinkBlockList.md_str error")
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
def bullet_type?
|
346
|
-
bullets = @list_items.map { |li| li[0] }
|
347
|
-
return bullets.uniq.first if bullets.uniq.size == 1
|
348
|
-
end
|
349
|
-
|
350
|
-
def has_items?
|
351
|
-
return !@list_items.nil? && !@list_items.empty?
|
352
|
-
end
|
353
|
-
|
354
|
-
def typed?
|
355
|
-
return !@link_type.nil? && !@link_type.empty?
|
356
|
-
end
|
357
|
-
end
|
358
|
-
|
359
|
-
# the wikilink class knows everything about the original markdown syntax and its semantic meaning
|
360
|
-
class WikiLinkInline
|
361
|
-
attr_accessor :embed, :link_type, :filename, :header_txt, :block_id, :label_txt
|
362
|
-
|
363
|
-
FILENAME = "filename"
|
364
|
-
HEADER_TXT = "header_txt"
|
365
|
-
BLOCK_ID = "block_id"
|
366
|
-
|
367
|
-
# parameters ordered by appearance in regex
|
368
|
-
def initialize(embed, link_type, filename, header_txt, block_id, label_txt)
|
369
|
-
@embed ||= embed
|
370
|
-
@link_type ||= link_type
|
371
|
-
@filename ||= filename
|
372
|
-
@header_txt ||= header_txt
|
373
|
-
@block_id ||= block_id
|
374
|
-
@label_txt ||= label_txt
|
375
|
-
end
|
376
|
-
|
377
|
-
# labels are really flexible, so we need to handle them with a bit more care
|
378
|
-
def clean_label_txt
|
379
|
-
return @label_txt.sub("[", "\\[").sub("]", "\\]")
|
380
|
-
end
|
381
|
-
|
382
|
-
# TODO: remove this once parsing is migrated to nokogiri...?
|
383
|
-
def md_link_str
|
384
|
-
embed = embedded? ? "!" : ""
|
385
|
-
link_type = typed? ? "#{@link_type}::" : ""
|
386
|
-
filename = described?(FILENAME) ? @filename : ""
|
387
|
-
if described?(HEADER_TXT)
|
388
|
-
header = "\##{@header_txt}"
|
389
|
-
block = ""
|
390
|
-
elsif described?(BLOCK_ID)
|
391
|
-
header = ""
|
392
|
-
block = "\#\^#{@block_id}"
|
393
|
-
elsif !described?(FILENAME)
|
394
|
-
Jekyll.logger.error "Invalid link level in 'md_link_str'. See WikiLink's 'md_link_str' for details"
|
395
|
-
end
|
396
|
-
label_ = labelled? ? "\|#{@label_txt}" : ""
|
397
|
-
return "#{embed}#{link_type}\[\[#{filename}#{header}#{block}#{label_}\]\]"
|
398
|
-
end
|
399
|
-
|
400
|
-
def md_link_regex
|
401
|
-
regex_embed = embedded? ? REGEX_LINK_EMBED : %r{}
|
402
|
-
regex_link_type = typed? ? %r{#{@link_type}#{REGEX_LINK_TYPE}} : %r{}
|
403
|
-
filename = described?(FILENAME) ? @filename : ""
|
404
|
-
if described?(HEADER_TXT)
|
405
|
-
header = %r{#{REGEX_LINK_HEADER}#{@header_txt}}
|
406
|
-
block = %r{}
|
407
|
-
elsif described?(BLOCK_ID)
|
408
|
-
header = %r{}
|
409
|
-
block = %r{#{REGEX_LINK_BLOCK}#{@block_id}}
|
410
|
-
elsif !described?(FILENAME)
|
411
|
-
Jekyll.logger.error "Invalid link level in regex. See WikiLink's 'md_link_regex' for details"
|
412
|
-
end
|
413
|
-
label_ = labelled? ? %r{#{REGEX_LINK_LABEL}#{clean_label_txt}} : %r{}
|
414
|
-
return %r{#{regex_embed}#{regex_link_type}#{REGEX_LINK_LEFT}#{filename}#{header}#{block}#{label_}#{REGEX_LINK_RIGHT}}
|
415
|
-
end
|
416
|
-
|
417
|
-
def describe
|
418
|
-
return {
|
419
|
-
'level' => level,
|
420
|
-
'labelled' => labelled?,
|
421
|
-
'embedded' => embedded?,
|
422
|
-
'typed_link' => typed?,
|
423
|
-
}
|
424
|
-
end
|
425
|
-
|
426
|
-
def labelled?
|
427
|
-
return !@label_txt.nil? && !@label_txt.empty?
|
428
|
-
end
|
429
|
-
|
430
|
-
def typed?
|
431
|
-
return !@link_type.nil? && !@link_type.empty?
|
432
|
-
end
|
433
|
-
|
434
|
-
def embedded?
|
435
|
-
return !@embed.nil? && @embed == "!"
|
436
|
-
end
|
437
|
-
|
438
|
-
def is_img?
|
439
|
-
# github supported image formats: https://docs.github.com/en/github/managing-files-in-a-repository/working-with-non-code-files/rendering-and-diffing-images
|
440
|
-
return SUPPORTED_IMG_FORMATS.any?{ |ext| ext == File.extname(@filename).downcase }
|
441
|
-
end
|
442
|
-
|
443
|
-
def is_img_svg?
|
444
|
-
return File.extname(@filename).downcase == ".svg"
|
445
|
-
end
|
446
|
-
|
447
|
-
def described?(chunk)
|
448
|
-
return (!@filename.nil? && !@filename.empty?) if chunk == FILENAME
|
449
|
-
return (!@header_txt.nil? && !@header_txt.empty?) if chunk == HEADER_TXT
|
450
|
-
return (!@block_id.nil? && !@block_id.empty?) if chunk == BLOCK_ID
|
451
|
-
Jekyll.logger.error "There is no link level '#{chunk}' in WikiLink Struct"
|
452
|
-
end
|
453
|
-
|
454
|
-
def level
|
455
|
-
return "file" if described?(FILENAME) && !described?(HEADER_TXT) && !described?(BLOCK_ID)
|
456
|
-
return "header" if described?(FILENAME) && described?(HEADER_TXT) && !described?(BLOCK_ID)
|
457
|
-
return "block" if described?(FILENAME) && !described?(HEADER_TXT) && described?(BLOCK_ID)
|
458
|
-
return "invalid"
|
459
|
-
end
|
460
|
-
end
|
461
|
-
|
462
168
|
end
|
463
169
|
end
|
@@ -12,37 +12,43 @@ module Jekyll
|
|
12
12
|
SUPPORTED_IMG_FORMATS = Set.new(['.png', '.jpg', '.gif', '.psd', '.svg'])
|
13
13
|
|
14
14
|
# wikilink constants
|
15
|
-
REGEX_LINK_LEFT
|
16
|
-
REGEX_LINK_RIGHT
|
17
|
-
REGEX_LINK_EMBED
|
18
|
-
REGEX_LINK_TYPE
|
19
|
-
REGEX_LINK_HEADER
|
20
|
-
REGEX_LINK_BLOCK
|
21
|
-
REGEX_LINK_LABEL
|
15
|
+
REGEX_LINK_LEFT = /\[\[/
|
16
|
+
REGEX_LINK_RIGHT = /\]\]/
|
17
|
+
REGEX_LINK_EMBED = /(?<embed>\!)/
|
18
|
+
REGEX_LINK_TYPE = /\s*::\s*/
|
19
|
+
REGEX_LINK_HEADER = /\#/
|
20
|
+
REGEX_LINK_BLOCK = /\#\^/
|
21
|
+
REGEX_LINK_LABEL = /\|/
|
22
22
|
|
23
|
-
#
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
23
|
+
# wikitext usable char requirements
|
24
|
+
REGEX_LINK_TYPE_CHARS = /[^\n\s\!\#\^\|\]]+/i
|
25
|
+
REGEX_FILENAME_CHARS = /[^\\\/:\#\^\|\[\]]+/i
|
26
|
+
REGEX_HEADER_CHARS = /[^\!\#\^\|\[\]]+/i
|
27
|
+
REGEX_BLOCK_ID_CHARS = /[^\\\/:\!\#\^\|\[\]^\n]+/i
|
28
|
+
REGEX_LABEL_CHARS = /(.+?)(?=\]{2}[^\]])/i
|
29
|
+
|
30
|
+
# capture groups
|
31
|
+
REGEX_LINK_TYPE_TXT = /(?<link-type-txt>#{REGEX_LINK_TYPE_CHARS})/i
|
32
|
+
REGEX_FILENAME = /(?<filename>#{REGEX_FILENAME_CHARS})/i
|
33
|
+
REGEX_HEADER_TXT = /(?<header-txt>#{REGEX_HEADER_CHARS})/i
|
34
|
+
REGEX_BLOCK_ID_TXT = /(?<block-id>#{REGEX_BLOCK_ID_CHARS})/i
|
35
|
+
REGEX_LABEL_TXT = /(?<label-txt>#{REGEX_LABEL_CHARS})/i
|
29
36
|
|
30
37
|
# target markdown text (headers, lists, and blocks)
|
31
38
|
## kramdown regexes
|
32
39
|
### atx header: https://github.com/gettalong/kramdown/blob/master/lib/kramdown/parser/kramdown/header.rb#L29
|
33
|
-
REGEX_ATX_HEADER
|
40
|
+
REGEX_ATX_HEADER = /^\#{1,6}[\t ]*([^ \t].*)\n/i
|
34
41
|
### setext header: https://github.com/gettalong/kramdown/blob/master/lib/kramdown/parser/kramdown/header.rb#L17
|
35
|
-
REGEX_SETEXT_HEADER
|
42
|
+
REGEX_SETEXT_HEADER = /^\s{0,3}([^ \t].*)\n[-=][-=]*[ \t\r\f\v]*\n/i
|
36
43
|
## list item: https://github.com/gettalong/kramdown/blob/master/lib/kramdown/parser/kramdown/list.rb#L49
|
37
|
-
REGEX_BULLET
|
38
|
-
|
39
|
-
|
40
|
-
## new-markdown-style
|
41
|
-
REGEX_BLOCK = /.*\s\^#{REGEX_BLOCK_ID_TXT}/i
|
44
|
+
REGEX_BULLET = /(?<bullet>[+*-])/i
|
45
|
+
## markdown-style block-reference
|
46
|
+
REGEX_BLOCK = /.*\s\^#{REGEX_BLOCK_ID_TXT}/i
|
42
47
|
|
43
48
|
# wikilinks
|
49
|
+
|
44
50
|
## inline
|
45
|
-
|
51
|
+
REGEX_WIKI_LINK_INLINES = %r{ # capture indeces
|
46
52
|
(#{REGEX_LINK_EMBED})? # 0
|
47
53
|
(#{REGEX_LINK_TYPE_TXT}#{REGEX_LINK_TYPE})? # 1
|
48
54
|
#{REGEX_LINK_LEFT}
|
@@ -52,15 +58,15 @@ module Jekyll
|
|
52
58
|
(#{REGEX_LINK_LABEL}#{REGEX_LABEL_TXT})? # 5
|
53
59
|
#{REGEX_LINK_RIGHT}
|
54
60
|
}x
|
55
|
-
## block
|
56
|
-
REGEX_TYPED_LINK_BLOCK = /#{REGEX_LINK_TYPE_TXT}#{REGEX_LINK_TYPE}#{REGEX_LINK_LEFT}#{REGEX_FILENAME}#{REGEX_LINK_RIGHT}\n/i
|
57
|
-
# TODO: keep an eye on this -- using REGEX_FILENAME in two places
|
58
|
-
REGEX_TYPED_LINK_BLOCK_LIST_COMMA = /(?:#{REGEX_LINK_TYPE_TXT}#{REGEX_LINK_TYPE}\s*(?:#{REGEX_LINK_LEFT}#{REGEX_FILENAME}#{REGEX_LINK_RIGHT})\s*|\G)\s*(?:,\s*#{REGEX_LINK_LEFT}#{REGEX_FILENAME}#{REGEX_LINK_RIGHT})\s*/i
|
59
|
-
REGEX_TYPED_LINK_BLOCK_LIST_MKDN = /#{REGEX_LINK_TYPE_TXT}#{REGEX_LINK_TYPE}\n|\G(?:#{REGEX_LIST_ITEM}\n)/i
|
60
|
-
|
61
|
-
# parsing for wikilinks in html
|
62
|
-
# identify missing links in doc via .invalid-wiki-link class and nested doc-text.
|
63
|
-
REGEX_INVALID_WIKI_LINK = /invalid-wiki-link(?:[^\]]+)\[\[(?<wiki-text>([^\]]+))\]\]/i
|
64
61
|
|
62
|
+
## block
|
63
|
+
### single
|
64
|
+
REGEX_SINGLE = /#{REGEX_LINK_LEFT}#{REGEX_FILENAME_CHARS}#{REGEX_LINK_RIGHT}/i
|
65
|
+
### list (comma is responsible for catching the single case)
|
66
|
+
REGEX_LIST_COMMA = /((?:\s*#{REGEX_SINGLE}\s*)(?:,\s*#{REGEX_SINGLE}\s*)*)/i
|
67
|
+
REGEX_LIST_MKDN = /((?<=\n)\s{0,3}#{REGEX_BULLET}\s#{REGEX_SINGLE}\s*)+/i # (see REGEX_LIST_ITEM)
|
68
|
+
### process
|
69
|
+
REGEX_BLOCK_TYPES = /((?<!\n)(?:#{REGEX_LIST_COMMA})|#{REGEX_LIST_MKDN})/i
|
70
|
+
REGEX_WIKI_LINK_BLOCKS = /^\s{0,3}#{REGEX_LINK_TYPE_TXT}#{REGEX_LINK_TYPE}(?:\s*|\G)(?<items>#{REGEX_BLOCK_TYPES})\n/i
|
65
71
|
end
|
66
72
|
end
|