jekyll-namespaces 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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