jekyll-wikirefs 0.0.1 → 0.0.14

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: bd19157531219d5251d79f6d9f31be1acd344d4c45c9177deec21612a5e03a0f
4
- data.tar.gz: 68fa28e81d81c3e4edb2f403ec8cb3b7a41c1fba41fcd6466956ec6a6de44190
3
+ metadata.gz: 6ffaf29b4a348e3036a6508d41df6cc915ae3459a2afb250a4c778242f4dff69
4
+ data.tar.gz: 939fa037711ee9f265ee73edc709f34264188f71dca4f7d7e8f972f97be9eb3b
5
5
  SHA512:
6
- metadata.gz: ec59939d22628f566605761c3413ee25311b2d5063bb4ab8a2ab95c960918f60ac07a8b196a45b86e5685d65d36320feca6cc0fb80431cf0ebf7544bce98da4e
7
- data.tar.gz: 61caaa334cd42d3b0f0718aca5aa02c3c7e6a26516c0dd65fa04f346cf960091cd7619d6533d06c3f7ed0a783bf5c4cee7b2bb3b95a08a93d22b7fa4cd0fda5e
6
+ metadata.gz: 97d3144acc57f975dfb1fb6799bc90df9c93de66b9b1bca5f2c6cfc34a5fe4b24316830d87410a90e5ba867516f68326dc9e4de688098e879e5cfd50f2ab0e33
7
+ data.tar.gz: 01c27427d75cb71a22965f91f890deca40fbfa8955560aea6fa01518d02343da53a26c927389624f12d771d574127383af61a7f65255a7111d1d1ef7b3d5b90f
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+ require "jekyll"
3
+
4
+ module Jekyll
5
+ module WikiRefs
6
+
7
+ class PluginConfig
8
+
9
+ ATTR_KEY = "attributes"
10
+ CONFIG_KEY = "wikirefs"
11
+ ENABLED_KEY = "enabled"
12
+ EXCLUDE_KEY = "exclude"
13
+ # css-related
14
+ CSS_KEY = "css"
15
+ NAME_KEY = "name"
16
+ # names
17
+ ## valid
18
+ TYPED_KEY = "typed"
19
+ WEB_KEY = "web"
20
+ WIKI_KEY = "wiki"
21
+ ## invalid
22
+ INV_WIKI_KEY = "invalid_wiki"
23
+ # INV_WEB_KEY = "invalid_web"
24
+ ## embed
25
+ EMBED_WRAPPER_KEY = "embed_wrapper"
26
+ EMBED_TITLE_KEY = "embed_title"
27
+ EMBED_CONTENT_KEY = "embed_content"
28
+ EMBED_LINK_KEY = "embed_wiki_link"
29
+ EMBED_IMG_WRAPPER_KEY = "embed_image_wrapper"
30
+ EMBED_IMG_KEY = "embed_image"
31
+
32
+ def initialize(config)
33
+ @config ||= config
34
+ self.old_config_warn()
35
+ Jekyll.logger.debug("Jekyll-WikiRefs: Excluded jekyll types: #{option(EXCLUDE_KEY)}") unless disabled?
36
+ end
37
+
38
+ # util
39
+
40
+ def css_name(name_key)
41
+ return option_css_name(name_key) if option_css_name(name_key)
42
+ return "typed" if name_key == TYPED_KEY
43
+ # valid
44
+ return "wiki-link" if name_key == WIKI_KEY
45
+ # invalid
46
+ return "invalid-wiki-link" if name_key == INV_WIKI_KEY
47
+ # return "invalid-web-link" if name_key == INV_WEB_KEY
48
+ # embeds
49
+ return "embed-wrapper" if name_key == EMBED_WRAPPER_KEY
50
+ return "embed-title" if name_key == EMBED_TITLE_KEY
51
+ return "embed-content" if name_key == EMBED_CONTENT_KEY
52
+ return "embed-wiki-link" if name_key == EMBED_LINK_KEY
53
+ # img
54
+ return "embed-image-wrapper" if name_key == EMBED_IMG_WRAPPER_KEY
55
+ return "embed-image" if name_key == EMBED_IMG_KEY
56
+ end
57
+
58
+ def disabled?
59
+ option(ENABLED_KEY) == false
60
+ end
61
+
62
+ def disabled_attributes?
63
+ option_attributes(ENABLED_KEY) == false
64
+ end
65
+
66
+ def exclude?(type)
67
+ return false unless option(EXCLUDE_KEY)
68
+ return option(EXCLUDE_KEY).include?(type.to_s)
69
+ end
70
+
71
+ def excluded_css_names
72
+ return self.option_css(EXCLUDE_KEY)
73
+ end
74
+
75
+ # options
76
+
77
+ def option(key)
78
+ @config[CONFIG_KEY] && @config[CONFIG_KEY][key]
79
+ end
80
+
81
+ def option_attributes(key)
82
+ @config[CONFIG_KEY] && @config[CONFIG_KEY][ATTR_KEY] && @config[CONFIG_KEY][ATTR_KEY][key]
83
+ end
84
+
85
+ def option_css(key)
86
+ @config[CONFIG_KEY] && @config[CONFIG_KEY][CSS_KEY] && @config[CONFIG_KEY][CSS_KEY][key]
87
+ end
88
+
89
+ def option_css_name(key)
90
+ option_css(NAME_KEY) && @config[CONFIG_KEY][CSS_KEY][NAME_KEY][key]
91
+ end
92
+
93
+ # !! deprecated !!
94
+
95
+ def option_exist?(key)
96
+ @config[CONFIG_KEY] && @config[CONFIG_KEY].include?(key)
97
+ end
98
+
99
+ def old_config_warn()
100
+ if @config.include?("wikilinks_collection")
101
+ Jekyll.logger.warn("Jekyll-WikiRefs: As of 0.0.3, 'wikilinks_collection' is no longer used for configs. Jekyll-WikiRefs will scan all markdown files by default. Check README for details.")
102
+ end
103
+ if option_exist?("assets_rel_path")
104
+ Jekyll.logger.warn("Jekyll-WikiRefs: As of 0.0.5, 'assets_rel_path' is now 'path'.")
105
+ end
106
+ if @config.include?("d3_graph_data")
107
+ Jekyll.logger.warn("Jekyll-WikiRefs: As of 0.0.6, 'd3_graph_data' and graph functionality have been moved to the 'jekyll-graph' plugin.")
108
+ end
109
+ end
110
+ end
111
+
112
+ end
113
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module WikiRefs
5
+
6
+ class Context
7
+ attr_reader :site
8
+
9
+ def initialize(site)
10
+ @site = site
11
+ end
12
+
13
+ def registers
14
+ { :site => site }
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+ require_relative "../util/regex"
3
+
4
+ module Jekyll
5
+ module WikiRefs
6
+
7
+ # todo: move these methods to the 'WikiRef' classes...?
8
+ #
9
+ # this class is responsible for answering any questions
10
+ # related to jekyll markdown documents
11
+ # that are meant to be processed by the wikirefs plugin.
12
+ #
13
+ # the following methods are specifically to address two things:
14
+ # 1. ruby's 'find' / 'detect' function does not throw errors if
15
+ # there are multiple matches. fail fast, i want to know if there
16
+ # are duplicates.
17
+ # (not using sets because i don't want to clobber existing documents)
18
+ # 2. handle all jekyll documents in one place. i don't want to
19
+ # have to filter all documents for target markdown documents
20
+ # every time i need to check if a file exists.
21
+ #
22
+ # there is probably a better way to do this...i would prefer to have
23
+ # a plugin-wide function that just wraps all of this and can be called
24
+ # from anywhere in the plugin...but ruby is not a functional language...
25
+ # gotta have classes...
26
+ #
27
+ class DocManager
28
+ CONVERTER_CLASS = Jekyll::Converters::Markdown
29
+
30
+ def initialize(site)
31
+ return if $wiki_conf.disabled?
32
+
33
+ markdown_converter = site.find_converter_instance(CONVERTER_CLASS)
34
+ # filter docs based on configs
35
+ docs = []
36
+ docs += site.pages if !$wiki_conf.exclude?(:pages)
37
+ docs += site.docs_to_write.filter { |d| !$wiki_conf.exclude?(d.type) }
38
+ @md_docs = docs.filter { |doc| markdown_converter.matches(doc.extname) }
39
+ if @md_docs.nil? || @md_docs.empty?
40
+ Jekyll.logger.warn("Jekyll-WikiRefs: No documents to process.")
41
+ end
42
+
43
+ @static_files ||= site.static_files
44
+ end
45
+
46
+ # accessors
47
+
48
+ def all
49
+ return @md_docs
50
+ end
51
+
52
+ def get_doc_by_fname(filename)
53
+ Jekyll.logger.error("Jekyll-WikiRefs: Must provide a 'filename'") if filename.nil? || filename.empty?
54
+ docs = @md_docs.select{ |d| File.basename(d.basename, File.extname(d.basename)) == filename }
55
+ return nil if docs.nil? || docs.empty? || docs.size > 1
56
+ return docs[0]
57
+ end
58
+
59
+ def get_doc_by_fpath(file_path)
60
+ Jekyll.logger.error("Jekyll-WikiRefs: Must provide a 'file_path'") if file_path.nil? || file_path.empty?
61
+ docs = @md_docs.select{ |d| d.relative_path == (file_path + ".md") }
62
+ return nil if docs.nil? || docs.empty? || docs.size > 1
63
+ return docs[0]
64
+ end
65
+
66
+ def get_doc_by_url(url)
67
+ Jekyll.logger.error("Jekyll-WikiRefs: Must provide a 'url'") if url.nil? || url.empty?
68
+ docs = @md_docs.select{ |d| d.url == url }
69
+ return nil if docs.nil? || docs.empty? || docs.size > 1
70
+ return docs[0]
71
+ end
72
+
73
+ def get_doc_content(filename)
74
+ doc = self.get_doc_by_fname(filename)
75
+ return nil if docs.nil?
76
+ return doc.content
77
+ end
78
+
79
+ def get_image_by_fname(filename)
80
+ Jekyll.logger.error("Jekyll-WikiRefs: Must provide a 'filename'") if filename.nil? || filename.empty?
81
+ return nil if @static_files.size == 0 || !SUPPORTED_IMG_FORMATS.any?{ |ext| ext == File.extname(filename).downcase }
82
+ docs = @static_files.select{ |d| File.basename(d.relative_path) == filename }
83
+ return nil if docs.nil? || docs.empty? || docs.size > 1
84
+ return docs[0]
85
+ end
86
+
87
+ # validators
88
+
89
+ def file_exists?(filename, file_path=nil)
90
+ Jekyll.logger.error("Jekyll-WikiRefs: Must provide a 'filename'") if filename.nil? || filename.empty?
91
+ if file_path.nil?
92
+ return false if get_doc_by_fname(filename).nil? && get_image_by_fname(filename).nil?
93
+ return true
94
+ else
95
+ return false if get_doc_by_fpath(file_path).nil?
96
+ return true
97
+ end
98
+ end
99
+
100
+ def doc_has_header?(doc, header)
101
+ Jekyll.logger.error("Jekyll-WikiRefs: Must provide a 'header'") if header.nil? || header.empty?
102
+ # leading + trailing whitespace is ignored when matching headers
103
+ header_results = doc.content.scan(REGEX_ATX_HEADER).flatten.map { |htxt| htxt.downcase.strip }
104
+ setext_header_results = doc.content.scan(REGEX_SETEXT_HEADER).flatten.map { |htxt| htxt.downcase.strip }
105
+ return header_results.include?(header.downcase.strip) || setext_header_results.include?(header.downcase.strip)
106
+ end
107
+
108
+ def doc_has_block_id?(doc, block_id)
109
+ Jekyll.logger.error("Jekyll-WikiRefs: Must provide a 'block_id'") if block_id.nil? || block_id.empty?
110
+ # leading + trailing whitespace is ignored when matching blocks
111
+ block_id_results = doc.content.scan(REGEX_BLOCK).flatten.map { |bid| bid.strip }
112
+ return block_id_results.include?(block_id)
113
+ end
114
+ end
115
+
116
+ end
117
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ require "jekyll"
3
+
4
+ # appending to built-in jekyll site object to pass data to jekyll-graph
5
+
6
+ module Jekyll
7
+
8
+ class Site
9
+ attr_accessor :doc_mngr, :link_index, :wiki_parser
10
+ end
11
+
12
+ end
@@ -0,0 +1,53 @@
1
+ require "jekyll"
2
+ require "nokogiri"
3
+
4
+ module Jekyll
5
+ module WikiRefs
6
+
7
+ class WebLinkConverter < Jekyll::Converter
8
+ priority :low
9
+
10
+ # config
11
+ CSS_KEY = "css"
12
+ CONFIG_KEY = "wikirefs"
13
+ EXCLUDE_KEY = "exclude"
14
+ # link types
15
+ # WEB_KEY = "web"
16
+ # WIKIL_KEY = "wiki"
17
+ # INVALID_KEY = "invalid"
18
+ # WIKI_EMBED_KEY = "wiki_embed"
19
+
20
+ def matches(ext)
21
+ ext =~ /^\.md$/i
22
+ end
23
+
24
+ def output_ext(ext)
25
+ ".html"
26
+ end
27
+
28
+ # add 'web-link' css class to links that aren't
29
+ # - wikilinks
30
+ # - contain an excluded css class
31
+ def convert(content)
32
+ excluded_classes = option_css(EXCLUDE_KEY)
33
+ if excluded_classes.nil? || excluded_classes.empty?
34
+ css_def = "a:not(.#{$wiki_conf.css_name("wiki")}):not(.#{$wiki_conf.css_name("embed_wiki_link")})"
35
+ else
36
+ css_def = "a:not(.#{$wiki_conf.css_name("wiki")}):not(.#{$wiki_conf.css_name("embed_wiki_link")}):not(.#{excluded_classes.join("):not(.")})"
37
+ end
38
+ parsed_content = Nokogiri::HTML::fragment(content)
39
+ parsed_content.css(css_def).each do |link|
40
+ link.add_class('web-link')
41
+ end
42
+ content = parsed_content.to_html
43
+ end
44
+
45
+ # config helpers
46
+
47
+ def option_css(key)
48
+ @config[CONFIG_KEY] && @config[CONFIG_KEY][CSS_KEY] && @config[CONFIG_KEY][CSS_KEY][key]
49
+ end
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module WikiRefs
5
+
6
+ module TypeFilters
7
+ # 'links' accepts untyped links, typed links, and attributes; fore and back.
8
+ # why: these filters are useful when you want to list backlinks of certain type(s) and don't want type mismatches to display as "missing"
9
+
10
+ # usage: {% assign note_links = page.links | doc_type: "notes" %}
11
+ def doc_type(links, doc_type)
12
+ Jekyll.logger.error("Jekyll-WikiRefs: 'links' invalid") if links.nil?
13
+ Jekyll.logger.error("Jekyll-WikiRefs: 'doc_type' invalid") if doc_type.nil? || doc_type.empty?
14
+ return [] if links.empty?
15
+
16
+ site = @context.registers[:site]
17
+
18
+ links_of_type = []
19
+ links.each do |l|
20
+ # links
21
+ if l.keys.include?('url')
22
+ docs = site.documents.select{ |d| d.url == l['url'] && d.type.to_s == doc_type.to_s }
23
+ if !docs.nil? && docs.size == 1
24
+ links_of_type << l
25
+ end
26
+ # attributes
27
+ elsif l.keys.include?('urls')
28
+ l['urls'].each do |lurl|
29
+ docs = site.documents.select{ |d| d.url == lurl && d.type.to_s == doc_type.to_s }
30
+ if !docs.nil? && docs.size == 1
31
+ links_of_type << l
32
+ end
33
+ end
34
+ else
35
+ Jekyll.logger.error("Jekyll-WikiRefs: In 'doc_type' filter, 'links' do not have 'url' or 'urls'")
36
+ end
37
+ end
38
+ return links_of_type.uniq
39
+ end
40
+
41
+ # usage: {% assign author_links = page.links | link_type: "author" %}
42
+ def link_type(links, link_type)
43
+ Jekyll.logger.error("Jekyll-WikiRefs: 'links' invalid") if links.nil?
44
+ Jekyll.logger.error("Jekyll-WikiRefs: 'link_type' invalid") if link_type.nil?
45
+ return [] if links.empty?
46
+
47
+ site = @context.registers[:site]
48
+
49
+ links_of_type = []
50
+ links.each do |l|
51
+ if l['type'].to_s == link_type.to_s
52
+ # links
53
+ if l.keys.include?('url')
54
+ docs = site.documents.select{ |d| d.url == l['url'] }
55
+ if !doc.nil? && docs.size != 1
56
+ links_of_type << l
57
+ end
58
+ # attributes
59
+ elsif l.keys.include?('urls')
60
+ all_docs_exist = true
61
+ l['urls'].each do |lurl|
62
+ docs = site.documents.select{ |d| d.url == lurl }
63
+ if !docs.nil? && docs.size != 1
64
+ all_docs_exist = false
65
+ end
66
+ end
67
+ if all_docs_exist
68
+ links_of_type << l
69
+ end
70
+ else
71
+ Jekyll.logge.error("Jekyll-WikiRefs: In 'link_type' filter, 'links' do not have 'url' or 'urls'")
72
+ end
73
+ end
74
+ end
75
+ return links_of_type.uniq
76
+ end
77
+
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+ require "jekyll"
3
+
4
+ require_relative "../patch/context"
5
+ require_relative "../patch/doc_manager"
6
+ require_relative "../patch/site"
7
+ require_relative "../util/link_index"
8
+ require_relative "../util/parser"
9
+
10
+ module Jekyll
11
+ module WikiRefs
12
+
13
+ class Generator < Jekyll::Generator
14
+
15
+ def generate(site)
16
+ return if $wiki_conf.disabled?
17
+
18
+ @site ||= site
19
+ @context ||= Jekyll::WikiRefs::Context.new(site)
20
+
21
+ # setup helper classes
22
+ @parser = Parser.new(@site)
23
+ @site.link_index = LinkIndex.new(@site)
24
+
25
+ @site.doc_mngr.all.each do |doc|
26
+ filename = File.basename(doc.basename, File.extname(doc.basename))
27
+ @parser.parse(filename, doc.content)
28
+ @site.link_index.populate(doc, @parser.wikilink_blocks, @parser.wikilink_inlines)
29
+ end
30
+ # wait until all docs are processed before assigning backward facing metadata,
31
+ # this ensures all attributed/backlinks are collected for assignment
32
+ @site.doc_mngr.all.each do |doc|
33
+ # populate frontmatter metadata from (wiki)link index
34
+ @site.link_index.assign_metadata(doc)
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,99 @@
1
+ require_relative 'regex'
2
+
3
+ module Jekyll
4
+ module WikiRefs
5
+
6
+ class LinkIndex
7
+ attr_reader :index
8
+
9
+ def initialize(site)
10
+ @baseurl = site.baseurl
11
+ @index = {}
12
+ site.doc_mngr.all.each do |doc|
13
+ @index[doc.url] = DocLinks.new()
14
+ end
15
+ end
16
+
17
+ def assign_metadata(doc)
18
+ doc.data['attributed'] = @index[doc.url].attributed.uniq
19
+ doc.data['attributes'] = @index[doc.url].attributes.uniq
20
+ doc.data['backlinks'] = @index[doc.url].backlinks.uniq
21
+ doc.data['forelinks'] = @index[doc.url].forelinks.uniq
22
+ doc.data['missing'] = @index[doc.url].missing.uniq
23
+ end
24
+
25
+ def populate(doc, wikilink_blocks, wikilink_inlines)
26
+ # #
27
+ # blocks #
28
+ # #
29
+ wikilink_blocks.each do |wlbl|
30
+ if wlbl.is_valid?
31
+ #
32
+ # attributes
33
+ #
34
+ target_attr = @index[doc.url].attributes.detect { |atr| atr['type'] == wlbl.link_type }
35
+ # create
36
+ if target_attr.nil?
37
+ @index[doc.url].attributes << wlbl.linked_fm_data
38
+ # append
39
+ else
40
+ target_attr['urls'] += wlbl.urls
41
+ end
42
+ ## append missing docs
43
+ @index[doc.url].missing += wlbl.missing_doc_filenames
44
+ #
45
+ # attributed
46
+ #
47
+ wlbl.linked_docs.each do |linked_doc|
48
+ target_attr = @index[linked_doc.url].attributed.detect { |atr| atr['type'] == wlbl.link_type }
49
+ # create
50
+ if target_attr.nil?
51
+ @index[linked_doc.url].attributed << wlbl.context_fm_data
52
+ # append
53
+ else
54
+ target_attr['urls'] << doc.url
55
+ end
56
+ end
57
+ else
58
+ #
59
+ # invalid || empty
60
+ #
61
+ @index[doc.url].missing += wlbl.missing_doc_filenames
62
+ end
63
+ end
64
+ # #
65
+ # inlines #
66
+ # #
67
+ wikilink_inlines.each do |wlil|
68
+ return if wlil.is_img?
69
+ if wlil.is_valid?
70
+ # forelink
71
+ @index[doc.url].forelinks << wlil.linked_fm_data
72
+ # backlink
73
+ @index[wlil.linked_doc.url].backlinks << wlil.context_fm_data
74
+ else
75
+ @index[doc.url].missing << wlil.filename
76
+ end
77
+ end
78
+ end
79
+
80
+ # def remove_baseurl(url)
81
+ # return url.gsub(@baseurl, '') if !@baseurl.nil?
82
+ # return url
83
+ # end
84
+
85
+ class DocLinks
86
+ attr_accessor :attributes, :attributed, :backlinks, :forelinks, :missing
87
+
88
+ def initialize
89
+ @attributed = [] # block typed backlinks; { 'type' => str, 'urls' => [ str ] }
90
+ @attributes = [] # block typed forelinks; { 'type' => str, 'urls' => [ str ] }
91
+ @backlinks = [] # inline typed and basic backlinks; { 'type' => str, 'url' => str }
92
+ @forelinks = [] # inline typed and basic forelinks; { 'type' => str, 'url' => str }
93
+ @missing = [] # missing forelinks + attributes; ( built from (missing) filenames )
94
+ end
95
+ end
96
+ end
97
+
98
+ end
99
+ end
@@ -0,0 +1,182 @@
1
+ require "nokogiri"
2
+ require_relative "regex"
3
+ require_relative "wikiref"
4
+
5
+ module Jekyll
6
+ module WikiRefs
7
+
8
+ # more of a "parser" than a parser
9
+ class Parser
10
+ attr_accessor :doc_manager, :markdown_converter, :wikilink_inlines, :wikilink_blocks
11
+
12
+ # Use Jekyll's native relative_url filter
13
+ include Jekyll::Filters::URLFilters
14
+
15
+ CONVERTER_CLASS = Jekyll::Converters::Markdown
16
+
17
+ def initialize(site)
18
+ @context ||= Jekyll::WikiRefs::Context.new(site)
19
+ # do not use @dm in parser -- it is only meant to be passed down into wikilink classes.
20
+ @doc_manager ||= site.doc_mngr
21
+ @markdown_converter ||= site.find_converter_instance(CONVERTER_CLASS)
22
+ @wikilink_blocks, @wikilink_inlines = [], []
23
+ end
24
+
25
+ # parsing
26
+
27
+ def parse(doc_filename, doc_content)
28
+ @wikilink_blocks, @wikilink_inlines = [], []
29
+ if !$wiki_conf.disabled_attributes?
30
+ self.parse_blocks(doc_filename, doc_content)
31
+ end
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 |w_match|
39
+ # init block wikilink
40
+ wikilink_block = WikiLinkBlock.new(
41
+ @doc_manager,
42
+ doc_filename,
43
+ w_match[0], # link_type
44
+ w_match[2], # bullet_type
45
+ )
46
+ # extract + add filenames
47
+ items = w_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)
52
+ end
53
+ end
54
+ # replace text
55
+ doc_content.gsub!(wikilink_block.md_regex, "\n")
56
+ @wikilink_blocks << wikilink_block
57
+ end
58
+ end
59
+ end
60
+
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 |w_match|
65
+ @wikilink_inlines << WikiLinkInline.new(
66
+ @doc_manager,
67
+ doc_filename,
68
+ w_match[0],
69
+ w_match[1],
70
+ w_match[2],
71
+ w_match[3],
72
+ w_match[4],
73
+ w_match[5],
74
+ )
75
+ end
76
+ end
77
+ # replace text
78
+ return if @wikilink_inlines.nil?
79
+ # process typed wikilinks first so we don't accidentally
80
+ # overwrite them when handling untyped wikilinks
81
+ self.sort_for_replacement
82
+ @wikilink_inlines.each do |wikilink|
83
+ doc_content.gsub!(
84
+ wikilink.md_regex,
85
+ self.build_html(wikilink)
86
+ )
87
+ end
88
+ end
89
+
90
+ # building/converting
91
+
92
+ def build_html_embed(title, content, url)
93
+ # multi-line for readability
94
+ return [
95
+ "<div class=\"#{$wiki_conf.css_name("embed_wrapper")}\">",
96
+ "<div class=\"#{$wiki_conf.css_name("embed_title")}\">",
97
+ "#{title}",
98
+ "</div>",
99
+ "<div class=\"#{$wiki_conf.css_name("embed_content")}\">",
100
+ "#{@markdown_converter.convert(content)}",
101
+ "</div>",
102
+ "<a class=\"#{$wiki_conf.css_name("embed_wiki_link")}\" href=\"#{url}\"></a>",
103
+ "</div>",
104
+ ].join("\n").gsub!("\n", "")
105
+ end
106
+
107
+ def build_html_img_embed(static_doc, is_svg=false)
108
+ svg_content = ""
109
+ if is_svg
110
+ File.open(static_doc.path, "r") do |svg_img|
111
+ svg_content = svg_img.read
112
+ end
113
+ return "<p><span class=\"#{$wiki_conf.css_name("embed_image_wrapper")}\">#{svg_content}</span></p>"
114
+ else
115
+ 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>"
116
+ end
117
+ end
118
+
119
+ def build_html(wikilink)
120
+ if !wikilink.is_valid?
121
+ return '<span class="' + $wiki_conf.css_name("invalid_wiki") + '">' + wikilink.md_str + '</span>'
122
+ end
123
+ # image processing
124
+ if wikilink.embedded? && wikilink.is_img?
125
+ return build_html_img_embed(wikilink.linked_img, is_svg=wikilink.is_img_svg?)
126
+ end
127
+ # markdown file processing
128
+ linked_doc = wikilink.linked_doc
129
+ link_type_txt = wikilink.is_typed? ? " #{$wiki_conf.css_name("typed")} #{wikilink.link_type}" : ""
130
+ lnk_doc_rel_url = relative_url(linked_doc.url)
131
+ if wikilink.labelled?
132
+ inner_txt = wikilink.label_txt
133
+ elsif linked_doc.data.keys.include?('title')
134
+ inner_txt = linked_doc.data['title'].downcase
135
+ # in case there is no 'title' frontmatter attribute
136
+ # (i'm seeing deprecation warnings, but there might
137
+ # be bugs caused by not using this...)
138
+ elsif linked_doc.respond_to?(:title)
139
+ inner_txt = linked_doc.title.downcase
140
+ # pages don't have automatically generated titles
141
+ else
142
+ inner_txt = Jekyll::Utils.slugify(linked_doc.basename)
143
+ end
144
+ # level-specific
145
+ if (wikilink.level == "file_path" || wikilink.level == "filename")
146
+ return build_html_embed(
147
+ linked_doc.title,
148
+ linked_doc.content,
149
+ lnk_doc_rel_url
150
+ ) if wikilink.embedded?
151
+ elsif (wikilink.level == "header")
152
+ # from: https://github.com/jekyll/jekyll/blob/6855200ebda6c0e33f487da69e4e02ec3d8286b7/Rakefile#L74
153
+ lnk_doc_rel_url += "\#" + Jekyll::Utils.slugify(wikilink.header_txt)
154
+ inner_txt += " > #{wikilink.header_txt.downcase}" if !wikilink.labelled?
155
+ elsif (wikilink.level == "block")
156
+ lnk_doc_rel_url += "\#" + wikilink.block_id
157
+ inner_txt += " > ^#{wikilink.block_id}" if !wikilink.labelled?
158
+ else
159
+ Jekyll.logger.error("Jekyll-WikiRefs: Invalid wikilink level")
160
+ end
161
+ return '<a class="' + $wiki_conf.css_name("wiki") + link_type_txt + '" href="' + lnk_doc_rel_url + '">' + inner_txt + '</a>'
162
+ end
163
+
164
+ # helpers
165
+
166
+ def sort_for_replacement
167
+ # sorting inline wikilinks is necessary so when wikilinks are replaced,
168
+ # !embeds and longer strings are replaced first so as not to accidentally overwrite
169
+ # substrings
170
+ # (this is especially likely if there is a matching wikilink that
171
+ # appears as both untyped and typed in a document or in a regular link and embed)
172
+ temp = @wikilink_inlines.dup
173
+ @wikilink_inlines.clear()
174
+ embeds = temp.select { |w| w.embedded? }
175
+ typed_wikilinks = temp.select { |w| w.is_typed? }
176
+ untyped_wikilinks = temp.select { |w| !w.is_typed? }
177
+ @wikilink_inlines = embeds.concat(typed_wikilinks.concat(untyped_wikilinks))
178
+ end
179
+ end
180
+
181
+ end
182
+ end
@@ -0,0 +1,72 @@
1
+ # regex.rb
2
+ # regex constants defining supported file types and valid names for files, variables, or text
3
+ #
4
+
5
+ module Jekyll
6
+ module WikiRefs
7
+ # <regex_variables> only work with 'match' function, not with 'scan' function. :/
8
+ # oh well...they are there for easier debugging...
9
+
10
+ # supported image formats
11
+ # from: https://docs.github.com/en/github/managing-files-in-a-repository/working-with-non-code-files/rendering-and-diffing-images
12
+ SUPPORTED_IMG_FORMATS = Set.new(['.png', '.jpg', '.gif', '.psd', '.svg'])
13
+
14
+ # wikilink constants
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
+
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
36
+
37
+ # target markdown text (headers, lists, and blocks)
38
+ ## kramdown regexes
39
+ ### atx header: https://github.com/gettalong/kramdown/blob/master/lib/kramdown/parser/kramdown/header.rb#L29
40
+ REGEX_ATX_HEADER = /^\#{1,6}[\t ]*([^ \t].*)\n/i
41
+ ### setext header: https://github.com/gettalong/kramdown/blob/master/lib/kramdown/parser/kramdown/header.rb#L17
42
+ REGEX_SETEXT_HEADER = /^\s{0,3}([^ \t].*)\n[-=][-=]*[ \t\r\f\v]*\n/i
43
+ ## list item: https://github.com/gettalong/kramdown/blob/master/lib/kramdown/parser/kramdown/list.rb#L49
44
+ REGEX_BULLET = /(?<bullet>[+*-])/i
45
+ ## markdown-style block-reference
46
+ REGEX_BLOCK = /.*\s\^#{REGEX_BLOCK_ID_TXT}/i
47
+
48
+ # wikilinks
49
+
50
+ ## inline
51
+ REGEX_WIKI_LINK_INLINES = %r{ # capture indeces
52
+ (#{REGEX_LINK_EMBED})? # 0
53
+ (#{REGEX_LINK_TYPE_TXT}#{REGEX_LINK_TYPE})? # 1
54
+ #{REGEX_LINK_LEFT}
55
+ #{REGEX_FILENAME} # 2
56
+ (#{REGEX_LINK_HEADER}#{REGEX_HEADER_TXT})? # 3
57
+ (#{REGEX_LINK_BLOCK}#{REGEX_BLOCK_ID_TXT})? # 4
58
+ (#{REGEX_LINK_LABEL}#{REGEX_LABEL_TXT})? # 5
59
+ #{REGEX_LINK_RIGHT}
60
+ }x
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
71
+ end
72
+ end
@@ -0,0 +1,312 @@
1
+ # wiki data structures
2
+ require_relative "regex"
3
+
4
+ module Jekyll
5
+ module WikiRefs
6
+
7
+ # wikilink classes know everything about the original markdown syntax and its semantic meaning
8
+
9
+ class WikiLinkBlock
10
+ attr_reader :link_type, :filenames
11
+
12
+ # parameters ordered by appearance in regex
13
+ def initialize(doc_mngr, context_filename, link_type, bullet_type=nil)
14
+ @doc_mngr ||= doc_mngr
15
+ @context_filename ||= context_filename
16
+ @link_type ||= link_type
17
+ @bullet_type ||= bullet_type
18
+ @filenames = []
19
+ end
20
+
21
+ def add_item(filename)
22
+ Jekyll.logger.error("Jekyll-WikiRefs: 'filename' required") if filename.nil? || filename.empty?
23
+ @filenames << filename
24
+ end
25
+
26
+ # data
27
+
28
+ def md_regex
29
+ if !is_typed? || !has_filenames?
30
+ Jekyll.logger.error("Jekyll-WikiRefs: WikiLinkBlock.md_regex error -- type: #{@link_type}, fnames: #{@filenames.inspect}, for: #{@context_filename}")
31
+ end
32
+ # comma (including singles)
33
+ if @bullet_type.nil?
34
+ link_type = /#{@link_type}#{REGEX_LINK_TYPE}/i
35
+ tmp_filenames = @filenames.dup
36
+ first_filename = /\s*#{REGEX_LINK_LEFT}#{tmp_filenames.shift()}#{REGEX_LINK_RIGHT}\s*/i
37
+ filename_strs = tmp_filenames.map { |f| /,\s*#{REGEX_LINK_LEFT}#{f}#{REGEX_LINK_RIGHT}\s*/i }
38
+ md_regex = /#{link_type}#{first_filename}#{filename_strs.join('')}\n/i
39
+ # mkdn
40
+ elsif !@bullet_type.match(REGEX_BULLET).nil?
41
+ link_type = /#{@link_type}#{REGEX_LINK_TYPE}\n/i
42
+ filename_strs = @filenames.map { |f| /\s{0,3}#{Regexp.escape(@bullet_type)}\s#{REGEX_LINK_LEFT}#{f}#{REGEX_LINK_RIGHT}\n/i }
43
+ md_regex = /#{link_type}#{filename_strs.join("")}/i
44
+ else
45
+ Jekyll.logger.error("Jekyll-WikiRefs: WikiLinkBlock.bullet_type error: #{@bullet_type}")
46
+ end
47
+ return md_regex
48
+ end
49
+
50
+ def md_str
51
+ if !is_typed? || !has_filenames?
52
+ Jekyll.logger.error("Jekyll-WikiRefs: WikiLinkBlockList.md_str error -- type: #{@link_type}, fnames: #{@filenames.inspect}, for: #{@context_filename}")
53
+ end
54
+ # comma (including singles)
55
+ if @bullet_type.nil?
56
+ link_type = "#{@link_type}::"
57
+ filename_strs = @filenames.map { |f| "\[\[#{f}\]\]," }
58
+ md_str = (link_type + filename_strs.join('')).delete_suffix(",")
59
+ # mkdn
60
+ elsif !@bullet_type.match(REGEX_BULLET).nil?
61
+ link_type = "#{@link_type}::\n"
62
+ filename_strs = @filenames.map { |f| li[0] + " \[\[#{li[1]}\]\]\n" }
63
+ md_str = link_type + filename_strs.join('')
64
+ else
65
+ Jekyll.logger.error("Jekyll-WikiRefs: 'bullet_type' invalid: #{@bullet_type}")
66
+ end
67
+ return md_str
68
+ end
69
+
70
+ def urls
71
+ # return @filenames.map { |f| @doc_mngr.get_doc_by_fname(f).url }.compact()
72
+ urls = []
73
+ @filenames.each do |f|
74
+ doc = @doc_mngr.get_doc_by_fname(f)
75
+ urls << doc.url if !doc.nil?
76
+ end
77
+ return urls
78
+ end
79
+
80
+ # 'fm' -> frontmatter
81
+
82
+ def context_fm_data
83
+ return {
84
+ 'type' => @link_type,
85
+ 'urls' => [self.context_doc.url],
86
+ }
87
+ end
88
+
89
+ def linked_fm_data
90
+ valid_urls = self.urls.select{ |url| @doc_mngr.get_doc_by_url(url) }
91
+ return {
92
+ 'type' => @link_type,
93
+ 'urls' => valid_urls,
94
+ }
95
+ end
96
+
97
+ def context_doc
98
+ return @doc_mngr.get_doc_by_fname(@context_filename)
99
+ end
100
+
101
+ def linked_docs
102
+ docs = []
103
+ @filenames.each do |f|
104
+ doc = @doc_mngr.get_doc_by_fname(f)
105
+ docs << doc if !doc.nil?
106
+ end
107
+ return docs
108
+ end
109
+
110
+ def missing_doc_filenames
111
+ missing_doc_fnames = []
112
+ @filenames.each do |f|
113
+ doc = @doc_mngr.get_doc_by_fname(f)
114
+ missing_doc_fnames << f if doc.nil?
115
+ end
116
+ return missing_doc_fnames
117
+ end
118
+
119
+ # descriptor methods
120
+
121
+ def has_filenames?
122
+ return !@filenames.nil? && !@filenames.empty?
123
+ end
124
+
125
+ def is_typed?
126
+ return !@link_type.nil? && !@link_type.empty?
127
+ end
128
+
129
+ # validation methods
130
+
131
+ def is_valid?
132
+ all_filenames_missing = linked_docs.empty?
133
+ return false if !is_typed? || !has_filenames? || all_filenames_missing
134
+ return true
135
+ end
136
+ end
137
+
138
+ class WikiLinkInline
139
+ attr_reader :link_type, :filename, :header_txt, :block_id
140
+
141
+ FILE_PATH = "file_path"
142
+ FILENAME = "filename"
143
+ HEADER_TXT = "header_txt"
144
+ BLOCK_ID = "block_id"
145
+
146
+ # parameters ordered by appearance in regex
147
+ def initialize(doc_mngr, context_filename, embed, link_type, file_string, header_txt, block_id, label_txt)
148
+ if file_string.include?('/') && file_string[0] == '/'
149
+ @path_type = "absolute"
150
+ @file_path ||= file_string[1...] # remove leading '/' to match `jekyll_collection_doc.relative_path`
151
+ @filename ||= file_string.split('/').last
152
+ elsif file_string.include?('/') && file_string[0] != '/'
153
+ Jekyll.logger.error("Jekyll-WikiRefs: Relative file paths are not yet supported, please use absolute file paths that start with '/' for #{file_string}")
154
+ # todo:
155
+ # @path_type = "relative"
156
+ else
157
+ @filename ||= file_string
158
+ end
159
+ @doc_mngr ||= doc_mngr
160
+ @context_filename ||= context_filename
161
+ @embed ||= embed
162
+ @link_type ||= link_type
163
+ @header_txt ||= header_txt
164
+ @block_id ||= block_id
165
+ @label_txt ||= label_txt
166
+ end
167
+
168
+ # escape square brackets if they appear in label text
169
+ def label_txt
170
+ return @label_txt.sub("[", "\\[").sub("]", "\\]")
171
+ end
172
+
173
+ # data
174
+
175
+ def md_regex
176
+ regex_embed = embedded? ? REGEX_LINK_EMBED : %r{}
177
+ regex_link_type = is_typed? ? %r{#{@link_type}#{REGEX_LINK_TYPE}} : %r{}
178
+ if !@file_path.nil?
179
+ file_string = described?(FILE_PATH) ? @file_path : ""
180
+ file_string = '/' + file_string if @path_type == "absolute"
181
+ else
182
+ file_string = described?(FILENAME) ? @filename : ""
183
+ end
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) && !described?(FILE_PATH)
191
+ Jekyll.logger.error("Jekyll-WikiRefs: WikiLinkInline.md_regex error")
192
+ end
193
+ label_ = labelled? ? %r{#{REGEX_LINK_LABEL}#{label_txt}} : %r{}
194
+ return %r{#{regex_embed}#{regex_link_type}#{REGEX_LINK_LEFT}#{file_string}#{header}#{block}#{label_}#{REGEX_LINK_RIGHT}}
195
+ end
196
+
197
+ def md_str
198
+ embed = embedded? ? "!" : ""
199
+ link_type = is_typed? ? "#{@link_type}::" : ""
200
+ if !@file_path.nil?
201
+ file_string = described?(FILE_PATH) ? @file_path : ""
202
+ file_string = '/' + file_string if @path_type == "absolute"
203
+ else
204
+ file_string = described?(FILENAME) ? @filename : ""
205
+ end
206
+ if described?(HEADER_TXT)
207
+ header = "\##{@header_txt}"
208
+ block = ""
209
+ elsif described?(BLOCK_ID)
210
+ header = ""
211
+ block = "\#\^#{@block_id}"
212
+ elsif !described?(FILENAME) && !described?(FILE_PATH)
213
+ Jekyll.logger.error("Jekyll-WikiRefs: WikiLinkInline.md_str error")
214
+ end
215
+ label_ = labelled? ? "\|#{@label_txt}" : ""
216
+ return "#{embed}#{link_type}\[\[#{file_string}#{header}#{block}#{label_}\]\]"
217
+ end
218
+
219
+ # 'fm' -> frontmatter
220
+
221
+ def context_fm_data
222
+ return {
223
+ 'type' => @link_type,
224
+ 'url' => self.context_doc.url,
225
+ }
226
+ end
227
+
228
+ def linked_fm_data
229
+ return {
230
+ 'type' => @link_type,
231
+ 'url' => self.linked_doc.url,
232
+ }
233
+ end
234
+
235
+ def context_doc
236
+ return @doc_mngr.get_doc_by_fname(@context_filename)
237
+ end
238
+
239
+ def linked_doc
240
+ # by file path
241
+ return @doc_mngr.get_doc_by_fpath(@file_path) if !@file_path.nil?
242
+ # by filename
243
+ return @doc_mngr.get_doc_by_fname(@filename) if @file_path.nil?
244
+ return nil
245
+ end
246
+
247
+ def linked_img
248
+ return @doc_mngr.get_image_by_fname(@filename) if self.is_img?
249
+ return nil
250
+ end
251
+
252
+ # descriptor methods
253
+
254
+ # def describe
255
+ # return {
256
+ # 'level' => level,
257
+ # 'labelled' => labelled?,
258
+ # 'embedded' => embedded?,
259
+ # 'typed_link' => is_typed?,
260
+ # }
261
+ # end
262
+
263
+ def labelled?
264
+ return !@label_txt.nil? && !@label_txt.empty?
265
+ end
266
+
267
+ def is_typed?
268
+ return !@link_type.nil? && !@link_type.empty?
269
+ end
270
+
271
+ def embedded?
272
+ return !@embed.nil? && @embed == "!"
273
+ end
274
+
275
+ def is_img?
276
+ # github supported image formats: https://docs.github.com/en/github/managing-files-in-a-repository/working-with-non-code-files/rendering-and-diffing-images
277
+ return SUPPORTED_IMG_FORMATS.any?{ |ext| ext == File.extname(@filename).downcase }
278
+ end
279
+
280
+ def is_img_svg?
281
+ return File.extname(@filename).downcase == ".svg"
282
+ end
283
+
284
+ # this method helps to make the 'WikiLinkInline.level' code read like a clean truth table.
285
+ def described?(chunk)
286
+ return (!@file_path.nil? && !@file_path.empty?) if chunk == FILE_PATH
287
+ return (!@filename.nil? && !@filename.empty?) if chunk == FILENAME
288
+ return (!@header_txt.nil? && !@header_txt.empty?) if chunk == HEADER_TXT
289
+ return (!@block_id.nil? && !@block_id.empty?) if chunk == BLOCK_ID
290
+ Jekyll.logger.error("Jekyll-WikiRefs: There is no link level '#{chunk}' in the WikiLink Class")
291
+ end
292
+
293
+ def level
294
+ return "file_path" if described?(FILE_PATH) && described?(FILENAME) && !described?(HEADER_TXT) && !described?(BLOCK_ID)
295
+ return "filename" if !described?(FILE_PATH) && described?(FILENAME) && !described?(HEADER_TXT) && !described?(BLOCK_ID)
296
+ return "header" if (described?(FILE_PATH) || described?(FILENAME)) && described?(HEADER_TXT) && !described?(BLOCK_ID)
297
+ return "block" if (described?(FILE_PATH) || described?(FILENAME)) && !described?(HEADER_TXT) && described?(BLOCK_ID)
298
+ return "invalid"
299
+ end
300
+
301
+ # validation methods
302
+
303
+ def is_valid?
304
+ return false if !@doc_mngr.file_exists?(@filename, @file_path)
305
+ return false if (self.level == "header") && !@doc_mngr.doc_has_header?(self.linked_doc, @header_txt)
306
+ return false if (self.level == "block") && !@doc_mngr.doc_has_block_id?(self.linked_doc, @block_id)
307
+ return true
308
+ end
309
+ end
310
+
311
+ end
312
+ end
@@ -3,7 +3,7 @@
3
3
  module Jekyll
4
4
  module WikiRefs
5
5
 
6
- VERSION = "0.0.1"
6
+ VERSION = "0.0.14"
7
7
 
8
8
  end
9
9
  end
@@ -2,9 +2,29 @@
2
2
 
3
3
  require_relative "jekyll-wikirefs/version"
4
4
 
5
- module Jekyll
6
- module WikiRefs
7
- class Error < StandardError; end
8
- # Your code goes here...
5
+ # setup config
6
+ require_relative "jekyll-wikirefs/config"
7
+ Jekyll::Hooks.register :site, :after_init do |site|
8
+ # global '$wiki_conf' to ensure that all local jekyll plugins
9
+ # are reading from the same configuration
10
+ # (global var is not ideal, but is DRY)
11
+ $wiki_conf = Jekyll::WikiRefs::PluginConfig.new(site.config)
12
+ end
13
+
14
+ # setup docs (based on configs)
15
+ require_relative "jekyll-wikirefs/patch/doc_manager"
16
+ Jekyll::Hooks.register :site, :post_read do |site|
17
+ if !$wiki_conf.disabled?
18
+ site.doc_mngr = Jekyll::WikiRefs::DocManager.new(site)
9
19
  end
10
20
  end
21
+
22
+ # parse wikilinks / generate metadata
23
+ require_relative "jekyll-wikirefs/plugins/generator"
24
+
25
+ # convert weblinks
26
+ require_relative "jekyll-wikirefs/plugins/converter"
27
+
28
+ # hook up liquid filters
29
+ require_relative "jekyll-wikirefs/plugins/filter"
30
+ Liquid::Template.register_filter(Jekyll::WikiRefs::TypeFilters)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-wikirefs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - manunamz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-03-02 00:00:00.000000000 Z
11
+ date: 2023-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
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.13.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.13.3
27
41
  description:
28
42
  email:
29
43
  - manunamz@pm.me
@@ -32,14 +46,25 @@ extensions: []
32
46
  extra_rdoc_files: []
33
47
  files:
34
48
  - lib/jekyll-wikirefs.rb
49
+ - lib/jekyll-wikirefs/config.rb
50
+ - lib/jekyll-wikirefs/patch/context.rb
51
+ - lib/jekyll-wikirefs/patch/doc_manager.rb
52
+ - lib/jekyll-wikirefs/patch/site.rb
53
+ - lib/jekyll-wikirefs/plugins/converter.rb
54
+ - lib/jekyll-wikirefs/plugins/filter.rb
55
+ - lib/jekyll-wikirefs/plugins/generator.rb
56
+ - lib/jekyll-wikirefs/util/link_index.rb
57
+ - lib/jekyll-wikirefs/util/parser.rb
58
+ - lib/jekyll-wikirefs/util/regex.rb
59
+ - lib/jekyll-wikirefs/util/wikiref.rb
35
60
  - lib/jekyll-wikirefs/version.rb
36
- homepage: https://github.com/manunamz/jekyll-wikirefs
61
+ homepage: https://github.com/wikibonsai/jekyll-wikirefs
37
62
  licenses:
38
63
  - MIT
39
64
  metadata:
40
- homepage_uri: https://github.com/manunamz/jekyll-wikirefs
41
- source_code_uri: https://github.com/manunamz/jekyll-wikirefs
42
- changelog_uri: https://github.com/manunamz/jekyll-wikirefs/blob/main/CHANGELOG.md
65
+ homepage_uri: https://github.com/wikibonsai/jekyll-wikirefs
66
+ source_code_uri: https://github.com/wikibonsai/jekyll-wikirefs
67
+ changelog_uri: https://github.com/wikibonsai/jekyll-wikirefs/blob/main/CHANGELOG.md
43
68
  post_install_message:
44
69
  rdoc_options: []
45
70
  require_paths:
@@ -55,8 +80,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
80
  - !ruby/object:Gem::Version
56
81
  version: '0'
57
82
  requirements: []
58
- rubygems_version: 3.4.6
83
+ rubygems_version: 3.4.10
59
84
  signing_key:
60
85
  specification_version: 4
61
- summary: "You thought there was something in here, didn't you? \U0001F609"
86
+ summary: Add [[wikirefs]] support (in markdown files) for jekyll.
62
87
  test_files: []