jekyll-wikilinks 0.0.4 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,236 +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
- lnk_doc_rel_url += "\#" + wikilink.header_txt.downcase
124
- wikilink_inner_txt = "#{fname_inner_txt} > #{wikilink.header_txt}" if wikilink_inner_txt.nil?
125
- elsif (link_lvl == "block" && DocManager.doc_has_block_id?(linked_doc, wikilink.block_id))
126
- lnk_doc_rel_url += "\#" + wikilink.block_id.downcase
127
- wikilink_inner_txt = "#{fname_inner_txt} > ^#{wikilink.block_id}" if wikilink_inner_txt.nil?
128
- else
129
- return '<span title="Content not found." class="invalid-wiki-link">' + wikilink.md_link_str + '</span>'
130
- end
131
- return '<a class="wiki-link' + link_type + '" href="' + lnk_doc_rel_url + '">' + wikilink_inner_txt + '</a>'
132
- else
133
- return '<span title="Content not found." class="invalid-wiki-link">' + wikilink.md_link_str + '</span>'
134
- end
135
- end
136
- end
137
-
138
- # the wikilink class knows everything about the original markdown syntax and its semantic meaning
139
- class WikiLink
140
- attr_accessor :embed, :link_type, :filename, :header_txt, :block_id, :label_txt
141
-
142
- FILENAME = "filename"
143
- HEADER_TXT = "header_txt"
144
- BLOCK_ID = "block_id"
145
-
146
- # parameters ordered by appearance in regex
147
- def initialize(embed, link_type, filename, header_txt, block_id, label_txt)
148
- # super(embed, link_type, filename, header_txt, block_id, label_txt)
149
- @embed ||= embed
150
- @link_type ||= link_type
151
- @filename ||= filename
152
- @header_txt ||= header_txt
153
- @block_id ||= block_id
154
- @label_txt ||= label_txt
155
- end
156
-
157
- # labeles are really flexible, so we need to handle them with a bit more care
158
- def clean_label_txt
159
- return @label_txt.sub("[", "\\[").sub("]", "\\]")
160
- end
161
-
162
- def md_link_str
163
- embed = embedded? ? "!" : ""
164
- link_type = typed? ? "#{@link_type}::" : ""
165
- filename = described?(FILENAME) ? @filename : ""
166
- if described?(HEADER_TXT)
167
- header = "\##{@header_txt}"
168
- block = ""
169
- elsif described?(BLOCK_ID)
170
- header = ""
171
- block = "\#\^#{@block_id}"
172
- elsif !described?(FILENAME)
173
- Jekyll.logger.error "Invalid link level in 'md_link_str'. See WikiLink's 'md_link_str' for details"
174
- end
175
- label_ = labelled? ? "\|#{@label_txt}" : ""
176
- return "#{embed}#{link_type}\[\[#{filename}#{header}#{block}#{label_}\]\]"
177
- end
178
-
179
- def md_link_regex
180
- regex_embed = embedded? ? REGEX_LINK_EMBED : %r{}
181
- regex_link_type = typed? ? %r{#{@link_type}#{REGEX_LINK_TYPE}} : %r{}
182
- filename = described?(FILENAME) ? @filename : ""
183
- if described?(HEADER_TXT)
184
- header = %r{#{REGEX_LINK_HEADER}#{@header_txt}}
185
- block = %r{}
186
- elsif described?(BLOCK_ID)
187
- header = %r{}
188
- block = %r{#{REGEX_LINK_BLOCK}#{@block_id}}
189
- elsif !described?(FILENAME)
190
- Jekyll.logger.error "Invalid link level in regex. See WikiLink's 'md_link_regex' for details"
191
- end
192
- label_ = labelled? ? %r{#{REGEX_LINK_LABEL}#{clean_label_txt}} : %r{}
193
- return %r{#{regex_embed}#{regex_link_type}\[\[#{filename}#{header}#{block}#{label_}\]\]}
194
- end
195
-
196
- def describe
197
- return {
198
- 'level' => level,
199
- 'labelled' => labelled?,
200
- 'embedded' => embedded?,
201
- 'typed_link' => typed?,
202
- }
203
- end
204
-
205
- def labelled?
206
- return !@label_txt.nil? && !@label_txt.empty?
207
- end
208
-
209
- def typed?
210
- return !@link_type.nil? && !@link_type.empty?
211
- end
212
-
213
- def embedded?
214
- return !@embed.nil? && @embed == "!"
215
- end
216
-
217
- def is_img?
218
- # github supported image formats: https://docs.github.com/en/github/managing-files-in-a-repository/working-with-non-code-files/rendering-and-diffing-images
219
- return SUPPORTED_IMG_FORMATS.any?{ |ext| ext == File.extname(@filename).downcase }
220
- end
221
-
222
- def described?(chunk)
223
- return (!@filename.nil? && !@filename.empty?) if chunk == FILENAME
224
- return (!@header_txt.nil? && !@header_txt.empty?) if chunk == HEADER_TXT
225
- return (!@block_id.nil? && !@block_id.empty?) if chunk == BLOCK_ID
226
- Jekyll.logger.error "There is no link level '#{chunk}' in WikiLink Struct"
227
- end
228
-
229
- def level
230
- return "file" if described?(FILENAME) && !described?(HEADER_TXT) && !described?(BLOCK_ID)
231
- return "header" if described?(FILENAME) && described?(HEADER_TXT) && !described?(BLOCK_ID)
232
- return "block" if described?(FILENAME) && !described?(HEADER_TXT) && described?(BLOCK_ID)
233
- return "invalid"
234
- end
235
- end
236
- end