yarrow 0.9.0 → 0.9.1

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: 96b575b4a93031397d38c09ab442ce577a98378114941c6be3dcaf4c2a71a3ac
4
- data.tar.gz: 15d01eb7b8f710aee890c8879dc202a12ecab3f3cca0030cdc7df8e61619ed75
3
+ metadata.gz: f8f774a7c3013a183129ba27e6929cb1d9cb65f784121f61d3df2c1ffba8a4fb
4
+ data.tar.gz: 7f94b3a971a5fb00d089b6bbad8c12cb724d35f3e00497091130c4731534b275
5
5
  SHA512:
6
- metadata.gz: be90c39d718849c20db481c2f90d105400af237c7232d4cdd091e7260fffe3d09e4828c4d50f473424daa1d223d2cf5259ed55f4120534ad884ea7ca4d2124dc
7
- data.tar.gz: b4e5150cd8a3da147489fe0f8077520df328ae2fc5018e4ea102ca171625ada864da3a08aeb59860a98d04b7515e8f0868a023f85fb10c1718592a066d818b1b
6
+ metadata.gz: de66835c7de07c4c84802a8adf75e57d637c4865f7a7e2f1f42f06ac0a22adbadfd067c812a6ba8a5be7e8fa03f116173f1a47777c550d38004e0683c6395685
7
+ data.tar.gz: a7aff55ba63ed7cc2b493b28dd27f415c985bd55730de71732411c2d3500ee0beb0dd21a599b7110599dfb80253bef6b4204a70276b4ed794cf0f2884d3149a1
data/.gitignore CHANGED
@@ -10,3 +10,4 @@ bin/scripts
10
10
  /www
11
11
  /web
12
12
  /docs
13
+ _*.md
@@ -12,13 +12,13 @@ module Yarrow
12
12
  def before_traversal(policy)
13
13
  end
14
14
 
15
- def expand_container(container, policy)
15
+ def expand_source(container, policy)
16
16
  end
17
17
 
18
- def expand_collection(collection, policy)
18
+ def expand_directory(collection, policy)
19
19
  end
20
20
 
21
- def expand_entity(entity, policy)
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].capitalize,
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 expand_container(container, policy)
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 expand_collection(collection, policy)
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 expand_entity(entity, policy)
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
@@ -2,17 +2,17 @@ module Yarrow
2
2
  module Content
3
3
  module Expansion
4
4
  class DirectoryMap < Aggregator
5
- def expand_container(container, policy)
5
+ def expand_source(container, policy)
6
6
  puts "create_node label=:collection type=:#{policy.container} name='#{container.props[:basename]}'"
7
7
  @current_collection = container.props[:basename]
8
8
  end
9
9
 
10
- def expand_collection(collection, policy)
10
+ def expand_directory(collection, policy)
11
11
  puts "create_node label=:collection type=:#{policy.collection} name='#{collection.props[:basename]}' collection=#{@current_collection}"
12
12
  @current_collection = collection.props[:basename]
13
13
  end
14
14
 
15
- def expand_entity(entity, policy)
15
+ def expand_file(entity, policy)
16
16
  puts "create_node label=:entity type=:#{policy.entity} name='#{entity.props[:basename]}' collection='#{@current_collection}"
17
17
  end
18
18
  end
@@ -8,16 +8,16 @@ module Yarrow
8
8
  @current_entity = nil
9
9
  end
10
10
 
11
- def expand_container(container, policy)
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 expand_collection(collection, policy)
16
+ def expand_directory(collection, policy)
17
17
  @current_entity = collection.props[:basename]
18
18
  end
19
19
 
20
- def expand_entity(entity, policy)
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 expand_container(container, policy)
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 expand_collection(collection, policy)
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 expand_entity(entity, policy)
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 on_root_visited(root_node)
25
- aggregator.expand_container(root_node, policy)
24
+ def visit_source(root_node)
25
+ aggregator.expand_source(root_node, policy)
26
26
  end
27
27
 
28
- def on_directory_visited(dir_node)
28
+ def visit_directory(dir_node)
29
29
  # TODO: match on potential directory extension/filter
30
- aggregator.expand_collection(dir_node, policy)
30
+ aggregator.expand_directory(dir_node, policy)
31
31
  end
32
32
 
33
- def on_file_visited(file_node)
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.expand_entity(file_node, policy)
36
+ aggregator.expand_file(file_node, policy)
37
37
  end
38
38
 
39
- def on_traversal_initiated
39
+ def start_traversal
40
40
  aggregator.before_traversal(policy)
41
41
  end
42
42
 
43
- def on_traversal_completed
43
+ def complete_traversal
44
44
  aggregator.after_traversal(policy)
45
45
  end
46
46
 
47
47
  def expand
48
- on_traversal_initiated
48
+ start_traversal
49
49
 
50
50
  traversal = source_node.depth_first.each
51
51
 
52
- on_root_visited(traversal.next)
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 on_directory_visited(node)
58
- when :file then on_file_visited(node)
57
+ when :directory then visit_directory(node)
58
+ when :file then visit_file(node)
59
59
  end
60
60
  end
61
61
 
62
- on_traversal_completed
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)
@@ -1,6 +1,6 @@
1
1
  module Yarrow
2
2
  module Format
3
- class Markdown < ContentType[".md", ".markdown"]
3
+ class Markdown < ContentType[".md", ".markdown", ".htm"]
4
4
  include Methods::FrontMatter
5
5
 
6
6
  def initialize(source)
@@ -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 = read_yfm(path)
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
+ TOML::Parser.new(raw).parsed
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
@@ -5,7 +5,7 @@ module Yarrow
5
5
 
6
6
  def initialize(document, metadata)
7
7
  @document = document
8
- @metadata = metadata
8
+ @metadata = metadata || {}
9
9
  end
10
10
  end
11
11
 
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module Yarrow
3
3
  APP_NAME = "Yarrow"
4
- VERSION = "0.9.0"
4
+ VERSION = "0.9.1"
5
5
  end
@@ -40,7 +40,8 @@ module Yarrow
40
40
  file.puts(content)
41
41
  end
42
42
 
43
- puts "[write] #{path} → #{url}"
43
+ # If stdout logging
44
+ #puts "[write] #{path} → #{url}"
44
45
  end
45
46
 
46
47
  def generate_sitemap(manifest)
@@ -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
@@ -1,6 +1,7 @@
1
1
  require "pathname"
2
2
  require "yaml"
3
3
  require "kramdown"
4
+ require "toml"
4
5
  require "mustache"
5
6
  require "parallel"
6
7
 
data/yarrow.gemspec CHANGED
@@ -24,6 +24,7 @@ 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
+ spec.add_runtime_dependency 'toml', '~> 0.3.0'
27
28
  # https://github.com/joeldrapper/phlex
28
29
  spec.add_runtime_dependency 'kramdown', '~> 2.4.0'
29
30
  spec.add_development_dependency 'rake', '~> 13.0'
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.0
4
+ version: 0.9.1
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-04-10 00:00:00.000000000 Z
11
+ date: 2023-09-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0.3'
167
+ - !ruby/object:Gem::Dependency
168
+ name: toml
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: 0.3.0
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: 0.3.0
167
181
  - !ruby/object:Gem::Dependency
168
182
  name: kramdown
169
183
  requirement: !ruby/object:Gem::Requirement