jekyll-wikilinks 0.0.3 → 0.0.7
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 +109 -0
- data/lib/jekyll-wikilinks/patch/context.rb +19 -0
- data/lib/jekyll-wikilinks/patch/doc_manager.rb +82 -0
- data/lib/jekyll-wikilinks/patch/site.rb +12 -0
- data/lib/jekyll-wikilinks/plugins/converter.rb +53 -0
- data/lib/jekyll-wikilinks/plugins/filter.rb +73 -0
- data/lib/jekyll-wikilinks/plugins/generator.rb +41 -0
- data/lib/jekyll-wikilinks/util/link_index.rb +112 -0
- data/lib/jekyll-wikilinks/util/parser.rb +463 -0
- data/lib/jekyll-wikilinks/util/regex.rb +66 -0
- data/lib/jekyll-wikilinks/version.rb +7 -3
- data/lib/jekyll-wikilinks.rb +46 -267
- metadata +50 -13
- data/lib/jekyll-wikilinks/context.rb +0 -15
- data/lib/jekyll-wikilinks/filter.rb +0 -28
data/lib/jekyll-wikilinks.rb
CHANGED
@@ -1,271 +1,50 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "jekyll"
|
3
|
-
require_relative "jekyll-wikilinks/context"
|
4
|
-
require_relative "jekyll-wikilinks/filter"
|
5
|
-
require_relative "jekyll-wikilinks/version"
|
6
|
-
|
7
|
-
|
8
|
-
module JekyllWikiLinks
|
9
|
-
class Generator < Jekyll::Generator
|
10
|
-
attr_accessor :site, :config, :md_docs, :graph_nodes, :graph_links
|
11
|
-
|
12
|
-
# Use Jekyll's native relative_url filter
|
13
|
-
include Jekyll::Filters::URLFilters
|
14
|
-
|
15
|
-
CONFIG_KEY = "wikilinks"
|
16
|
-
CONVERTER_CLASS = Jekyll::Converters::Markdown
|
17
|
-
ENABLED_KEY = "enabled"
|
18
|
-
ENABLED_GRAPH_DATA_KEY = "enabled"
|
19
|
-
EXCLUDE_KEY = "exclude"
|
20
|
-
EXCLUDE_GRAPH_KEY = "exclude"
|
21
|
-
GRAPH_DATA_KEY = "d3_graph_data"
|
22
|
-
|
23
|
-
def initialize(config)
|
24
|
-
@config = config
|
25
|
-
end
|
26
|
-
|
27
|
-
def generate(site)
|
28
|
-
return if disabled?
|
29
|
-
Jekyll.logger.debug "Excluded jekyll types: ", option(EXCLUDE_KEY)
|
30
|
-
Jekyll.logger.debug "Excluded jekyll types in graph: ", option_graph(EXCLUDE_GRAPH_KEY)
|
31
|
-
|
32
|
-
@site = site
|
33
|
-
@context = context
|
34
|
-
|
35
|
-
documents = []
|
36
|
-
documents += site.pages if !exclude?(:pages)
|
37
|
-
included_docs = site.docs_to_write.filter { |d| !exclude?(d.type) }
|
38
|
-
documents += included_docs
|
39
|
-
@md_docs = documents.select {|doc| markdown_extension?(doc.extname) }
|
40
|
-
|
41
|
-
old_config_warn()
|
42
|
-
|
43
|
-
# build links
|
44
|
-
md_docs.each do |document|
|
45
|
-
parse_wiki_links(document)
|
46
|
-
end
|
47
|
-
|
48
|
-
# backlinks data handling
|
49
|
-
@graph_nodes, @graph_links = [], []
|
50
|
-
md_docs.each do |document|
|
51
|
-
document.data['backlinks'] = get_backlinks(document)
|
52
|
-
if !disabled_graph_data? && !exclude_graph?(document.type)
|
53
|
-
generate_graph_data(document)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
if !disabled_graph_data?
|
58
|
-
write_graph_data()
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def old_config_warn()
|
63
|
-
if config.include?("wikilinks_collection")
|
64
|
-
Jekyll.logger.warn "Deprecated: As of 0.0.3, 'wikilinks_collection' is no longer used for configs. jekyll-wikilinks will scan all markdown files by default. Check README for details: https://shorty25h0r7.github.io/jekyll-wikilinks/"
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def parse_wiki_links(note)
|
69
|
-
# Convert all Wiki/Roam-style double-bracket link syntax to plain HTML
|
70
|
-
# anchor tag elements (<a>) with "wiki-link" CSS class
|
71
|
-
md_docs.each do |note_potentially_linked_to|
|
72
|
-
title_from_filename = File.basename(
|
73
|
-
note_potentially_linked_to.basename,
|
74
|
-
File.extname(note_potentially_linked_to.basename)
|
75
|
-
)
|
76
|
-
|
77
|
-
note_url = relative_url(note_potentially_linked_to.url) if note_potentially_linked_to&.url
|
78
|
-
|
79
|
-
# Replace double-bracketed links using note title
|
80
|
-
# [[feline.cats]]
|
81
|
-
regex_wl, cap_gr = regex_wiki_link(title_from_filename)
|
82
|
-
render_txt = note_potentially_linked_to.data['title'].downcase
|
83
|
-
note.content = note.content.gsub(
|
84
|
-
regex_wl,
|
85
|
-
"<a class='wiki-link' href='#{note_url}'>#{render_txt}</a>"
|
86
|
-
)
|
87
|
-
|
88
|
-
# Replace double-bracketed links with alias (right)
|
89
|
-
# [[feline.cats|this is a link to the note about cats]]
|
90
|
-
regex_wl, cap_gr = regex_wiki_link_w_alias_right(title_from_filename)
|
91
|
-
note.content = note.content.gsub(
|
92
|
-
regex_wl,
|
93
|
-
"<a class='wiki-link' href='#{note_url}'>#{cap_gr}</a>"
|
94
|
-
)
|
95
|
-
|
96
|
-
# Replace double-bracketed links with alias (left)
|
97
|
-
# [[this is a link to the note about cats|feline.cats]]
|
98
|
-
regex_wl, cap_gr = regex_wiki_link_w_alias_left(title_from_filename)
|
99
|
-
note.content = note.content.gsub(
|
100
|
-
regex_wl,
|
101
|
-
"<a class='wiki-link' href='#{note_url}'>#{cap_gr}</a>"
|
102
|
-
)
|
103
|
-
end
|
104
|
-
|
105
|
-
# At this point, all remaining double-bracket-wrapped words are
|
106
|
-
# pointing to non-existing pages, so let's turn them into disabled
|
107
|
-
# links by greying them out and changing the cursor
|
108
|
-
# vanilla wiki-links
|
109
|
-
regex_wl, cap_gr = regex_wiki_link()
|
110
|
-
note.content = note.content.gsub(
|
111
|
-
regex_wl,
|
112
|
-
"<span title='There is no note that matches this link.' class='invalid-wiki-link'>[[#{cap_gr}]]</span>"
|
113
|
-
)
|
114
|
-
# aliases -- both kinds
|
115
|
-
regex_wl, cap_gr = regex_wiki_link_w_alias()
|
116
|
-
note.content = note.content.gsub(
|
117
|
-
regex_wl,
|
118
|
-
"<span title='There is no note that matches this link.' class='invalid-wiki-link'>[[#{cap_gr}]]</span>"
|
119
|
-
)
|
120
|
-
end
|
121
|
-
|
122
|
-
def get_backlinks(doc)
|
123
|
-
backlinks = []
|
124
|
-
md_docs.each do |backlinked_doc|
|
125
|
-
if backlinked_doc.content.include?(doc.url)
|
126
|
-
backlinks << backlinked_doc
|
127
|
-
end
|
128
|
-
end
|
129
|
-
return backlinks
|
130
|
-
end
|
131
3
|
|
132
|
-
|
133
|
-
regex, _ = regex_invalid_wiki_link()
|
134
|
-
return doc.content.scan(regex)[0]
|
135
|
-
end
|
136
|
-
|
137
|
-
def generate_graph_data(doc)
|
138
|
-
Jekyll.logger.debug "Processing graph nodes for doc: ", doc.data['title']
|
139
|
-
# missing nodes
|
140
|
-
missing_node_names = invalid_wiki_links(doc)
|
141
|
-
if !missing_node_names.nil?
|
142
|
-
missing_node_names.each do |missing_node_name|
|
143
|
-
if graph_nodes.none? { |node| node[:id] == missing_node_name }
|
144
|
-
Jekyll.logger.warn "Net-Web node missing: ", missing_node_name
|
145
|
-
Jekyll.logger.warn " in: ", doc.data['slug']
|
146
|
-
graph_nodes << {
|
147
|
-
id: missing_node_name,
|
148
|
-
url: '',
|
149
|
-
label: missing_node_name,
|
150
|
-
}
|
151
|
-
end
|
152
|
-
graph_links << {
|
153
|
-
source: relative_url(doc.url),
|
154
|
-
target: missing_node_name,
|
155
|
-
}
|
156
|
-
end
|
157
|
-
end
|
158
|
-
# existing nodes
|
159
|
-
graph_nodes << {
|
160
|
-
id: relative_url(doc.url),
|
161
|
-
url: relative_url(doc.url),
|
162
|
-
label: doc.data['title'],
|
163
|
-
}
|
164
|
-
get_backlinks(doc).each do |b|
|
165
|
-
if !exclude_graph?(b.type)
|
166
|
-
graph_links << {
|
167
|
-
source: relative_url(b.url),
|
168
|
-
target: relative_url(doc.url),
|
169
|
-
}
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
def write_graph_data()
|
175
|
-
# from: https://github.com/jekyll/jekyll/issues/7195#issuecomment-415696200
|
176
|
-
static_file = Jekyll::StaticFile.new(site, site.source, "/assets", "graph-net-web.json")
|
177
|
-
File.write(@site.source + static_file.relative_path, JSON.dump({
|
178
|
-
links: graph_links,
|
179
|
-
nodes: graph_nodes,
|
180
|
-
}))
|
181
|
-
end
|
182
|
-
|
183
|
-
def context
|
184
|
-
@context ||= JekyllWikiLinks::Context.new(site)
|
185
|
-
end
|
186
|
-
|
187
|
-
|
188
|
-
def exclude?(type)
|
189
|
-
return false unless option(EXCLUDE_KEY)
|
190
|
-
return option(EXCLUDE_KEY).include?(type.to_s)
|
191
|
-
end
|
192
|
-
|
193
|
-
def exclude_graph?(type)
|
194
|
-
return false unless option_graph(EXCLUDE_KEY)
|
195
|
-
return option_graph(EXCLUDE_KEY).include?(type.to_s)
|
196
|
-
end
|
197
|
-
|
198
|
-
def markdown_extension?(extension)
|
199
|
-
markdown_converter.matches(extension)
|
200
|
-
end
|
201
|
-
|
202
|
-
def markdown_converter
|
203
|
-
@markdown_converter ||= site.find_converter_instance(CONVERTER_CLASS)
|
204
|
-
end
|
205
|
-
|
206
|
-
def option(key)
|
207
|
-
config[CONFIG_KEY] && config[CONFIG_KEY][key]
|
208
|
-
end
|
209
|
-
|
210
|
-
def option_graph(key)
|
211
|
-
config[GRAPH_DATA_KEY] && config[GRAPH_DATA_KEY][key]
|
212
|
-
end
|
213
|
-
|
214
|
-
def disabled?
|
215
|
-
option(ENABLED_KEY) == false
|
216
|
-
end
|
217
|
-
|
218
|
-
def disabled_graph_data?
|
219
|
-
option_graph(ENABLED_GRAPH_DATA_KEY) == false
|
220
|
-
end
|
221
|
-
|
222
|
-
# regex
|
223
|
-
# returns two items: regex and a target capture group (text to be rendered)
|
224
|
-
# using functions instead of constants because of the need to access 'wiki_link_text'
|
225
|
-
# -- esp. when aliasing.
|
226
|
-
|
227
|
-
def regex_invalid_wiki_link()
|
228
|
-
# identify missing links in note via .invalid-wiki-link class and nested note-name.
|
229
|
-
regex = /invalid-wiki-link[^\]]+\[\[([^\]]+)\]\]/i
|
230
|
-
cap_gr = "\\1" # this is mostly just to remain consistent with other regex functions
|
231
|
-
return regex, cap_gr
|
232
|
-
end
|
233
|
-
|
234
|
-
def regex_wiki_link(wiki_link_text='')
|
235
|
-
if wiki_link_text.empty?
|
236
|
-
regex = /(\[\[)([^\|\]]+)(\]\])/i
|
237
|
-
cap_gr = "\\2"
|
238
|
-
return regex, cap_gr
|
239
|
-
else
|
240
|
-
regex = /\[\[#{wiki_link_text}\]\]/i
|
241
|
-
cap_gr = wiki_link_text
|
242
|
-
return regex, cap_gr
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
def regex_wiki_link_w_alias()
|
247
|
-
regex = /(\[\[)([^\]\|]+)(\|)([^\]]+)(\]\])/i
|
248
|
-
cap_gr = "\\2|\\4"
|
249
|
-
return regex, cap_gr
|
250
|
-
end
|
251
|
-
|
252
|
-
def regex_wiki_link_w_alias_left(wiki_link_text)
|
253
|
-
raise ArgumentError.new(
|
254
|
-
"Expected a value for 'wiki_link_text'"
|
255
|
-
) if wiki_link_text.nil?
|
256
|
-
regex = /(\[\[)([^\]\|]+)(\|)(#{wiki_link_text})(\]\])/i
|
257
|
-
cap_gr = "\\2"
|
258
|
-
return regex, cap_gr
|
259
|
-
end
|
260
|
-
|
261
|
-
def regex_wiki_link_w_alias_right(wiki_link_text)
|
262
|
-
raise ArgumentError.new(
|
263
|
-
"Expected a value for 'wiki_link_text'"
|
264
|
-
) if wiki_link_text.nil?
|
265
|
-
regex = /(\[\[)(#{wiki_link_text})(\|)([^\]]+)(\]\])/i
|
266
|
-
cap_gr = "\\4"
|
267
|
-
return regex, cap_gr
|
268
|
-
end
|
4
|
+
require_relative "jekyll-wikilinks/version"
|
269
5
|
|
270
|
-
|
271
|
-
|
6
|
+
# in order of expected execution
|
7
|
+
|
8
|
+
# setup config
|
9
|
+
require_relative "jekyll-wikilinks/config"
|
10
|
+
Jekyll::Hooks.register :site, :after_init do |site|
|
11
|
+
# global '$wiki_conf' to ensure that all local jekyll plugins
|
12
|
+
# are reading from the same configuration
|
13
|
+
# (global var is not ideal, but is DRY)
|
14
|
+
$wiki_conf = Jekyll::WikiLinks::PluginConfig.new(site.config)
|
15
|
+
end
|
16
|
+
|
17
|
+
# setup docs (based on configs)
|
18
|
+
require_relative "jekyll-wikilinks/patch/doc_manager"
|
19
|
+
Jekyll::Hooks.register :site, :post_read do |site|
|
20
|
+
if !$wiki_conf.disabled?
|
21
|
+
site.doc_mngr = Jekyll::WikiLinks::DocManager.new(site)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# convert
|
26
|
+
require_relative "jekyll-wikilinks/plugins/converter"
|
27
|
+
|
28
|
+
# generate
|
29
|
+
require_relative "jekyll-wikilinks/plugins/generator"
|
30
|
+
|
31
|
+
# convert fores
|
32
|
+
# Jekyll::Hooks.register :documents, :pre_convert do |doc|
|
33
|
+
# Jekyll:WikiLinks::Parser.parse_blocks(doc)
|
34
|
+
# @site.link_index.populate_fores(doc, typed_link_blocks, md_docs)
|
35
|
+
# end
|
36
|
+
|
37
|
+
# convert backs
|
38
|
+
# Jekyll::Hooks.register :documents, :pre_convert do |doc|
|
39
|
+
# Jekyll:WikiLinks::Parser.parse_inlines(doc)
|
40
|
+
# @site.link_index.populate_backs(doc, typed_link_blocks, md_docs)
|
41
|
+
# end
|
42
|
+
|
43
|
+
# generate metadata
|
44
|
+
# Jekyll::Hooks.register :documents, :post_convert do |doc|
|
45
|
+
# Jekyll:WikiLinks::Generator.generate(doc)
|
46
|
+
# end
|
47
|
+
|
48
|
+
# hook up liquid filters
|
49
|
+
require_relative "jekyll-wikilinks/plugins/filter"
|
50
|
+
Liquid::Template.register_filter(Jekyll::WikiLinks::TypeFilters)
|
metadata
CHANGED
@@ -1,32 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-wikilinks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- manunamz
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
12
|
-
dependencies:
|
11
|
+
date: 2021-11-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: jekyll
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.2.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.2.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: nokogiri
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.12.3
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.12.3
|
13
41
|
description:
|
14
42
|
email:
|
15
|
-
-
|
43
|
+
- manunamz@pm.me
|
16
44
|
executables: []
|
17
45
|
extensions: []
|
18
46
|
extra_rdoc_files: []
|
19
47
|
files:
|
20
48
|
- lib/jekyll-wikilinks.rb
|
21
|
-
- lib/jekyll-wikilinks/
|
22
|
-
- lib/jekyll-wikilinks/
|
49
|
+
- lib/jekyll-wikilinks/config.rb
|
50
|
+
- lib/jekyll-wikilinks/patch/context.rb
|
51
|
+
- lib/jekyll-wikilinks/patch/doc_manager.rb
|
52
|
+
- lib/jekyll-wikilinks/patch/site.rb
|
53
|
+
- lib/jekyll-wikilinks/plugins/converter.rb
|
54
|
+
- lib/jekyll-wikilinks/plugins/filter.rb
|
55
|
+
- lib/jekyll-wikilinks/plugins/generator.rb
|
56
|
+
- lib/jekyll-wikilinks/util/link_index.rb
|
57
|
+
- lib/jekyll-wikilinks/util/parser.rb
|
58
|
+
- lib/jekyll-wikilinks/util/regex.rb
|
23
59
|
- lib/jekyll-wikilinks/version.rb
|
24
|
-
homepage: https://github.com/
|
60
|
+
homepage: https://github.com/manunamz/jekyll-wikilinks
|
25
61
|
licenses:
|
26
|
-
-
|
62
|
+
- GPL3
|
27
63
|
metadata:
|
28
|
-
homepage_uri: https://github.com/
|
29
|
-
source_code_uri: https://github.com/
|
64
|
+
homepage_uri: https://github.com/manunamz/jekyll-wikilinks
|
65
|
+
source_code_uri: https://github.com/manunamz/jekyll-wikilinks
|
66
|
+
changelog_uri: https://github.com/manunamz/jekyll-wikilinks/blob/main/CHANGELOG.md
|
30
67
|
post_install_message:
|
31
68
|
rdoc_options: []
|
32
69
|
require_paths:
|
@@ -42,8 +79,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
42
79
|
- !ruby/object:Gem::Version
|
43
80
|
version: '0'
|
44
81
|
requirements: []
|
45
|
-
rubygems_version: 3.2.
|
82
|
+
rubygems_version: 3.2.27
|
46
83
|
signing_key:
|
47
84
|
specification_version: 4
|
48
|
-
summary: Add support for [[wikilinks]] (in markdown).
|
85
|
+
summary: Add jekyll support for [[wikilinks]] (in markdown files).
|
49
86
|
test_files: []
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module JekyllWikiLinks
|
4
|
-
module BackLinkTypeFilters
|
5
|
-
# usage:
|
6
|
-
# {% assign note_backlinks = page.backlinks | backlink_type = "notes" %}
|
7
|
-
def backlink_type(backlinks, type)
|
8
|
-
return if backlinks.nil?
|
9
|
-
target_backlinks = []
|
10
|
-
backlinks.each do |bl|
|
11
|
-
target_backlinks << bl if self.to_string(bl.type) == type
|
12
|
-
end
|
13
|
-
return target_backlinks
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_string(type)
|
17
|
-
return type if type.is_a?(String)
|
18
|
-
type = type.to_s
|
19
|
-
begin
|
20
|
-
String(type)
|
21
|
-
rescue ::ArgumentError
|
22
|
-
raise ArgumentError, "invalid type"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
Liquid::Template.register_filter(JekyllWikiLinks::BackLinkTypeFilters)
|