jekyll-wikilinks 0.0.5 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,237 +0,0 @@
1
- require_relative "naming_const"
2
-
3
- module JekyllWikiLinks
4
- REGEX_LINK_EMBED = /(?<embed>(\!))/i # 0 (capture index for WikiLinks class)
5
- REGEX_LINK_TYPE = /::/
6
- REGEX_LINK_HEADER = /\#/
7
- REGEX_LINK_BLOCK = /\#\^/
8
- REGEX_LINK_LABEL = /\|/
9
- REGEX_WIKI_LINKS = %r{
10
- (#{REGEX_LINK_EMBED})?
11
- (#{REGEX_LINK_TYPE_TXT}#{REGEX_LINK_TYPE})?
12
- \[\[
13
- #{REGEX_FILENAME}
14
- (#{REGEX_LINK_HEADER}#{REGEX_HEADER_TXT})?
15
- (#{REGEX_LINK_BLOCK}#{REGEX_BLOCK_ID_TXT})?
16
- (#{REGEX_LINK_LABEL}#{REGEX_LABEL_TXT})?
17
- \]\]
18
- }x
19
- REGEX_TYPED_LINK_BLOCK = /#{REGEX_LINK_TYPE_TXT}#{REGEX_LINK_TYPE}\[\[#{REGEX_FILENAME}\]\]\n/i
20
-
21
- # more of a "parser" than a parser
22
- class Parser
23
- attr_accessor :doc_manager, :markdown_converter, :wikilinks, :typed_link_blocks
24
-
25
- # Use Jekyll's native relative_url filter
26
- include Jekyll::Filters::URLFilters
27
-
28
- def initialize(context, markdown_converter, doc_manager)
29
- @context ||= context
30
- @doc_manager ||= doc_manager
31
- @markdown_converter ||= markdown_converter
32
- @wikilinks, @typed_link_blocks = [], []
33
- end
34
-
35
- def parse(doc_content)
36
- @typed_link_blocks, @wikilinks = [], []
37
- # process blocks
38
- typed_link_block_matches = doc_content.scan(REGEX_TYPED_LINK_BLOCK)
39
- if !typed_link_block_matches.nil? && typed_link_block_matches.size != 0
40
- typed_link_block_matches.each do |wl_match|
41
- typed_link_block_wikilink = WikiLink.new(
42
- nil,
43
- wl_match[0],
44
- wl_match[1],
45
- nil,
46
- nil,
47
- nil,
48
- )
49
- doc_content.gsub!(typed_link_block_wikilink.md_link_str, "")
50
- @typed_link_blocks << typed_link_block_wikilink
51
- end
52
- end
53
- # process inlines
54
- wikilink_matches = doc_content.scan(REGEX_WIKI_LINKS)
55
- if !wikilink_matches.nil? && wikilink_matches.size != 0
56
- wikilink_matches.each do |wl_match|
57
- @wikilinks << WikiLink.new(
58
- wl_match[0],
59
- wl_match[1],
60
- wl_match[2],
61
- wl_match[3],
62
- wl_match[4],
63
- wl_match[5],
64
- )
65
- end
66
- end
67
- # replace text
68
- return if @wikilinks.nil?
69
- @wikilinks.each do |wikilink|
70
- doc_content.sub!(
71
- wikilink.md_link_regex,
72
- self.build_html(wikilink)
73
- )
74
- end
75
- end
76
-
77
- def build_html_embed(title, content, url)
78
- # multi-line for readability
79
- return [
80
- "<div class=\"wiki-link-embed\">",
81
- "<div class=\"wiki-link-embed-title\">",
82
- "#{title}",
83
- "</div>",
84
- "<div class=\"wiki-link-embed-content\">",
85
- "#{@markdown_converter.convert(content)}",
86
- "</div>",
87
- "<a class=\"wiki-link-embed-link\" href=\"#{url}\"></a>",
88
- "</div>",
89
- ].join("\n").gsub!("\n", "")
90
- end
91
-
92
- def build_html_img_embed(img_file)
93
- "<p><span class=\"wiki-link-embed-image\"><img class=\"wiki-link-img\" src=\"#{relative_url(img_file.relative_path)}\"/></span></p>"
94
- end
95
-
96
- def build_html(wikilink)
97
- if wikilink.is_img?
98
- linked_doc = @doc_manager.get_image_by_bname(wikilink.filename)
99
- if wikilink.embedded? && wikilink.is_img?
100
- return build_html_img_embed(linked_doc)
101
- end
102
- end
103
- linked_doc = @doc_manager.get_doc_by_fname(wikilink.filename)
104
- if !linked_doc.nil?
105
- link_type = wikilink.typed? ? " link-type #{wikilink.link_type}" : ""
106
-
107
- # label
108
- wikilink_inner_txt = wikilink.clean_label_txt if wikilink.labelled?
109
-
110
- lnk_doc_rel_url = relative_url(linked_doc.url) if linked_doc&.url
111
- # TODO not sure about downcase
112
- fname_inner_txt = linked_doc['title'].downcase if wikilink_inner_txt.nil?
113
-
114
- link_lvl = wikilink.describe['level']
115
- if (link_lvl == "file")
116
- wikilink_inner_txt = "#{fname_inner_txt}" if wikilink_inner_txt.nil?
117
- return build_html_embed(
118
- linked_doc['title'],
119
- @doc_manager.get_doc_content(wikilink.filename),
120
- lnk_doc_rel_url
121
- ) if wikilink.embedded?
122
- elsif (link_lvl == "header" && DocManager.doc_has_header?(linked_doc, wikilink.header_txt))
123
- # from: https://github.com/jekyll/jekyll/blob/6855200ebda6c0e33f487da69e4e02ec3d8286b7/Rakefile#L74
124
- lnk_doc_rel_url += "\#" + Jekyll::Utils.slugify(wikilink.header_txt)
125
- wikilink_inner_txt = "#{fname_inner_txt} > #{wikilink.header_txt}" if wikilink_inner_txt.nil?
126
- elsif (link_lvl == "block" && DocManager.doc_has_block_id?(linked_doc, wikilink.block_id))
127
- lnk_doc_rel_url += "\#" + wikilink.block_id.downcase
128
- wikilink_inner_txt = "#{fname_inner_txt} > ^#{wikilink.block_id}" if wikilink_inner_txt.nil?
129
- else
130
- return '<span title="Content not found." class="invalid-wiki-link">' + wikilink.md_link_str + '</span>'
131
- end
132
- return '<a class="wiki-link' + link_type + '" href="' + lnk_doc_rel_url + '">' + wikilink_inner_txt + '</a>'
133
- else
134
- return '<span title="Content not found." class="invalid-wiki-link">' + wikilink.md_link_str + '</span>'
135
- end
136
- end
137
- end
138
-
139
- # the wikilink class knows everything about the original markdown syntax and its semantic meaning
140
- class WikiLink
141
- attr_accessor :embed, :link_type, :filename, :header_txt, :block_id, :label_txt
142
-
143
- FILENAME = "filename"
144
- HEADER_TXT = "header_txt"
145
- BLOCK_ID = "block_id"
146
-
147
- # parameters ordered by appearance in regex
148
- def initialize(embed, link_type, filename, header_txt, block_id, label_txt)
149
- # super(embed, link_type, filename, header_txt, block_id, label_txt)
150
- @embed ||= embed
151
- @link_type ||= link_type
152
- @filename ||= filename
153
- @header_txt ||= header_txt
154
- @block_id ||= block_id
155
- @label_txt ||= label_txt
156
- end
157
-
158
- # labeles are really flexible, so we need to handle them with a bit more care
159
- def clean_label_txt
160
- return @label_txt.sub("[", "\\[").sub("]", "\\]")
161
- end
162
-
163
- def md_link_str
164
- embed = embedded? ? "!" : ""
165
- link_type = typed? ? "#{@link_type}::" : ""
166
- filename = described?(FILENAME) ? @filename : ""
167
- if described?(HEADER_TXT)
168
- header = "\##{@header_txt}"
169
- block = ""
170
- elsif described?(BLOCK_ID)
171
- header = ""
172
- block = "\#\^#{@block_id}"
173
- elsif !described?(FILENAME)
174
- Jekyll.logger.error "Invalid link level in 'md_link_str'. See WikiLink's 'md_link_str' for details"
175
- end
176
- label_ = labelled? ? "\|#{@label_txt}" : ""
177
- return "#{embed}#{link_type}\[\[#{filename}#{header}#{block}#{label_}\]\]"
178
- end
179
-
180
- def md_link_regex
181
- regex_embed = embedded? ? REGEX_LINK_EMBED : %r{}
182
- regex_link_type = typed? ? %r{#{@link_type}#{REGEX_LINK_TYPE}} : %r{}
183
- filename = described?(FILENAME) ? @filename : ""
184
- if described?(HEADER_TXT)
185
- header = %r{#{REGEX_LINK_HEADER}#{@header_txt}}
186
- block = %r{}
187
- elsif described?(BLOCK_ID)
188
- header = %r{}
189
- block = %r{#{REGEX_LINK_BLOCK}#{@block_id}}
190
- elsif !described?(FILENAME)
191
- Jekyll.logger.error "Invalid link level in regex. See WikiLink's 'md_link_regex' for details"
192
- end
193
- label_ = labelled? ? %r{#{REGEX_LINK_LABEL}#{clean_label_txt}} : %r{}
194
- return %r{#{regex_embed}#{regex_link_type}\[\[#{filename}#{header}#{block}#{label_}\]\]}
195
- end
196
-
197
- def describe
198
- return {
199
- 'level' => level,
200
- 'labelled' => labelled?,
201
- 'embedded' => embedded?,
202
- 'typed_link' => typed?,
203
- }
204
- end
205
-
206
- def labelled?
207
- return !@label_txt.nil? && !@label_txt.empty?
208
- end
209
-
210
- def typed?
211
- return !@link_type.nil? && !@link_type.empty?
212
- end
213
-
214
- def embedded?
215
- return !@embed.nil? && @embed == "!"
216
- end
217
-
218
- def is_img?
219
- # github supported image formats: https://docs.github.com/en/github/managing-files-in-a-repository/working-with-non-code-files/rendering-and-diffing-images
220
- return SUPPORTED_IMG_FORMATS.any?{ |ext| ext == File.extname(@filename).downcase }
221
- end
222
-
223
- def described?(chunk)
224
- return (!@filename.nil? && !@filename.empty?) if chunk == FILENAME
225
- return (!@header_txt.nil? && !@header_txt.empty?) if chunk == HEADER_TXT
226
- return (!@block_id.nil? && !@block_id.empty?) if chunk == BLOCK_ID
227
- Jekyll.logger.error "There is no link level '#{chunk}' in WikiLink Struct"
228
- end
229
-
230
- def level
231
- return "file" if described?(FILENAME) && !described?(HEADER_TXT) && !described?(BLOCK_ID)
232
- return "header" if described?(FILENAME) && described?(HEADER_TXT) && !described?(BLOCK_ID)
233
- return "block" if described?(FILENAME) && !described?(HEADER_TXT) && described?(BLOCK_ID)
234
- return "invalid"
235
- end
236
- end
237
- end