yarrow 0.8.3 → 0.8.5

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: b4319be245b1b70240d28422cf095d64bb61bdacf1b95c545cd055ed7c9e645b
4
- data.tar.gz: 1c0fc21f3536a09dd5c11a1c359ce11ab128ea9c527f002a6e6a777090848173
3
+ metadata.gz: 33fcaf7b1d66e43c0bd0a83967d0cc8b4891b96ec652bbfd28e5e91e7991b7e2
4
+ data.tar.gz: ccf4513eee11929864f76386e22adf39224a1898f5b207a3cefb11a30a5ed6e7
5
5
  SHA512:
6
- metadata.gz: 0c3d3176870c6bc82695a825bfa7dc46908311200a35722142620e2fdfd5ce60ea795ef03b88ee35c206379e9f382bab41e0cd38f96d5cc261ba0578d7fe51ed
7
- data.tar.gz: 3d8b4f4acb48ef94dc75b65ebda43c5a0d0e588679688b090a6ebaba6c5bccc7f7610793d60663a2e7c5cdd6fcdc213be989f064ac8d9092f6dfd191a0b38b90
6
+ metadata.gz: 20272c169c2dd1280c06b80277a981217ae08c77c80892b4c8d07bac0564099ea0cbc248d54ac3160522e7e38c7dbe129aa703e6cb9e9cb848619f2009e15273
7
+ data.tar.gz: 143a1bbb91909f1e8921b9b587f611293b2f20de9f50d66b18a7346c00e6ebc2078d98ac0e9abcb88cad258e2f3a2d902f1f2eda811d27abd0348ece8f7cf87e
@@ -21,4 +21,11 @@ module Mementus
21
21
  "nodes_count=#{nodes_count} edges_count=#{edges_count}>"
22
22
  end
23
23
  end
24
+
25
+ class Node
26
+ def merge_props(data)
27
+ next_props = props.merge(data)
28
+ @props = next_props.freeze
29
+ end
30
+ end
24
31
  end
@@ -34,6 +34,23 @@ module Yarrow
34
34
  data
35
35
  end
36
36
 
37
+ def populate_collection(node, policy, meta_attrs)
38
+ node.label = :collection
39
+ node.props[:type] = policy.collection
40
+ node.props[:resource] = policy.collection_const.new(meta_attrs)
41
+ end
42
+
43
+ def populate_entity(node, policy, meta_attrs)
44
+ node.label = :item
45
+ node.props[:type] = policy.entity
46
+ node.props[:resource] = policy.entity_const.new(meta_attrs)
47
+ end
48
+
49
+ def merge_collection_index(node, policy, meta_attrs)
50
+ props = { resource: node.props[:resource].merge(meta_attrs) }
51
+ node.merge_props(props)
52
+ end
53
+
37
54
  # Workaround for handling meta and content source in multiple files or a single
38
55
  # file with front matter.
39
56
  def process_content(path)
@@ -21,11 +21,12 @@ module Yarrow
21
21
  end
22
22
 
23
23
  # Extract metadata from given start node
24
- collection_metadata = extract_metadata(start_node, policy.container)
24
+ #collection_metadata = extract_metadata(start_node, policy.container)
25
25
 
26
26
  # Collect all nested collections in the subgraph for this content type
27
27
  subcollections = {}
28
- item_links = []
28
+ entity_links = []
29
+ index_links = []
29
30
  index = nil
30
31
 
31
32
  # Scan and collect all nested files from the root
@@ -33,12 +34,14 @@ module Yarrow
33
34
  if node.label == :directory
34
35
  # Create a collection node representing a collection of documents
35
36
  index = graph.create_node do |collection_node|
36
- collection_node.label = :collection
37
- collection_node.props[:type] = policy.container
38
- collection_node.props[:name] = node.props[:name]
39
37
 
40
- # TODO: title needs to be defined from metadata
41
- collection_node.props[:title] = node.props[:name].capitalize
38
+ collection_attrs = {
39
+ name: node.props[:name],
40
+ title: node.props[:name].capitalize,
41
+ body: ""
42
+ }
43
+
44
+ populate_collection(collection_node, policy, collection_attrs)
42
45
  end
43
46
 
44
47
  # Add this collection id to the lookup table for edge construction
@@ -54,38 +57,55 @@ module Yarrow
54
57
  end
55
58
  elsif node.label == :file
56
59
  body, meta = process_content(node.props[:entry])
60
+ meta = {} if !meta
57
61
 
58
- # Create an item node representing a file mapped to a unique content object
59
- item = graph.create_node do |item_node|
60
- item_node.label = :item
61
- item_node.props[:type] = policy.entity
62
- item_node.props[:name] = node.props[:entry].basename(node.props[:entry].extname).to_s
63
- item_node.props[:body] = body if body
64
- item_node.props[:title] = meta[:title] if meta
65
- # TODO: better handling of metadata on node props
66
-
67
- # TODO: new schema edits go here
68
- #puts policy.entity_const
69
- end
62
+ # TODO: document mapping convention for index pages and collection metadata
63
+ # TODO: underscore _index pattern?
64
+ bare_basename = node.props[:entry].basename(node.props[:entry].extname)
65
+ if bare_basename.to_s == "index"
66
+ index_links << {
67
+ parent_id: subcollections[node.props[:entry].parent.to_s],
68
+ index_attrs: meta.merge({ body: body})
69
+ }
70
+ else
71
+ # Create an entity node representing a file mapped to a unique content object
72
+ entity = graph.create_node do |entity_node|
73
+
74
+ entity_slug = node.props[:entry].basename(node.props[:entry].extname).to_s
70
75
 
71
- # We may not have an expanded node for the parent collection if this is a
72
- # preorder traversal so save it for later
73
- item_links << {
74
- parent_path: node.props[:entry].parent.to_s,
75
- item_id: item.id
76
- }
76
+ entity_attrs = {
77
+ name: entity_slug,
78
+ title: entity_slug.gsub("-", " ").capitalize,
79
+ body: body
80
+ }
81
+
82
+ populate_entity(entity_node, policy, entity_attrs.merge(meta || {}))
83
+ end
84
+
85
+ # We may not have an expanded node for the parent collection if this is a
86
+ # preorder traversal so save it for later
87
+ entity_links << {
88
+ parent_id: subcollections[node.props[:entry].parent.to_s],
89
+ child_id: entity
90
+ }
91
+ end
77
92
  end
78
93
  end
79
94
 
80
95
  # Once all files and directories have been expanded, connect all the child
81
- # edges between collections and items
82
- item_links.each do |item_link|
96
+ # edges between collections and entities
97
+ entity_links.each do |entity_link|
83
98
  graph.create_edge do |edge|
84
99
  edge.label = :child
85
- edge.from = subcollections[item_link[:parent_path]].id
86
- edge.to = item_link[:item_id]
100
+ edge.from = entity_link[:parent_id].id
101
+ edge.to = entity_link[:child_id].id
87
102
  end
88
103
  end
104
+
105
+ # Merge index page body and metadata with their parent collections
106
+ index_links.each do |index_link|
107
+ merge_collection_index(index_link[:parent_id], policy, index_link[:index_attrs])
108
+ end
89
109
  end
90
110
  end
91
111
  end
@@ -81,6 +81,9 @@ module Yarrow
81
81
  @container_const ||= Yarrow::Symbols.to_module_const([*module_prefix, container])
82
82
  end
83
83
 
84
+ alias_method :collection, :container
85
+ alias_method :collection_const, :container_const
86
+
84
87
  def entity_const
85
88
  @entity_const ||= Yarrow::Symbols.to_module_const([*module_prefix, entity])
86
89
  end
@@ -58,7 +58,7 @@ module Yarrow
58
58
  end
59
59
  end
60
60
 
61
- private
61
+ #private
62
62
 
63
63
  attr_reader :config, :workflow
64
64
 
@@ -8,7 +8,8 @@ module Yarrow
8
8
  path: Types::Instance.of(Pathname).accept(String),
9
9
  any: Types::Any.new,
10
10
  array: Types::List.of(Types::Any),
11
- hash: Types::Instance.of(Hash)
11
+ hash: Types::Instance.of(Hash),
12
+ markdown: Types::Instance.of(Kramdown::Document).accept(String)
12
13
  }
13
14
 
14
15
  TEMPLATE_TYPES = {
@@ -28,13 +28,13 @@ module Yarrow
28
28
 
29
29
  if missing_attrs.any?
30
30
  missing_attrs.each do |name|
31
- raise "wrong number of attributes" unless @attrs_spec[name].is_a?(Types::Any)
31
+ raise "#{missing_attrs} wrong number of attributes" unless @attrs_spec[name].is_a?(Types::Any)
32
32
  end
33
33
  end
34
34
 
35
35
  mismatching_attrs = input.keys.difference(@attrs_spec.keys)
36
36
 
37
- raise "attribute does not exist" if mismatching_attrs.any?
37
+ raise "attribute #{mismatching_attrs} does not exist" if mismatching_attrs.any?
38
38
 
39
39
  input.reduce({}) do |converted, (name, value)|
40
40
  converted[name] = @attrs_spec[name].cast(value)
@@ -59,7 +59,7 @@ module Yarrow
59
59
  end
60
60
 
61
61
  def merge(other)
62
- unless other.is_a?(self.class)
62
+ unless other.is_a?(self.class) || other.is_a?(Hash)
63
63
  raise ArgumentError.new("cannot merge entities that are not the same type")
64
64
  end
65
65
 
@@ -31,8 +31,13 @@ module Yarrow
31
31
  @accepts = {}
32
32
  end
33
33
 
34
- def accept(type, constructor=:new)
35
- accepts[type] = constructor
34
+ def accept(type, constructor=:new, options=nil)
35
+ accepts[type] = if options.nil?
36
+ [constructor]
37
+ else
38
+ [constructor, options]
39
+ end
40
+
36
41
  self
37
42
  end
38
43
 
@@ -41,8 +46,14 @@ module Yarrow
41
46
  end
42
47
 
43
48
  def coerce(input)
44
- constructor = accepts[input.class]
45
- unit.send(constructor, input)
49
+ constructor, options = accepts[input.class]
50
+
51
+ # TODO: should we clone all input so copy is stored rather than ref?
52
+ if options.nil?
53
+ unit.send(constructor, input)
54
+ else
55
+ unit.send(constructor, input, options.clone)
56
+ end
46
57
  end
47
58
 
48
59
  def check_instance_of!(input)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module Yarrow
3
3
  APP_NAME = "Yarrow"
4
- VERSION = "0.8.3"
4
+ VERSION = "0.8.5"
5
5
  end
@@ -6,35 +6,75 @@ module Yarrow
6
6
  # too clever which has burned this lib in the past).
7
7
  def initialize(item, parent, is_index)
8
8
  @item = item
9
+ @resource = item.props[:resource]
9
10
  @parent = parent
10
11
  @is_index = is_index
11
12
  end
12
13
 
14
+ def resource
15
+ @resource
16
+ end
17
+
18
+ def index
19
+ _index = @item.out_e(:index)
20
+ unless _index.first.nil?
21
+ _index.first.to.props
22
+ else
23
+ nil
24
+ end
25
+ end
26
+
27
+ def index_body
28
+ @item.props[:index_body]
29
+ end
30
+
31
+ # TODO: manage behaviour with and without current item
32
+ # TODO: link to manifest
33
+ def breadcrumbs
34
+ path = []
35
+
36
+ current_parent = @item.in(:collection)
37
+
38
+ while !current_parent.first.nil?
39
+ path << current_parent.first.props[:resource]
40
+ current_parent = current_parent.in(:collection)
41
+ end
42
+
43
+ path.reverse
44
+ end
45
+
13
46
  def name
14
- @item.props[:name]
47
+ @resource.name
15
48
  end
16
49
 
17
50
  def title
18
- @item.props[:title]
51
+ @resource.title
19
52
  end
20
53
 
21
54
  def type
22
55
  @item.props[:type]
23
56
  end
24
57
 
58
+ def body
59
+ return @resource.body.to_html if @resource.respond_to?(:body)
60
+ ""
61
+ end
62
+
25
63
  def url
26
64
  if @parent.nil?
27
65
  "/"
28
66
  else
29
- segments = [@item.props[:name]]
67
+ segments = [@resource.name]
30
68
  current = @parent
31
69
 
32
70
  until current.in(:collection).first.nil? do
33
- segments << current.props[:name]
71
+ segments << current.props[:resource].name
34
72
  current = current.in(:collection).first
35
73
  end
36
74
 
37
- "/" + segments.reverse.join("/")
75
+ suffix = @is_index ? "/" : ""
76
+
77
+ "/" + segments.reverse.join("/") + suffix
38
78
  end
39
79
  end
40
80
  end
@@ -12,7 +12,7 @@ module Yarrow
12
12
  unless collection.props[:index_only]
13
13
  collection.out(:item).each do |item|
14
14
  #if item[:entity].status.to_sym == :published
15
- if item.props[:name] == "index"
15
+ if item.props[:resource].name == "index"
16
16
  index = item
17
17
  else
18
18
  manifest.add_document(item_context(item))
@@ -25,7 +25,7 @@ module Yarrow
25
25
  unless collection.props[:content_only]
26
26
  if index
27
27
  manifest.add_document(collection_index_context(collection, index))
28
- else
28
+ else
29
29
  manifest.add_document(collection_context(collection))
30
30
  end
31
31
  end
data/lib/yarrow.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "pathname"
2
2
  require "yaml"
3
+ require "kramdown"
3
4
  require "mustache"
4
5
  require "parallel"
5
6
 
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.8.3
4
+ version: 0.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Rickerby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-07 00:00:00.000000000 Z
11
+ date: 2022-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable