jekyll-namespaces 0.0.1 → 0.0.2

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: 6b18126c3527c30dd23fe45e39414c918bcc046bcc85a9955e43476457298be2
4
- data.tar.gz: 0a61c1b500793f8eded07a8a55575b25f7e6e9983dbac9df4a77c0591c0c220c
3
+ metadata.gz: 6a486b2fb9c89ac6247a8650948f1111e81836bb374afe532cb08e254dccd831
4
+ data.tar.gz: 94e8c5b5404a1f4550fe2cc6fc06f40df372f61c7ba65a901bda40b4cca6766c
5
5
  SHA512:
6
- metadata.gz: 5ff7599ba50975db33b0d72f14e41606e5b9c0d21126732271dfbc152a08d4c9c9a9dcc422a22bf671bf864ebc637ce14bc58f25c1cd792174ea22b6f64894e5
7
- data.tar.gz: 9f3c5053343f86090eac806c00bcf806034d34fb31ddbb64f17efda9060bd17bf78378482f84f09902bc557b3581bbcc2c2eb2b24ade705bd516136d08e15656
6
+ metadata.gz: c214a76c788e7fe52bc27ec85977546237f714be562973c433fa94f94764c8c88fdf0202a595f9845b85a43b8549c23b9707b05b33176d2f13014395d0da03cb
7
+ data.tar.gz: e0a73b6a22a2c80d32f8142152d46da831f32e73989daa0271766c894cd1debe5245bf36d6aa750556a494ec6560248a98b3144af3edccbd4fa1bfec7ee7c962
@@ -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-d3
5
+
6
+ module Jekyll
7
+
8
+ class Site
9
+ attr_accessor :tree
10
+ end
11
+
12
+ end
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+ require "jekyll"
3
+
4
+ module Jekyll
5
+
6
+ class Tree
7
+ attr_reader :root
8
+
9
+ def initialize(root_doc, md_docs)
10
+ @root = Node.new('root', root_doc.data['id'], root_doc.data['title'], root_doc.url, root_doc)
11
+
12
+ md_docs.each do |doc|
13
+ if doc != @root.doc
14
+ # jekyll pages don't have the slug attribute: https://github.com/jekyll/jekyll/blob/master/lib/jekyll/page.rb#L8
15
+ if doc.type == :pages
16
+ page_basename = File.basename(doc.name, File.extname(doc.name))
17
+ doc.data['slug'] = Jekyll::Utils.slugify(page_basename)
18
+ end
19
+ self.add_path(doc)
20
+ end
21
+ end
22
+
23
+ # print_tree(root)
24
+ end
25
+
26
+ # add unique path for the given doc to tree (node-class).
27
+ def add_path(doc, node=nil, depth=1)
28
+ node = @root if depth == 1
29
+ Jekyll.logger.error("Incorrect node in tree.add_path") if node == nil
30
+ levels = doc.data['slug'].split(/\s|\./)
31
+ # handle doc if the given node was not root and we are at depth
32
+ if depth == levels.length
33
+ cur_nd_namespace = 'root' + '.' + doc.data['slug']
34
+ cur_nd_id = doc.data['id']
35
+ cur_nd_title = doc.data['title']
36
+ cur_nd_url = doc.url
37
+
38
+ cur_node = node.children.detect {|c| c.namespace == cur_nd_namespace }
39
+ # create node if one does not exist
40
+ if cur_node.nil?
41
+ new_node = Node.new(cur_nd_namespace, cur_nd_id, cur_nd_title, cur_nd_url, doc)
42
+ node.children << new_node
43
+ # fill-in node if one already exists
44
+ else
45
+ cur_node.fill(cur_nd_id, cur_nd_title, cur_nd_url, doc)
46
+ end
47
+ return
48
+ # create temp node and recurse
49
+ else
50
+ cur_namespace = 'root' + '.' + levels[0..(depth - 1)].join('.')
51
+ unless node.children.any? { |c| c.namespace == cur_namespace }
52
+ new_node = Node.new(cur_namespace)
53
+ node.children << new_node
54
+ else
55
+ new_node = node.children.detect { |c| c.namespace == cur_namespace }
56
+ end
57
+ end
58
+ self.add_path(doc, new_node, depth + 1)
59
+ end
60
+
61
+ def get_all_relative_ids(target_node_id, node=@root, ancestors=[], descendents=[], found=false)
62
+ # found target node, stop adding ancestors and build descendents
63
+ if target_node_id == node.url || target_node_id == node.namespace || found
64
+ node.children.each do |child_node|
65
+ # if the child document is an empty string, it is a missing node
66
+ if child_node.missing
67
+ descendents << child_node.namespace
68
+ else
69
+ descendents << child_node.doc.url
70
+ end
71
+ self.get_all_relative_ids(target_node_id, child_node, ancestors.clone, descendents, found=true)
72
+ end
73
+ return ancestors, descendents
74
+ # target node not yet found, build ancestors
75
+ else
76
+ # if the node document is an empty string, it is a missing node
77
+ if node.missing
78
+ ancestors << node.namespace
79
+ else
80
+ ancestors << node.doc.url
81
+ end
82
+ results = []
83
+ node.children.each do |child_node|
84
+ results.concat(self.get_all_relative_ids(target_node_id, child_node, ancestors.clone))
85
+ end
86
+ return results.select { |r| !r.nil? }
87
+ end
88
+ end
89
+
90
+ # find the parent and children of the 'target_doc'.
91
+ # ('node' as in the current node, which first is root.)
92
+ def find_doc_immediate_relatives(target_doc, node=nil, ancestors=[])
93
+ node = @root if ancestors == []
94
+ Jekyll.logger.error("Incorrect node in tree.find_doc_immediate_relatives") if node == nil
95
+ if target_doc == node.doc
96
+ children = []
97
+ node.children.each do |child|
98
+ # if the child document is an empty string, it is a missing node
99
+ if child.missing
100
+ children << child.namespace
101
+ else
102
+ children << child.doc.url
103
+ end
104
+ end
105
+ return ancestors, children
106
+ else
107
+ # if the node document is an empty string, it is a missing node
108
+ if node.missing
109
+ ancestors << node.namespace
110
+ else
111
+ ancestors << node.doc.url
112
+ end
113
+ results = []
114
+ node.children.each do |child_node|
115
+ results.concat(self.find_doc_immediate_relatives(target_doc, child_node, ancestors.clone))
116
+ end
117
+ return results.select { |r| !r.nil? }
118
+ end
119
+ end
120
+
121
+ # ...for debugging
122
+ def print_tree(node, ancestors=[])
123
+ Jekyll.logger.warn "Ancestors: ", ancestors.length
124
+ Jekyll.logger.warn node
125
+ Jekyll.logger.warn "Children: ", node.children
126
+ ancestors.append(node.id)
127
+ node.children.each do |child_node|
128
+ self.print_tree(child_node, ancestors.clone)
129
+ end
130
+ end
131
+ end
132
+
133
+ class Node
134
+ attr_accessor :namespace, :id, :title, :children, :url, :doc
135
+
136
+ def initialize(namespace, id="", title="", url="", doc="")
137
+ # mandatory
138
+ @namespace = namespace
139
+ # optional
140
+ @id = id.to_s
141
+ @title = title
142
+ @url = url.nil? ? "" : url
143
+ @doc = doc
144
+ # auto-init
145
+ @children = []
146
+ end
147
+
148
+ def fill(id, title, url, doc)
149
+ @id = id
150
+ @title = title
151
+ @url = url
152
+ @doc = doc
153
+ end
154
+
155
+ def missing
156
+ return @doc == ""
157
+ end
158
+
159
+ def type
160
+ return @doc.type
161
+ end
162
+
163
+ def to_s
164
+ "namespace: #{@namespace}"
165
+ end
166
+ end
167
+
168
+ end
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module JekyllNamespaces
4
- VERSION = "0.0.1"
3
+ module Jekyll
4
+ module Namespaces
5
+
6
+ VERSION = "0.0.2"
7
+
8
+ end
5
9
  end
@@ -2,237 +2,97 @@
2
2
  require "jekyll"
3
3
 
4
4
  require_relative "jekyll-namespaces/context"
5
- require_relative "jekyll-namespaces/node"
5
+ require_relative "jekyll-namespaces/site"
6
+ require_relative "jekyll-namespaces/tree"
6
7
  require_relative "jekyll-namespaces/version"
7
8
 
8
- module JekyllNamespaces
9
- class Generator < Jekyll::Generator
10
- attr_accessor :site, :config
11
-
12
- # Use Jekyll's native relative_url filter
13
- include Jekyll::Filters::URLFilters
14
-
15
- CONVERTER_CLASS = Jekyll::Converters::Markdown
16
- # config
17
- CONFIG_KEY = "namespaces"
18
- ENABLED_KEY = "enabled"
19
- INCLUDE_KEY = "include"
20
- # graph config
21
- GRAPH_DATA_KEY = "d3_graph_data"
22
- ENABLED_GRAPH_DATA_KEY = "enabled"
23
- EXCLUDE_GRAPH_KEY = "exclude"
24
- GRAPH_ASSETS_LOCATION_KEY = "path"
25
-
26
- def initialize(config)
27
- @config ||= config
28
- @testing ||= config['testing'] if config.keys.include?('testing')
29
- end
30
-
31
- def generate(site)
32
- return if disabled?
33
-
34
- # setup site
35
- @site = site
36
- @context ||= Context.new(site)
37
-
38
- # setup markdown docs
39
- docs = []
40
- docs += site.pages if include?(:pages)
41
- docs += site.docs_to_write.filter { |d| include?(d.type) }
42
- @md_docs = docs.filter {|doc| markdown_extension?(doc.extname) }
43
-
44
- # setup tree
45
- root_doc = @md_docs.detect {|doc| doc.data['slug'] == 'root' }
46
- root = Node.new(root_doc.data['id'], 'root', root_doc.data['title'], root_doc)
47
- # build tree
48
- @md_docs.each do |cur_doc|
49
- # add path to tree
50
- if !cur_doc.data['slug'].nil? and cur_doc.data['slug'] != 'root'
51
- self.add_path(root, cur_doc)
52
- end
53
- end
54
-
55
- # print_tree(root)
56
-
57
- # generate tree metadata
58
- @md_docs.each do |cur_doc|
59
- if !excluded_in_graph?(cur_doc)
60
- # TODO: cur_doc.data['namespace'] = cur_doc.basename_without_ext
61
- cur_doc.data['namespace'] = cur_doc.basename[0...-3]
62
- cur_doc.data['ancestors'], cur_doc.data['children'] = self.find_doc_immediate_relatives(cur_doc, root)
63
- end
64
- end
65
- # graph
66
- if !disabled_graph_data?
67
- self.write_graph(root)
68
- end
69
- end
70
-
71
- # config helpers
72
-
73
- def disabled?
74
- option(ENABLED_KEY) == false
75
- end
9
+ module Jekyll
10
+ module Namespaces
76
11
 
77
- def include?(type)
78
- return false unless option(INCLUDE_KEY)
79
- return option(INCLUDE_KEY).include?(type.to_s)
80
- end
12
+ class Generator < Jekyll::Generator
13
+ # for testing
14
+ attr_reader :config
81
15
 
82
- def markdown_extension?(extension)
83
- markdown_converter.matches(extension)
84
- end
85
-
86
- def markdown_converter
87
- @markdown_converter ||= @site.find_converter_instance(CONVERTER_CLASS)
88
- end
16
+ CONVERTER_CLASS = Jekyll::Converters::Markdown
17
+ # config
18
+ CONFIG_KEY = "namespaces"
19
+ ENABLED_KEY = "enabled"
20
+ EXCLUDE_KEY = "exclude"
89
21
 
90
- def option(key)
91
- config[CONFIG_KEY] && config[CONFIG_KEY][key]
92
- end
22
+ def initialize(config)
23
+ @config ||= config
24
+ end
93
25
 
94
- # graph config helpers
26
+ def generate(site)
27
+ return if disabled?
28
+ self.old_config_warn()
29
+
30
+ # setup site
31
+ @site = site
32
+ @context ||= Context.new(site)
33
+
34
+ # setup markdown docs
35
+ docs = []
36
+ docs += @site.pages if !excluded?(:pages)
37
+ docs += @site.docs_to_write.filter { |d| !excluded?(d.type) }
38
+ @md_docs = docs.filter { |doc| markdown_extension?(doc.extname) }
39
+ if @md_docs.empty?
40
+ Jekyll.logger.debug("No documents to process.")
41
+ end
95
42
 
96
- def disabled_graph_data?
97
- option_graph(ENABLED_GRAPH_DATA_KEY) == false
98
- end
43
+ # tree setup
44
+ root_doc = @md_docs.detect { |d| d.data['slug'] == 'root' }
45
+ if root_doc.nil?
46
+ Jekyll.logger.debug("No root.md detected.")
47
+ end
48
+ @site.tree = Tree.new(root_doc, @md_docs)
99
49
 
100
- def excluded_in_graph?(type)
101
- return false unless option_graph(EXCLUDE_GRAPH_KEY)
102
- return option_graph(EXCLUDE_GRAPH_KEY).include?(type.to_s)
103
- end
50
+ # generate metadata
51
+ @md_docs.each do |doc|
52
+ doc.data['namespace'] = doc.data['slug']
53
+ doc.data['ancestors'], doc.data['children'] = @site.tree.find_doc_immediate_relatives(doc)
54
+ end
104
55
 
105
- def has_custom_assets_path?
106
- return !!option_graph(GRAPH_ASSETS_LOCATION_KEY)
107
- end
56
+ end
108
57
 
109
- def option_graph(key)
110
- config[GRAPH_DATA_KEY] && config[GRAPH_DATA_KEY][key]
111
- end
58
+ # config helpers
112
59
 
113
- # helpers
114
-
115
- # add unique path for the given doc to tree (node-class).
116
- def add_path(node, doc, depth=1)
117
- chunked_namespace = doc.data['slug'].split(/\s|\./)
118
- # handle doc if the given node was not root and we are at depth
119
- if depth == chunked_namespace.length
120
- cur_nd_namespace = 'root' + '.' + doc.data['slug']
121
- cur_nd_id = doc.data['id']
122
- cur_nd_title = doc.data['title']
123
- # create node if one does not exist
124
- unless node.children.any?{ |c| c.namespace == cur_nd_namespace }
125
- new_node = Node.new(cur_nd_id, cur_nd_namespace, cur_nd_title, doc)
126
- node.children << new_node
127
- # fill-in node if one already exists
128
- else
129
- cur_node = node.children.detect {|c| c.namespace == cur_nd_namespace }
130
- cur_node.id = cur_nd_id
131
- cur_node.title = cur_nd_title
132
- cur_node.doc = doc
133
- end
134
- return
135
- # create temp node and recurse
136
- else
137
- cur_namespace = 'root' + '.' + chunked_namespace[0..(depth - 1)].join('.')
138
- unless node.children.any?{ |c| c.namespace == cur_namespace }
139
- new_node = Node.new('', cur_namespace, '', '')
140
- node.children << new_node
141
- else
142
- new_node = node.children.detect {|c| c.namespace == cur_namespace }
143
- end
60
+ def disabled?
61
+ option(ENABLED_KEY) == false
144
62
  end
145
- self.add_path(new_node, doc, depth + 1)
146
- end
147
63
 
148
- # find the parent and children of the 'target_doc'.
149
- # ('node' as in the current node, which first is root.)
150
- def find_doc_immediate_relatives(target_doc, node, ancestors=[])
151
- if target_doc.data['id'] == node.id
152
- children = []
153
- node.children.each do |child|
154
- if child.id == ''
155
- children << {
156
- 'id' => '',
157
- 'title' => child.namespace.match('([^.]*$)')[0].gsub('-', ' ')
158
- }
159
- else
160
- children << child.doc
161
- end
162
- end
163
- return ancestors, children
164
- else
165
- if node.id == ''
166
- ancestors << {
167
- 'id' => '',
168
- 'title' => node.namespace.match('([^.]*$)')[0].gsub('-', ' ')
169
- }
170
- else
171
- ancestors << node.doc
172
- end
173
- results = []
174
- node.children.each do |child_node|
175
- results.concat self.find_doc_immediate_relatives(target_doc, child_node, ancestors.clone)
176
- end
177
- return results.select { |r| !r.nil? }
64
+ def excluded?(type)
65
+ return false unless option(EXCLUDE_KEY)
66
+ return option(EXCLUDE_KEY).include?(type.to_s)
178
67
  end
179
- end
180
68
 
181
- # ...for debugging
182
- def print_tree(node, ancestors=[])
183
- Jekyll.logger.warn "Ancestors: ", ancestors.length
184
- Jekyll.logger.warn node
185
- Jekyll.logger.warn "Children: ", node.children
186
- ancestors.append(node.id)
187
- node.children.each do |child_node|
188
- self.print_tree(child_node, ancestors.clone)
69
+ def markdown_extension?(extension)
70
+ markdown_converter.matches(extension)
189
71
  end
190
- end
191
72
 
192
- # graph helpers
193
-
194
- # convert tree (node-class) to json
195
- def tree_to_json(baseurl, node, json_node={})
196
- if node.id.empty?
197
- Jekyll.logger.warn "Tree node missing: ", node.namespace
198
- label = node.namespace.match('([^.]*$)')[0].gsub('-', ' ')
199
- node_url = ''
200
- else
201
- label = node.title
202
- node_url = relative_url(node.doc.url)
73
+ def markdown_converter
74
+ @markdown_converter ||= @site.find_converter_instance(CONVERTER_CLASS)
203
75
  end
204
- json_children = []
205
- node.children.each do |child|
206
- new_child = self.tree_to_json(baseurl, child)
207
- json_children.append(new_child)
76
+
77
+ def option(key)
78
+ @config[CONFIG_KEY] && @config[CONFIG_KEY][key]
208
79
  end
209
- json_node = {
210
- # "id": node.id,
211
- "id": node_url,
212
- "namespace": node.namespace,
213
- "label": label,
214
- "children": json_children,
215
- "url": node_url,
216
- }
217
- return json_node
218
- end
219
80
 
220
- def write_graph(root)
221
- assets_path = has_custom_assets_path? ? option_graph(GRAPH_ASSETS_LOCATION_KEY) : "/assets"
222
- if !File.directory?(File.join(site.source, assets_path))
223
- Jekyll.logger.error "Assets location does not exist, please create required directories for path: ", assets_path
81
+ # !! deprecated !!
82
+
83
+ def option_exist?(key)
84
+ @config[CONFIG_KEY] && @config[CONFIG_KEY].include?(key)
224
85
  end
225
- # from: https://github.com/jekyll/jekyll/issues/7195#issuecomment-415696200
226
- static_file = Jekyll::StaticFile.new(site, site.source, assets_path, "graph-tree.json")
227
- json_formatted_tree = self.tree_to_json(@site.baseurl, root)
228
- File.write(@site.source + static_file.relative_path, JSON.dump(
229
- json_formatted_tree
230
- ))
231
- # tests fail without manually adding the static file, but actual site builds seem to do ok
232
- # ...although there does seem to be a race condition which causes a rebuild to be necessary in order to detect the graph data file
233
- if @testing
234
- @site.static_files << static_file if !@site.static_files.include?(static_file)
86
+
87
+ def old_config_warn()
88
+ if @config.include?("d3_graph_data")
89
+ Jekyll.logger.warn "As of 0.0.2, 'd3_graph_data' should now be 'd3' and requires the 'jekyll-d3' plugin."
90
+ end
91
+ if option_exist?("include")
92
+ Jekyll.logger.warn "As of 0.0.2, all markdown files are processed by default. Use 'exclude' config to exclude document types."
93
+ end
235
94
  end
236
95
  end
96
+
237
97
  end
238
98
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-namespaces
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - manunamz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-23 00:00:00.000000000 Z
11
+ date: 2021-09-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -19,11 +19,12 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - lib/jekyll-namespaces.rb
21
21
  - lib/jekyll-namespaces/context.rb
22
- - lib/jekyll-namespaces/node.rb
22
+ - lib/jekyll-namespaces/site.rb
23
+ - lib/jekyll-namespaces/tree.rb
23
24
  - lib/jekyll-namespaces/version.rb
24
25
  homepage: https://github.com/manunamz/jekyll-namespaces
25
26
  licenses:
26
- - MIT
27
+ - GPL3
27
28
  metadata:
28
29
  homepage_uri: https://github.com/manunamz/jekyll-namespaces
29
30
  source_code_uri: https://github.com/manunamz/jekyll-namespaces
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # helper class for tree-building.
4
- class Node
5
- attr_accessor :id, :namespace, :title, :children, :doc
6
-
7
- def initialize(id, namespace, title, doc)
8
- @id = id
9
- @children = []
10
- @namespace = namespace
11
- @title = title
12
- @doc = doc
13
- end
14
-
15
- def type
16
- return doc.type
17
- end
18
-
19
- def to_s
20
- "namespace: #{@namespace}"
21
- end
22
- end