yarrow 0.9.0 → 0.9.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 +4 -4
- data/.gitignore +1 -0
- data/lib/yarrow/content/expansion/aggregator.rb +9 -6
- data/lib/yarrow/content/expansion/basename_merge.rb +3 -3
- data/lib/yarrow/content/expansion/directory_merge.rb +3 -3
- data/lib/yarrow/content/expansion/filename_map.rb +3 -3
- data/lib/yarrow/content/expansion/traversal.rb +13 -13
- data/lib/yarrow/content/policy.rb +1 -1
- data/lib/yarrow/format/markdown.rb +1 -1
- data/lib/yarrow/format/methods/front_matter.rb +59 -2
- data/lib/yarrow/format.rb +1 -1
- data/lib/yarrow/symbols.rb +6 -0
- data/lib/yarrow/version.rb +1 -1
- data/lib/yarrow/web/generator.rb +2 -1
- data/lib/yarrow/web/manifest.rb +8 -0
- data/lib/yarrow.rb +1 -0
- data/yarrow.gemspec +3 -1
- metadata +44 -6
- data/lib/yarrow/content/expansion/directory_map.rb +0 -21
- data/lib/yarrow/content/expansion/file_list.rb +0 -15
- data/lib/yarrow/content/expansion/strategy.rb +0 -118
- data/lib/yarrow/content/expansion/tree.rb +0 -93
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee0d0048f5ad41b5bd0d8c0cb49059728e2920217876618294cc08997e450914
|
4
|
+
data.tar.gz: e12fc19f4d9e973e522ae20e995bddf81c1e21861cfa26136cc3f03acf7f20b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81d64f248a17176116104d16f3d1e1a718aa5aa68eced9cc5eefa5ae8fb2d050bf43532c378a131010eab80125cb63360704790d62687287669f1a8c96bf91e3
|
7
|
+
data.tar.gz: 1f3e90865e4a947a1615eb0ea190a35f7cf4b8d3b51de6a1e1d9b78391f7e47d7a480153aacdef51028debca6d6eeb58222017c480cb1c66b143e361fa762bb6
|
data/.gitignore
CHANGED
@@ -12,13 +12,13 @@ module Yarrow
|
|
12
12
|
def before_traversal(policy)
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
15
|
+
def expand_source(container, policy)
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
18
|
+
def expand_directory(collection, policy)
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
21
|
+
def expand_file(entity, policy)
|
22
22
|
end
|
23
23
|
|
24
24
|
def after_traversal(policy)
|
@@ -53,13 +53,16 @@ module Yarrow
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def create_entity(source_node, parent_path, type, entity_const)
|
56
|
+
contents = Yarrow::Format.read(source_node.props[:path])
|
57
|
+
|
56
58
|
# Create an entity node with attached resource model
|
57
59
|
entity = graph.create_node do |entity_node|
|
58
60
|
attributes = {
|
59
61
|
name: source_node.props[:basename],
|
60
|
-
title: source_node.props[:basename]
|
61
|
-
body:
|
62
|
-
}
|
62
|
+
title: Yarrow::Symbols.to_text(source_node.props[:basename]),
|
63
|
+
body: contents.document.to_s
|
64
|
+
}.merge(contents.metadata)
|
65
|
+
|
63
66
|
entity_node.label = :entity
|
64
67
|
entity_node.props[:type] = type
|
65
68
|
entity_node.props[:resource] = entity_const.new(attributes)
|
@@ -9,18 +9,18 @@ module Yarrow
|
|
9
9
|
@entity_collections = {}
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
12
|
+
def expand_source(container, policy)
|
13
13
|
puts "create_node label=:collection type=:#{policy.collection} name='#{container.props[:basename]}'"
|
14
14
|
@container_collection = container.props[:basename]
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
17
|
+
def expand_directory(collection, policy)
|
18
18
|
if @container_collection == collection.props[:entry].parent.to_s
|
19
19
|
puts "create_node label=:collection type=:#{policy.entity} name='#{collection.props[:basename]}' collection='#{@container_collection}'"
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
23
|
+
def expand_file(entity, policy)
|
24
24
|
unless @entity_bundles.key?(entity.props[:basename])
|
25
25
|
@entity_bundles[entity.props[:basename]] = []
|
26
26
|
end
|
@@ -8,16 +8,16 @@ module Yarrow
|
|
8
8
|
@current_entity = nil
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
11
|
+
def expand_source(container, policy)
|
12
12
|
create_collection(container, policy.container, policy.container_const)
|
13
13
|
@current_collection = container.props[:path]
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def expand_directory(collection, policy)
|
17
17
|
@current_entity = collection.props[:basename]
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
20
|
+
def expand_file(entity, policy)
|
21
21
|
if entity.props[:basename] == @current_entity && entity.props[:ext] == ".md"
|
22
22
|
create_entity(entity, @current_collection, policy.entity, policy.entity_const)
|
23
23
|
else
|
@@ -2,17 +2,17 @@ module Yarrow
|
|
2
2
|
module Content
|
3
3
|
module Expansion
|
4
4
|
class FilenameMap < Aggregator
|
5
|
-
def
|
5
|
+
def expand_source(container, policy)
|
6
6
|
create_collection(container, policy.container, policy.container_const)
|
7
7
|
@current_collection = container.props[:path]
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
10
|
+
def expand_directory(collection, policy)
|
11
11
|
create_collection(collection, policy.collection, policy.collection_const)
|
12
12
|
@current_collection = collection.props[:path]
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
15
|
+
def expand_file(entity, policy)
|
16
16
|
if policy.match_by_extension(entity.props[:ext])
|
17
17
|
parent_path = entity.incoming(:directory).first.props[:path]
|
18
18
|
create_entity(entity, parent_path, policy.entity, policy.entity_const)
|
@@ -21,45 +21,45 @@ module Yarrow
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
25
|
-
aggregator.
|
24
|
+
def visit_source(root_node)
|
25
|
+
aggregator.expand_source(root_node, policy)
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
28
|
+
def visit_directory(dir_node)
|
29
29
|
# TODO: match on potential directory extension/filter
|
30
|
-
aggregator.
|
30
|
+
aggregator.expand_directory(dir_node, policy)
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
33
|
+
def visit_file(file_node)
|
34
34
|
# TODO: dispatch underscore prefix or index files separately
|
35
35
|
# TODO: match on file extension
|
36
|
-
aggregator.
|
36
|
+
aggregator.expand_file(file_node, policy)
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
39
|
+
def start_traversal
|
40
40
|
aggregator.before_traversal(policy)
|
41
41
|
end
|
42
42
|
|
43
|
-
def
|
43
|
+
def complete_traversal
|
44
44
|
aggregator.after_traversal(policy)
|
45
45
|
end
|
46
46
|
|
47
47
|
def expand
|
48
|
-
|
48
|
+
start_traversal
|
49
49
|
|
50
50
|
traversal = source_node.depth_first.each
|
51
51
|
|
52
|
-
|
52
|
+
visit_source(traversal.next)
|
53
53
|
|
54
54
|
loop do
|
55
55
|
node = traversal.next
|
56
56
|
case node.label
|
57
|
-
when :directory then
|
58
|
-
when :file then
|
57
|
+
when :directory then visit_directory(node)
|
58
|
+
when :file then visit_file(node)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
|
62
|
+
complete_traversal
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
@@ -109,7 +109,7 @@ module Yarrow
|
|
109
109
|
@container = container
|
110
110
|
@collection = collection
|
111
111
|
@entity = entity
|
112
|
-
@expansion = expansion
|
112
|
+
@expansion = expansion.to_sym
|
113
113
|
@extensions = extensions
|
114
114
|
@source_path = source_path
|
115
115
|
@module_prefix = module_prefix.split(MODULE_SEPARATOR)
|
@@ -3,18 +3,75 @@ module Yarrow
|
|
3
3
|
module Methods
|
4
4
|
# Utility methods for working with text formats containing frontmatter separators.
|
5
5
|
module FrontMatter
|
6
|
+
module Syntax
|
7
|
+
YAML = "-"
|
8
|
+
YAML_DOC_END = "."
|
9
|
+
TOML = "+"
|
10
|
+
MM_JSON = ";"
|
11
|
+
JSON_START = "{"
|
12
|
+
JSON_END = "}"
|
13
|
+
|
14
|
+
PATTERN = /\A
|
15
|
+
(?<start>[\-]{3}|[\+]{3}|[;]{3}|[\{]{1})\s*\r?\n
|
16
|
+
(?<meta>.*?)\r?\n?
|
17
|
+
^(?<stop>[\-]{3}|[\+]{3}|[;]{3}|[\.]{3}|[\}]{1})\s*\r?\n?
|
18
|
+
\r?\n?
|
19
|
+
(?<body>.*)
|
20
|
+
/mx
|
21
|
+
end
|
22
|
+
|
6
23
|
module ClassMethods
|
7
24
|
def read(path)
|
8
25
|
text = File.read(path, :encoding => "utf-8")
|
9
|
-
source, metadata =
|
26
|
+
source, metadata = parse(text)
|
10
27
|
Yarrow::Format::Contents.new(new(source), metadata)
|
11
28
|
end
|
12
29
|
|
30
|
+
def parse(text)
|
31
|
+
result = Syntax::PATTERN.match(text)
|
32
|
+
|
33
|
+
return [text, nil] if result.nil?
|
34
|
+
|
35
|
+
start_chr = result[:start].chr
|
36
|
+
stop_chr = result[:stop].chr
|
37
|
+
input = result[:meta]
|
38
|
+
|
39
|
+
meta = if start_chr == stop_chr
|
40
|
+
case start_chr
|
41
|
+
when Syntax::YAML then parse_yaml(input)
|
42
|
+
when Syntax::TOML then parse_toml(input)
|
43
|
+
when Syntax::MM_JSON then parse_json(input)
|
44
|
+
end
|
45
|
+
else
|
46
|
+
if start_chr == Syntax::YAML && stop_chr == Syntax::YAML_DOC_END
|
47
|
+
parse_yaml(input)
|
48
|
+
elsif start_chr == Syntax::JSON_START && stop_chr == Syntax::JSON_END
|
49
|
+
parse_json(input)
|
50
|
+
else
|
51
|
+
raise "Unsupported frontmatter delimiters"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
[result[:body], meta]
|
56
|
+
end
|
57
|
+
|
58
|
+
def parse_yaml(raw)
|
59
|
+
YAML.load(raw, symbolize_names: true)
|
60
|
+
end
|
61
|
+
|
62
|
+
def parse_toml(raw)
|
63
|
+
TomlRB.parse(raw, symbolize_keys: true)
|
64
|
+
end
|
65
|
+
|
66
|
+
def parse_json(raw)
|
67
|
+
JSON.parse("{#{raw}}", symbolize_names: true)
|
68
|
+
end
|
69
|
+
|
13
70
|
def read_yfm(path)
|
14
71
|
text = File.read(path, :encoding => 'utf-8')
|
15
72
|
extract_yfm(text, symbolize_keys: true)
|
16
73
|
end
|
17
|
-
|
74
|
+
|
18
75
|
def extract_yfm(text, options={})
|
19
76
|
pattern = /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
20
77
|
if text =~ pattern
|
data/lib/yarrow/format.rb
CHANGED
data/lib/yarrow/symbols.rb
CHANGED
@@ -30,5 +30,11 @@ module Yarrow
|
|
30
30
|
def self.to_plural(atom)
|
31
31
|
Strings::Inflection.pluralize(atom.to_s).to_sym
|
32
32
|
end
|
33
|
+
|
34
|
+
# @param [Symbol, String] atom
|
35
|
+
# @return [String]
|
36
|
+
def self.to_text(identifier)
|
37
|
+
identifier.to_s.gsub(/\A[^[:alnum:]]+/, "").gsub(/[\-_]+/, " ").capitalize
|
38
|
+
end
|
33
39
|
end
|
34
40
|
end
|
data/lib/yarrow/version.rb
CHANGED
data/lib/yarrow/web/generator.rb
CHANGED
data/lib/yarrow/web/manifest.rb
CHANGED
@@ -56,10 +56,18 @@ module Yarrow
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def self.collection_context(collection)
|
59
|
+
# TODO: debug log
|
60
|
+
# puts "collection_context"
|
61
|
+
# p collection.props[:resource].title
|
62
|
+
# p collection
|
59
63
|
IndexDocument.new(collection, nil, true)
|
60
64
|
end
|
61
65
|
|
62
66
|
def self.collection_index_context(collection, entity)
|
67
|
+
# TODO: debug log
|
68
|
+
# puts "collection_index_context"
|
69
|
+
# p collection.props[:resource].title
|
70
|
+
# p entity.props[:resource].title
|
63
71
|
IndexDocument.new(collection, entity, false)
|
64
72
|
end
|
65
73
|
|
data/lib/yarrow.rb
CHANGED
data/yarrow.gemspec
CHANGED
@@ -24,7 +24,9 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_runtime_dependency 'parallel', '~> 1.22.1'
|
25
25
|
spec.add_runtime_dependency 'strings-inflection', '~> 0.1'
|
26
26
|
spec.add_runtime_dependency 'strings-case', '~> 0.3'
|
27
|
-
|
27
|
+
spec.add_runtime_dependency 'toml-rb', '~> 2.2.0'
|
28
|
+
spec.add_runtime_dependency 'shale', '~> 1.0.0'
|
29
|
+
spec.add_runtime_dependency 'phlex', '~> 1.8.1'
|
28
30
|
spec.add_runtime_dependency 'kramdown', '~> 2.4.0'
|
29
31
|
spec.add_development_dependency 'rake', '~> 13.0'
|
30
32
|
spec.add_development_dependency 'rspec', '~> 3.11'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yarrow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Rickerby
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -164,6 +164,48 @@ dependencies:
|
|
164
164
|
- - "~>"
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0.3'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: toml-rb
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 2.2.0
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: 2.2.0
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: shale
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: 1.0.0
|
188
|
+
type: :runtime
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: 1.0.0
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: phlex
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - "~>"
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: 1.8.1
|
202
|
+
type: :runtime
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - "~>"
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: 1.8.1
|
167
209
|
- !ruby/object:Gem::Dependency
|
168
210
|
name: kramdown
|
169
211
|
requirement: !ruby/object:Gem::Requirement
|
@@ -263,13 +305,9 @@ files:
|
|
263
305
|
- lib/yarrow/console_runner.rb
|
264
306
|
- lib/yarrow/content/expansion/aggregator.rb
|
265
307
|
- lib/yarrow/content/expansion/basename_merge.rb
|
266
|
-
- lib/yarrow/content/expansion/directory_map.rb
|
267
308
|
- lib/yarrow/content/expansion/directory_merge.rb
|
268
|
-
- lib/yarrow/content/expansion/file_list.rb
|
269
309
|
- lib/yarrow/content/expansion/filename_map.rb
|
270
|
-
- lib/yarrow/content/expansion/strategy.rb
|
271
310
|
- lib/yarrow/content/expansion/traversal.rb
|
272
|
-
- lib/yarrow/content/expansion/tree.rb
|
273
311
|
- lib/yarrow/content/graph.rb
|
274
312
|
- lib/yarrow/content/model.rb
|
275
313
|
- lib/yarrow/content/policy.rb
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Yarrow
|
2
|
-
module Content
|
3
|
-
module Expansion
|
4
|
-
class DirectoryMap < Aggregator
|
5
|
-
def expand_container(container, policy)
|
6
|
-
puts "create_node label=:collection type=:#{policy.container} name='#{container.props[:basename]}'"
|
7
|
-
@current_collection = container.props[:basename]
|
8
|
-
end
|
9
|
-
|
10
|
-
def expand_collection(collection, policy)
|
11
|
-
puts "create_node label=:collection type=:#{policy.collection} name='#{collection.props[:basename]}' collection=#{@current_collection}"
|
12
|
-
@current_collection = collection.props[:basename]
|
13
|
-
end
|
14
|
-
|
15
|
-
def expand_entity(entity, policy)
|
16
|
-
puts "create_node label=:entity type=:#{policy.entity} name='#{entity.props[:basename]}' collection='#{@current_collection}"
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Yarrow
|
2
|
-
module Content
|
3
|
-
module Expansion
|
4
|
-
class FileList < Strategy
|
5
|
-
def expand(policy)
|
6
|
-
start_node = graph.n(:root).out(name: policy.container.to_s)
|
7
|
-
|
8
|
-
start_node.out(:files).each do |file_node|
|
9
|
-
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,118 +0,0 @@
|
|
1
|
-
module Yarrow
|
2
|
-
module Content
|
3
|
-
module Expansion
|
4
|
-
class Strategy
|
5
|
-
include Yarrow::Tools::FrontMatter
|
6
|
-
|
7
|
-
attr_reader :graph
|
8
|
-
|
9
|
-
def initialize(graph)
|
10
|
-
@graph = graph
|
11
|
-
@subcollections = {}
|
12
|
-
@entity_links = []
|
13
|
-
@index_links = []
|
14
|
-
@index = nil
|
15
|
-
end
|
16
|
-
|
17
|
-
# Expand a directory to a collection node representing a collection of entities
|
18
|
-
def expand_directory(policy, node)
|
19
|
-
index = graph.create_node do |collection_node|
|
20
|
-
|
21
|
-
collection_attrs = {
|
22
|
-
name: node.props[:name],
|
23
|
-
title: node.props[:name].capitalize,
|
24
|
-
body: ""
|
25
|
-
}
|
26
|
-
|
27
|
-
populate_collection(collection_node, policy, collection_attrs)
|
28
|
-
end
|
29
|
-
|
30
|
-
# Add this collection id to the lookup table for edge construction
|
31
|
-
@subcollections[node.props[:path]] = index
|
32
|
-
|
33
|
-
# Join the collection to its parent
|
34
|
-
unless node.props[:slug] == policy.collection.to_s || !@subcollections.key?(node.props[:entry].parent.to_s)
|
35
|
-
graph.create_edge do |edge|
|
36
|
-
edge.label = :child
|
37
|
-
edge.from = @subcollections[node.props[:entry].parent.to_s].id
|
38
|
-
edge.to = index.id
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# Extract collection level configuration/metadata from the root node for
|
44
|
-
# this content type.
|
45
|
-
def extract_metadata(node, type)
|
46
|
-
# TODO: support _index or _slug convention as well
|
47
|
-
meta_file = node.out(slug: type.to_s).first
|
48
|
-
|
49
|
-
if meta_file
|
50
|
-
# Process metadata and add it to the collection node
|
51
|
-
# TODO: pass in content converter object
|
52
|
-
# TODO: index/body content by default if extracted from frontmatter
|
53
|
-
body, data = process_content(meta_file.props[:entry])
|
54
|
-
else
|
55
|
-
# Otherwise, assume default collection behaviour
|
56
|
-
data = {}
|
57
|
-
end
|
58
|
-
|
59
|
-
# Generate a default title if not provided in metadata
|
60
|
-
unless data.key?(:title)
|
61
|
-
data[:title] = type.to_s.capitalize
|
62
|
-
end
|
63
|
-
|
64
|
-
data
|
65
|
-
end
|
66
|
-
|
67
|
-
def populate_collection(node, policy, meta_attrs)
|
68
|
-
node.label = :collection
|
69
|
-
node.props[:type] = policy.collection
|
70
|
-
node.props[:resource] = policy.collection_const.new(meta_attrs)
|
71
|
-
end
|
72
|
-
|
73
|
-
def populate_entity(node, policy, meta_attrs)
|
74
|
-
node.label = :item
|
75
|
-
node.props[:type] = policy.entity
|
76
|
-
node.props[:resource] = policy.entity_const.new(meta_attrs)
|
77
|
-
end
|
78
|
-
|
79
|
-
def merge_collection_index(node, policy, meta_attrs)
|
80
|
-
props = { resource: node.props[:resource].merge(meta_attrs) }
|
81
|
-
node.merge_props(props)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Workaround for handling meta and content source in multiple files or a single
|
85
|
-
# file with front matter.
|
86
|
-
def process_content(path)
|
87
|
-
case path.extname
|
88
|
-
when '.htm', '.md'
|
89
|
-
read_split_content(path.to_s, symbolize_keys: true)
|
90
|
-
# when '.md'
|
91
|
-
# body, data = read_split_content(path.to_s, symbolize_keys: true)
|
92
|
-
# [Kramdown::Document.new(body).to_html, data]
|
93
|
-
when '.yml'
|
94
|
-
[nil, YAML.load(File.read(path.to_s), symbolize_names: true)]
|
95
|
-
end
|
96
|
-
# TODO: Raise error if unsupported extname reaches here
|
97
|
-
end
|
98
|
-
|
99
|
-
def connect_expanded_entities
|
100
|
-
# Once all files and directories have been expanded, connect all the child
|
101
|
-
# edges between collections and entities
|
102
|
-
@entity_links.each do |entity_link|
|
103
|
-
graph.create_edge do |edge|
|
104
|
-
edge.label = :child
|
105
|
-
edge.from = entity_link[:parent_id].id
|
106
|
-
edge.to = entity_link[:child_id].id
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
# Merge index page body and metadata with their parent collections
|
111
|
-
@index_links.each do |index_link|
|
112
|
-
merge_collection_index(index_link[:parent_id], policy, index_link[:index_attrs])
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
@@ -1,93 +0,0 @@
|
|
1
|
-
module Yarrow
|
2
|
-
module Content
|
3
|
-
module Expansion
|
4
|
-
class Tree < Strategy
|
5
|
-
def expand(policy)
|
6
|
-
# If match path represents entire content dir, then include the entire
|
7
|
-
# content dir instead of scanning from a subfolder matching the name of
|
8
|
-
# the collection.
|
9
|
-
#start_node = if policy.match_path == "."
|
10
|
-
start_node = if policy.match_path == "."
|
11
|
-
# TODO: match against source_dir
|
12
|
-
graph.n(:root).out(:directory)
|
13
|
-
else
|
14
|
-
graph.n(name: policy.match_path)
|
15
|
-
end
|
16
|
-
|
17
|
-
# Collect all nested collections in the subgraph for this content type
|
18
|
-
@subcollections = {}
|
19
|
-
@entity_links = []
|
20
|
-
@index_links = []
|
21
|
-
@index = nil
|
22
|
-
|
23
|
-
# Scan and collect all nested files from the root
|
24
|
-
start_node.depth_first.each do |node|
|
25
|
-
if node.label == :directory
|
26
|
-
expand_directory(policy, node)
|
27
|
-
elsif node.label == :file
|
28
|
-
expand_file_by_extension(policy, node)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Once all files and directories have been expanded, connect all the child
|
33
|
-
# edges between collections and entities
|
34
|
-
@entity_links.each do |entity_link|
|
35
|
-
graph.create_edge do |edge|
|
36
|
-
edge.label = :child
|
37
|
-
edge.from = entity_link[:parent_id].id
|
38
|
-
edge.to = entity_link[:child_id].id
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# Merge index page body and metadata with their parent collections
|
43
|
-
@index_links.each do |index_link|
|
44
|
-
merge_collection_index(index_link[:parent_id], policy, index_link[:index_attrs])
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def expand_file_by_basename(policy, node)
|
49
|
-
body, meta = process_content(node.props[:entry])
|
50
|
-
meta = {} if !meta
|
51
|
-
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
def expand_file_by_extension(policy, node)
|
56
|
-
body, meta = process_content(node.props[:entry])
|
57
|
-
meta = {} if !meta
|
58
|
-
|
59
|
-
# TODO: document mapping convention for index pages and collection metadata
|
60
|
-
# TODO: underscore _index pattern?
|
61
|
-
bare_basename = node.props[:entry].basename(node.props[:entry].extname)
|
62
|
-
if bare_basename.to_s == "index"
|
63
|
-
@index_links << {
|
64
|
-
parent_id: @subcollections[node.props[:entry].parent.to_s],
|
65
|
-
index_attrs: meta.merge({ body: body})
|
66
|
-
}
|
67
|
-
else
|
68
|
-
# Create an entity node representing a file mapped to a unique content object
|
69
|
-
entity = graph.create_node do |entity_node|
|
70
|
-
|
71
|
-
entity_slug = node.props[:entry].basename(node.props[:entry].extname).to_s
|
72
|
-
|
73
|
-
entity_attrs = {
|
74
|
-
name: entity_slug,
|
75
|
-
title: entity_slug.gsub("-", " ").capitalize,
|
76
|
-
body: body
|
77
|
-
}
|
78
|
-
|
79
|
-
populate_entity(entity_node, policy, entity_attrs.merge(meta || {}))
|
80
|
-
end
|
81
|
-
|
82
|
-
# We may not have an expanded node for the parent collection if this is a
|
83
|
-
# preorder traversal so save it for later
|
84
|
-
@entity_links << {
|
85
|
-
parent_id: @subcollections[node.props[:entry].parent.to_s],
|
86
|
-
child_id: entity
|
87
|
-
}
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|