yarrow 0.8.3 → 0.8.5

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: 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