yarrow 0.9.3 → 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -7
- data/lib/yarrow/config.rb +73 -10
- data/lib/yarrow/configuration.rb +5 -18
- data/lib/yarrow/content/collection.rb +7 -0
- data/lib/yarrow/content/expansion/aggregator.rb +3 -3
- data/lib/yarrow/content/expansion/filename_map.rb +1 -1
- data/lib/yarrow/content/policy.rb +48 -42
- data/lib/yarrow/defaults.yml +15 -2
- data/lib/yarrow/output/build.rb +37 -0
- data/lib/yarrow/schema/definitions.rb +1 -1
- data/lib/yarrow/schema/dictionary.rb +3 -2
- data/lib/yarrow/schema/entity.rb +10 -2
- data/lib/yarrow/schema/types.rb +63 -33
- data/lib/yarrow/version.rb +1 -1
- data/lib/yarrow/web/document.rb +22 -1
- data/lib/yarrow/web/manifest.rb +22 -0
- data/lib/yarrow/web/url.rb +29 -0
- data/lib/yarrow.rb +3 -2
- metadata +5 -9
- data/lib/yarrow/assets/manifest.rb +0 -118
- data/lib/yarrow/assets/pipeline.rb +0 -126
- data/lib/yarrow/assets.rb +0 -2
- data/lib/yarrow/output/context.rb +0 -16
- data/lib/yarrow/output/web/indexed_file.rb +0 -45
- data/lib/yarrow/source/graph.rb +0 -6
- data/lib/yarrow/tools/front_matter.rb +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9312b361a125e332c4283433f1b26d29eda2a66c19b08023778eb77ea4b7e297
|
4
|
+
data.tar.gz: 04d6809bb61575cb508b0abb87de095e5bc8c861261177558eb602c95f6913a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c9869456f8255277347e442693d68e894b4af657f82ecba0024a9b3d624cfd4393e83f30f4e98f8cb3897bbbc36c15fcd564060fc940a0de727c193f38ceb3b
|
7
|
+
data.tar.gz: 6ed205652f8a844e87d6c9c5c447d34a65e7e26bfcdc661b742ff26079796082b8b1fcf7fd7d521d37885f79ea83342dcf07e605e64ee5d84d1a8a447d556266
|
data/README.md
CHANGED
@@ -29,7 +29,7 @@ gem 'yarrow'
|
|
29
29
|
Status
|
30
30
|
------
|
31
31
|
|
32
|
-
Yarrow is an extraction from several existing private documentation projects. This repo is in alpha state, which means that many of the useful features are not yet folded into this codebase.
|
32
|
+
Yarrow is an extraction from several existing private documentation projects. ~~This repo is in alpha state, which means that many of the useful features are not yet folded into this codebase.~~ This repo is in flux as it is being used on several live projects, but lacks documentation and a unified command line tool.
|
33
33
|
|
34
34
|
Yarrow is being slowly developed as a part-time project to scratch a few itches. New features and bugfixes are pushed straight to `main`, and releases of the Gem are kept more or less in sync with the planned roadmap.
|
35
35
|
|
@@ -40,12 +40,15 @@ A rough sketch of the project direction.
|
|
40
40
|
|
41
41
|
| Version | Features |
|
42
42
|
|---------|-------------------------------------------------|
|
43
|
-
| `0.
|
44
|
-
| `0.
|
45
|
-
| `0.
|
46
|
-
| `0.
|
47
|
-
| `0.
|
48
|
-
| `
|
43
|
+
| `0.10` | Filename map expansion strategy |
|
44
|
+
| `0.11` | Directory merge expansion strategy |
|
45
|
+
| `0.12` | Basename merge expansion strategy |
|
46
|
+
| `0.13` | Resources and Assets vocabulary |
|
47
|
+
| `0.14` | Flatten namespaces and clean up modules |
|
48
|
+
| `0.15` | Web template mapping and markup generators |
|
49
|
+
| `0.16` | Document custom Markdown components |
|
50
|
+
| `0.17` | Publishing support for S3 and GitHub/Netlify |
|
51
|
+
| `0.18` | Clean up local web server and watcher |
|
49
52
|
|
50
53
|
License
|
51
54
|
-------
|
data/lib/yarrow/config.rb
CHANGED
@@ -10,11 +10,11 @@ module Yarrow
|
|
10
10
|
# For larger web publishing projects, this should be moved out into a
|
11
11
|
# template context or language/translation files to make it editable
|
12
12
|
# for a larger group of people.
|
13
|
-
Meta
|
14
|
-
:title,
|
15
|
-
:author
|
13
|
+
class Meta < Yarrow::Schema::Entity
|
14
|
+
attribute :title, :string
|
15
|
+
attribute :author, :string
|
16
16
|
# :copyright TODO: what other basic details to include?
|
17
|
-
|
17
|
+
end
|
18
18
|
|
19
19
|
# Dev server config. This is mainly useful if you want to set up a specific
|
20
20
|
# chain of Rack middleware and handlers. If you don’t care about default
|
@@ -52,27 +52,90 @@ module Yarrow
|
|
52
52
|
# :__config_source_map,
|
53
53
|
# Yarrow::Schema::Types::Map.of(Symbol)
|
54
54
|
# )
|
55
|
-
|
56
55
|
class Content < Yarrow::Schema::Entity
|
57
56
|
attribute :module, :string
|
58
57
|
#attribute :source_map, :__config_source_map
|
59
58
|
attribute :source_map, :hash
|
60
59
|
end
|
60
|
+
|
61
|
+
# Template engine and site generator configuration block
|
62
|
+
class OutputGenerator < Yarrow::Schema::Entity
|
63
|
+
attribute :engine, :string
|
64
|
+
attribute :template_dir, :string
|
65
|
+
attribute :options, :hash
|
66
|
+
end
|
67
|
+
|
68
|
+
# Document mapping configuration block
|
69
|
+
class OutputManifest < Yarrow::Schema::Entity
|
70
|
+
attribute :layout, :string
|
71
|
+
attribute :scheme, :string
|
72
|
+
|
73
|
+
DEFAULT_URL_SCHEME = "/{ancestors*}"
|
74
|
+
|
75
|
+
def self.from_spec(input, context)
|
76
|
+
attrs = {}
|
77
|
+
|
78
|
+
if input.is_a?(TrueClass)
|
79
|
+
attrs[:layout] = context[:key].to_s
|
80
|
+
elsif input.is_a?(FalseClass)
|
81
|
+
raise "Reconciliation for content type #{context[:key]} cannot be skipped (yet)"
|
82
|
+
elsif input.is_a?(Symbol)
|
83
|
+
attrs[:layout] = input.to_s
|
84
|
+
elsif input.is_a?(String)
|
85
|
+
attrs[:layout] = context[:key].to_s
|
86
|
+
attrs[:scheme] = input
|
87
|
+
elsif input.is_a?(Hash)
|
88
|
+
attrs = input
|
89
|
+
else
|
90
|
+
raise "Invalid data for output manifest: #{input.class}"
|
91
|
+
end
|
92
|
+
|
93
|
+
unless attrs.key?(:scheme)
|
94
|
+
attrs[:scheme] = DEFAULT_URL_SCHEME
|
95
|
+
end
|
96
|
+
|
97
|
+
new(attrs)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Define output document map type
|
102
|
+
Yarrow::Schema::Definitions.register(
|
103
|
+
:yarrow_config_output_manifest_spec,
|
104
|
+
Yarrow::Schema::Types::Map.of(Symbol => OutputManifest).accept_elements(Hash)
|
105
|
+
.accept_elements(TrueClass, :from_spec)
|
106
|
+
.accept_elements(FalseClass, :from_spec)
|
107
|
+
.accept_elements(Symbol, :from_spec)
|
108
|
+
.accept_elements(String, :from_spec)
|
109
|
+
)
|
110
|
+
|
111
|
+
# Manifest reconciliation configuration block
|
112
|
+
class OutputReconcile < Yarrow::Schema::Entity
|
113
|
+
attribute :match, :string
|
114
|
+
attribute :manifest, :yarrow_config_output_manifest_spec
|
115
|
+
end
|
61
116
|
|
117
|
+
# Output configuration block
|
62
118
|
class Output < Yarrow::Schema::Entity
|
63
|
-
attribute :
|
64
|
-
attribute :
|
65
|
-
|
119
|
+
attribute :target, :string
|
120
|
+
attribute :generator, :yarrow_config_output_generator
|
121
|
+
attribute :reconcile, :yarrow_config_output_reconcile
|
66
122
|
end
|
67
123
|
|
124
|
+
# Define output schema list type
|
125
|
+
Yarrow::Schema::Definitions.register(
|
126
|
+
:yarrow_config_output_list,
|
127
|
+
Yarrow::Schema::Types::List.of(Output).accept_elements(Hash)
|
128
|
+
)
|
129
|
+
|
68
130
|
# Top level root config namespace.
|
69
131
|
class Instance < Yarrow::Schema::Entity
|
70
132
|
attribute :source_dir, :path
|
71
133
|
attribute :output_dir, :path
|
72
|
-
attribute :meta, :
|
134
|
+
attribute :meta, :yarrow_config_meta
|
73
135
|
attribute :server, :any
|
74
136
|
attribute :content, :yarrow_config_content
|
75
|
-
attribute :output, :
|
137
|
+
attribute :output, :yarrow_config_output_list
|
138
|
+
#attribute :output, :any
|
76
139
|
end
|
77
140
|
#
|
78
141
|
# `content_dir` and `output_dir` are placeholders and should be overriden
|
data/lib/yarrow/configuration.rb
CHANGED
@@ -1,21 +1,11 @@
|
|
1
1
|
module Yarrow
|
2
2
|
class Configuration
|
3
3
|
class << self
|
4
|
-
# Merges the given configuration or hash-like object with the
|
5
|
-
# registered global configuration.
|
6
|
-
#
|
7
|
-
# @param [Hash, Hashie::Mash, Yarrow::Configuration]
|
8
|
-
#
|
9
|
-
def merge(config)
|
10
|
-
instance.deep_merge!(config)
|
11
|
-
end
|
12
|
-
|
13
4
|
# Loads a configuration object from the given YAML file.
|
14
5
|
#
|
15
6
|
# @param [String] path to YAML file
|
16
7
|
#
|
17
8
|
# @return [Yarrow::Config]
|
18
|
-
#
|
19
9
|
def load(file)
|
20
10
|
coerce_config_struct(YAML.load(File.read(file), symbolize_names: true))
|
21
11
|
end
|
@@ -34,12 +24,9 @@ module Yarrow
|
|
34
24
|
# TODO: this should be folded into the schema machinery with type coercions
|
35
25
|
def coerce_config_struct(config)
|
36
26
|
meta_obj = if config.key?(:meta)
|
37
|
-
|
38
|
-
title: config[:meta][:title],
|
39
|
-
author: config[:meta][:author]
|
40
|
-
)
|
27
|
+
config[:meta]
|
41
28
|
else
|
42
|
-
|
29
|
+
raise "missing :meta key in config"
|
43
30
|
end
|
44
31
|
|
45
32
|
server_obj = if config.key?(:server)
|
@@ -49,7 +36,7 @@ module Yarrow
|
|
49
36
|
end
|
50
37
|
|
51
38
|
content_obj = if config.key?(:content)
|
52
|
-
|
39
|
+
config[:content]
|
53
40
|
else
|
54
41
|
Yarrow::Config::Content.new({
|
55
42
|
module: "",
|
@@ -60,9 +47,9 @@ module Yarrow
|
|
60
47
|
end
|
61
48
|
|
62
49
|
output_obj = if config.key?(:output)
|
63
|
-
|
50
|
+
config[:output]
|
64
51
|
else
|
65
|
-
|
52
|
+
raise "missing :output key in config"
|
66
53
|
end
|
67
54
|
|
68
55
|
# TODO: messy hack to get rid of Hashie::Mash, this should either be
|
@@ -36,7 +36,7 @@ module Yarrow
|
|
36
36
|
}
|
37
37
|
collection_node.label = :collection
|
38
38
|
collection_node.props[:type] = type
|
39
|
-
collection_node.props[:
|
39
|
+
collection_node.props[:collection] = collection_const.new(attributes)
|
40
40
|
end
|
41
41
|
|
42
42
|
# Add this collection id to the lookup table for edge construction
|
@@ -52,7 +52,7 @@ module Yarrow
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
def
|
55
|
+
def create_resource(source_node, parent_path, type, entity_const)
|
56
56
|
contents = Yarrow::Format.read(source_node.props[:path])
|
57
57
|
|
58
58
|
# Create an entity node with attached resource model
|
@@ -63,7 +63,7 @@ module Yarrow
|
|
63
63
|
body: contents.document.to_s
|
64
64
|
}.merge(contents.metadata)
|
65
65
|
|
66
|
-
entity_node.label = :
|
66
|
+
entity_node.label = :resource
|
67
67
|
entity_node.props[:type] = type
|
68
68
|
entity_node.props[:resource] = entity_const.new(attributes)
|
69
69
|
end
|
@@ -15,7 +15,7 @@ module Yarrow
|
|
15
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_resource(entity, parent_path, policy.entity, policy.entity_const)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -1,40 +1,53 @@
|
|
1
|
+
Yarrow::Schema::Definitions.register(:extension_list, Yarrow::Schema::Types::List.of(String))
|
2
|
+
|
1
3
|
module Yarrow
|
2
4
|
module Content
|
3
|
-
class Policy
|
5
|
+
class Policy < Yarrow::Schema::Entity
|
6
|
+
# TODO: document meaning and purpose of each attribute
|
7
|
+
attribute :container, :symbol
|
8
|
+
attribute :collection, :symbol
|
9
|
+
attribute :entity, :symbol
|
10
|
+
attribute :expansion, :symbol
|
11
|
+
attribute :extensions, :extension_list
|
12
|
+
attribute :source_path, :string
|
13
|
+
attribute :module_prefix, :string
|
14
|
+
|
4
15
|
DEFAULT_EXPANSION = :filename_map
|
5
16
|
|
6
17
|
DEFAULT_EXTENSIONS = [".md", ".yml", ".htm"]
|
7
18
|
|
8
19
|
DEFAULT_SOURCE_PATH = "."
|
9
20
|
|
21
|
+
DEFAULT_MODULE_PREFIX = ""
|
22
|
+
|
10
23
|
MODULE_SEPARATOR = "::"
|
11
24
|
|
12
25
|
# Construct a content policy from the given source specification.
|
13
|
-
def self.from_spec(policy_label, policy_props, module_prefix=
|
26
|
+
def self.from_spec(policy_label, policy_props=DEFAULT_SOURCE_PATH, module_prefix=DEFAULT_MODULE_PREFIX)
|
14
27
|
# TODO: validate length, structure etc
|
15
28
|
|
16
29
|
# If the spec holds a symbol value then treat it as an entity mapping
|
17
30
|
if policy_props.is_a?(Symbol)
|
18
|
-
new(
|
19
|
-
policy_label,
|
20
|
-
policy_label,
|
21
|
-
policy_props,
|
22
|
-
DEFAULT_EXPANSION,
|
23
|
-
DEFAULT_EXTENSIONS,
|
24
|
-
policy_label.to_s,
|
25
|
-
module_prefix
|
26
|
-
)
|
31
|
+
new({
|
32
|
+
container: policy_label,
|
33
|
+
collection: policy_label,
|
34
|
+
entity: policy_props,
|
35
|
+
expansion: DEFAULT_EXPANSION,
|
36
|
+
extensions: DEFAULT_EXTENSIONS,
|
37
|
+
source_path: policy_label.to_s,
|
38
|
+
module_prefix: module_prefix
|
39
|
+
})
|
27
40
|
|
28
41
|
# If the spec holds a string value then treat it as a source path mapping
|
29
42
|
elsif policy_props.is_a?(String)
|
30
43
|
new(
|
31
|
-
policy_label,
|
32
|
-
policy_label,
|
33
|
-
Yarrow::Symbols.to_singular(policy_label),
|
34
|
-
DEFAULT_EXPANSION,
|
35
|
-
DEFAULT_EXTENSIONS,
|
36
|
-
policy_props,
|
37
|
-
module_prefix
|
44
|
+
container: policy_label,
|
45
|
+
collection: policy_label,
|
46
|
+
entity: Yarrow::Symbols.to_singular(policy_label),
|
47
|
+
expansion: DEFAULT_EXPANSION,
|
48
|
+
extensions: DEFAULT_EXTENSIONS,
|
49
|
+
source_path: policy_props,
|
50
|
+
module_prefix: module_prefix
|
38
51
|
)
|
39
52
|
|
40
53
|
# Otherwise scan through the spec and fill in any gaps
|
@@ -43,7 +56,8 @@ module Yarrow
|
|
43
56
|
collection = if policy_props.key?(:collection)
|
44
57
|
policy_props[:collection]
|
45
58
|
else
|
46
|
-
# If an entity name is provided use its plural for the container name
|
59
|
+
# If an entity name is provided use its plural for the container name.
|
60
|
+
# Otherwise fall back to a container name or policy label.
|
47
61
|
if policy_props.key?(:entity)
|
48
62
|
Yarrow::Symbols.to_plural(policy_props[:entity])
|
49
63
|
else
|
@@ -51,7 +65,7 @@ module Yarrow
|
|
51
65
|
end
|
52
66
|
end
|
53
67
|
|
54
|
-
# Use explicit container name if provided
|
68
|
+
# Use explicit container name if provided. Otherwise fall back to the collection name.
|
55
69
|
container = if policy_props.key?(:container)
|
56
70
|
policy_props[:container]
|
57
71
|
else
|
@@ -91,44 +105,36 @@ module Yarrow
|
|
91
105
|
end
|
92
106
|
|
93
107
|
# Construct the new policy
|
94
|
-
new(
|
95
|
-
container,
|
96
|
-
collection,
|
97
|
-
entity,
|
98
|
-
expansion,
|
99
|
-
extensions,
|
100
|
-
source_path,
|
101
|
-
module_prefix
|
102
|
-
)
|
108
|
+
new({
|
109
|
+
container: container,
|
110
|
+
collection: collection,
|
111
|
+
entity: entity,
|
112
|
+
expansion: expansion,
|
113
|
+
extensions: extensions,
|
114
|
+
source_path: source_path,
|
115
|
+
module_prefix: module_prefix
|
116
|
+
})
|
103
117
|
end
|
104
118
|
end
|
105
119
|
|
106
|
-
|
107
|
-
|
108
|
-
def initialize(container, collection, entity, expansion, extensions, source_path, module_prefix)
|
109
|
-
@container = container
|
110
|
-
@collection = collection
|
111
|
-
@entity = entity
|
112
|
-
@expansion = expansion.to_sym
|
113
|
-
@extensions = extensions
|
114
|
-
@source_path = source_path
|
115
|
-
@module_prefix = module_prefix.split(MODULE_SEPARATOR)
|
120
|
+
def module_prefix_parts
|
121
|
+
module_prefix.split(MODULE_SEPARATOR)
|
116
122
|
end
|
117
123
|
|
118
124
|
def container_const
|
119
|
-
@container_const ||= Yarrow::Symbols.to_module_const([*
|
125
|
+
@container_const ||= Yarrow::Symbols.to_module_const([*module_prefix_parts, container])
|
120
126
|
end
|
121
127
|
|
122
128
|
def collection_const
|
123
129
|
begin
|
124
|
-
@collection_const ||= Yarrow::Symbols.to_module_const([*
|
130
|
+
@collection_const ||= Yarrow::Symbols.to_module_const([*module_prefix_parts, collection])
|
125
131
|
rescue NameError
|
126
132
|
raise NameError, "cannot map undefined entity `#{collection}`"
|
127
133
|
end
|
128
134
|
end
|
129
135
|
|
130
136
|
def entity_const
|
131
|
-
@entity_const ||= Yarrow::Symbols.to_module_const([*
|
137
|
+
@entity_const ||= Yarrow::Symbols.to_module_const([*module_prefix_parts, entity])
|
132
138
|
end
|
133
139
|
|
134
140
|
def aggregator_const
|
data/lib/yarrow/defaults.yml
CHANGED
@@ -11,8 +11,21 @@ content:
|
|
11
11
|
pages:
|
12
12
|
expansion: tree
|
13
13
|
output:
|
14
|
-
|
15
|
-
|
14
|
+
- target: web
|
15
|
+
generator:
|
16
|
+
engine: __PENDING_LIBRARY_DECISION__
|
17
|
+
template_dir: templates
|
18
|
+
options:
|
19
|
+
error_mode: strict
|
20
|
+
reconcile:
|
21
|
+
match: collection
|
22
|
+
manifest:
|
23
|
+
collection:
|
24
|
+
layout: collection
|
25
|
+
scheme: /{ancestor_path}
|
26
|
+
resource:
|
27
|
+
layout: resource
|
28
|
+
scheme: /{ancestor_path}/{name}
|
16
29
|
assets:
|
17
30
|
input_dir: assets
|
18
31
|
output_dir: public/assets
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Yarrow
|
2
|
+
module Output
|
3
|
+
class Build
|
4
|
+
attr_reader :graph, :output_config
|
5
|
+
|
6
|
+
def initialize(graph, output_config)
|
7
|
+
@graph = graph
|
8
|
+
@output_config = output_config
|
9
|
+
end
|
10
|
+
|
11
|
+
def reconcile
|
12
|
+
case output_config.reconcile.match
|
13
|
+
when "collection/resource" then traverse_by_path(:collection, :resource)
|
14
|
+
when "collection" then traverse_by_label(:collection)
|
15
|
+
when "resource" then traverse_by_label(:resource)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def traverse_by_label(label)
|
22
|
+
graph.n(label).each do |node|
|
23
|
+
puts "§ #{label} node #{node.label} #{node.props}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def traverse_by_path(parent_label, child_label)
|
28
|
+
graph.n(parent_label).each do |collection_node|
|
29
|
+
puts "§ #{parent_label} node #{collection_node.label} #{collection_node.props}"
|
30
|
+
collection_node.out(child_label).each do |resource_node|
|
31
|
+
puts "§ #{child_label} node #{resource_node.label} #{resource_node.props}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -7,7 +7,7 @@ module Yarrow
|
|
7
7
|
symbol: Types::Instance.of(Symbol).accept(String, :to_sym),
|
8
8
|
path: Types::Instance.of(Pathname).accept(String),
|
9
9
|
any: Types::Any.new,
|
10
|
-
array: Types::List.
|
10
|
+
array: Types::List.any,
|
11
11
|
hash: Types::Instance.of(Hash),
|
12
12
|
markdown: Types::Instance.of(Kramdown::Document).accept(String)
|
13
13
|
}
|
@@ -23,11 +23,12 @@ module Yarrow
|
|
23
23
|
@attrs_spec.keys
|
24
24
|
end
|
25
25
|
|
26
|
-
def cast(input)
|
26
|
+
def cast(input, context=nil)
|
27
27
|
missing_attrs = @attrs_spec.keys.difference(input.keys)
|
28
28
|
|
29
29
|
if missing_attrs.any?
|
30
30
|
missing_attrs.each do |name|
|
31
|
+
# TODO: add optional check
|
31
32
|
raise "#{missing_attrs} wrong number of attributes" unless @attrs_spec[name].is_a?(Types::Any)
|
32
33
|
end
|
33
34
|
end
|
@@ -37,7 +38,7 @@ module Yarrow
|
|
37
38
|
raise "attribute #{mismatching_attrs} does not exist" if mismatching_attrs.any?
|
38
39
|
|
39
40
|
input.reduce({}) do |converted, (name, value)|
|
40
|
-
converted[name] = @attrs_spec[name].cast(value)
|
41
|
+
converted[name] = @attrs_spec[name].cast(value, context)
|
41
42
|
converted
|
42
43
|
end
|
43
44
|
end
|
data/lib/yarrow/schema/entity.rb
CHANGED
@@ -33,7 +33,7 @@ module Yarrow
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def initialize(config)
|
36
|
+
def initialize(config, context=nil)
|
37
37
|
converted = dictionary.cast(config)
|
38
38
|
|
39
39
|
converted.each_pair do |key, value|
|
@@ -46,7 +46,15 @@ module Yarrow
|
|
46
46
|
dictionary.attr_names.reduce({}) do |attr_dict, name|
|
47
47
|
value = instance_variable_get("@#{name}")
|
48
48
|
|
49
|
-
attr_dict[name] =
|
49
|
+
attr_dict[name] =if value.is_a?(Array)
|
50
|
+
value.map do |entry|
|
51
|
+
if entry.respond_to?(:to_h)
|
52
|
+
entry.to_h
|
53
|
+
else
|
54
|
+
entry
|
55
|
+
end
|
56
|
+
end
|
57
|
+
elsif value.respond_to?(:to_h)
|
50
58
|
value.to_h
|
51
59
|
else
|
52
60
|
value
|
data/lib/yarrow/schema/types.rb
CHANGED
@@ -53,14 +53,37 @@ module Yarrow
|
|
53
53
|
accepts.key?(input.class)
|
54
54
|
end
|
55
55
|
|
56
|
-
|
56
|
+
# Coerce input into the defined format based on configured
|
57
|
+
# accept rules.
|
58
|
+
#
|
59
|
+
# Will use the unit type’s constructor by default unless
|
60
|
+
# an alternative factory method and constructor arguments are
|
61
|
+
# provided in the accept rule or passed in via context.
|
62
|
+
#
|
63
|
+
# Most object coercions use the defaults, but the context
|
64
|
+
# and options enable specific customisations, such as passing
|
65
|
+
# in an assigned attribute name or the hash key that the input
|
66
|
+
# is a value of.
|
67
|
+
#
|
68
|
+
# @param [Object] input
|
69
|
+
# @param [nil, Hash] context
|
70
|
+
#
|
71
|
+
# @return [Object] instance of unit type represented by this wrapper
|
72
|
+
def coerce(input, context=nil)
|
57
73
|
constructor, options = accepts[input.class]
|
58
74
|
|
59
|
-
|
60
|
-
|
75
|
+
context_args = if context.nil?
|
76
|
+
options.clone
|
77
|
+
elsif options.nil?
|
78
|
+
context.clone
|
79
|
+
else
|
80
|
+
options.merge(context)
|
81
|
+
end
|
82
|
+
|
83
|
+
if context_args.nil?
|
61
84
|
unit.send(constructor, input)
|
62
85
|
else
|
63
|
-
unit.send(constructor, input,
|
86
|
+
unit.send(constructor, input, context_args)
|
64
87
|
end
|
65
88
|
end
|
66
89
|
|
@@ -88,14 +111,14 @@ module Yarrow
|
|
88
111
|
end
|
89
112
|
end
|
90
113
|
|
91
|
-
def cast(input)
|
92
|
-
return coerce(input) if should_coerce?(input)
|
114
|
+
def cast(input, context=nil)
|
115
|
+
return coerce(input, context) if should_coerce?(input)
|
93
116
|
check(input)
|
94
117
|
end
|
95
118
|
end
|
96
119
|
|
97
120
|
class Any < TypeClass
|
98
|
-
def cast(input)
|
121
|
+
def cast(input, context=nil)
|
99
122
|
input
|
100
123
|
end
|
101
124
|
end
|
@@ -141,39 +164,40 @@ module Yarrow
|
|
141
164
|
end
|
142
165
|
end
|
143
166
|
|
144
|
-
|
145
|
-
def
|
146
|
-
|
147
|
-
|
167
|
+
class List < TypeClass
|
168
|
+
def self.any
|
169
|
+
# Constraint: must be array instance
|
170
|
+
new(Instance.of(Array), Any.new)
|
148
171
|
end
|
149
172
|
|
150
|
-
def
|
151
|
-
|
152
|
-
self
|
173
|
+
def self.of(wrapped_type)
|
174
|
+
new(Instance.of(Array), Instance.of(wrapped_type))
|
153
175
|
end
|
154
176
|
|
155
|
-
|
156
|
-
|
157
|
-
self
|
158
|
-
end
|
159
|
-
end
|
177
|
+
attr_reader :element_type
|
178
|
+
alias container_type unit
|
160
179
|
|
161
|
-
|
162
|
-
|
180
|
+
def initialize(unit_type, element_type)
|
181
|
+
@element_type = element_type
|
182
|
+
super(unit_type)
|
183
|
+
end
|
163
184
|
|
164
|
-
def
|
165
|
-
|
185
|
+
def accept_elements(accept_type)
|
186
|
+
element_type.accept(accept_type)
|
187
|
+
self
|
166
188
|
end
|
167
189
|
|
168
|
-
def
|
169
|
-
|
170
|
-
|
190
|
+
def check(input)
|
191
|
+
converted = container_type.cast(input)
|
192
|
+
|
193
|
+
converted.map do |item|
|
194
|
+
element_type.cast(item)
|
171
195
|
end
|
172
196
|
end
|
173
197
|
end
|
174
198
|
|
175
199
|
class Map < TypeClass
|
176
|
-
include CompoundType
|
200
|
+
#include CompoundType
|
177
201
|
|
178
202
|
def self.of(map_spec)
|
179
203
|
if map_spec.is_a?(Hash)
|
@@ -198,15 +222,21 @@ module Yarrow
|
|
198
222
|
super(value_type)
|
199
223
|
end
|
200
224
|
|
225
|
+
def accept_elements(accept_type, constructor=:new, options=nil)
|
226
|
+
value_type.accept(accept_type, constructor, options)
|
227
|
+
self
|
228
|
+
end
|
229
|
+
|
201
230
|
def check(input)
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
value_type.cast(value)
|
231
|
+
result = {}
|
232
|
+
|
233
|
+
input.each_pair do |key, value|
|
234
|
+
checked_key = key_type.cast(key)
|
235
|
+
checked_value = value_type.cast(value, { key: checked_key })
|
236
|
+
result[checked_key] = checked_value
|
207
237
|
end
|
208
238
|
|
209
|
-
|
239
|
+
result
|
210
240
|
end
|
211
241
|
end
|
212
242
|
|
data/lib/yarrow/version.rb
CHANGED
data/lib/yarrow/web/document.rb
CHANGED
@@ -1,5 +1,26 @@
|
|
1
|
-
|
1
|
+
module Yarrow
|
2
2
|
module Web
|
3
|
+
class Document
|
4
|
+
attr_reader :content_node
|
5
|
+
|
6
|
+
def initialize(node, manifest)
|
7
|
+
@content_node = node
|
8
|
+
#manifest.add_document(self)
|
9
|
+
@manifest = manifest
|
10
|
+
end
|
11
|
+
|
12
|
+
def resource
|
13
|
+
content_node.props[:resource]
|
14
|
+
end
|
15
|
+
|
16
|
+
def url
|
17
|
+
@url ||= URL.generate(resource)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Deprecated
|
23
|
+
module LegacyWeb
|
3
24
|
class BaseDocument
|
4
25
|
def resource
|
5
26
|
@resource
|
data/lib/yarrow/web/manifest.rb
CHANGED
@@ -1,5 +1,27 @@
|
|
1
1
|
module Yarrow
|
2
2
|
module Web
|
3
|
+
class NewManifest
|
4
|
+
def initialize
|
5
|
+
@documents_index = {}
|
6
|
+
@documents = []
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :documents
|
10
|
+
|
11
|
+
def add_resource(resource)
|
12
|
+
add_document(Document.new(resource, self))
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_document(document)
|
16
|
+
if @documents_index.key?(document.url)
|
17
|
+
raise "#{document.url} already exists in manifest"
|
18
|
+
end
|
19
|
+
|
20
|
+
@documents << document
|
21
|
+
@documents_index[document.url] = @documents.count - 1
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
3
25
|
class Manifest
|
4
26
|
def self.build(graph)
|
5
27
|
manifest = new
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Yarrow
|
2
|
+
module Web
|
3
|
+
module URI
|
4
|
+
end
|
5
|
+
|
6
|
+
class URL
|
7
|
+
def self.generate(resource)
|
8
|
+
path = if resource.respond_to?(:url)
|
9
|
+
resource.url
|
10
|
+
elsif resource.respond_to?(:permalink)
|
11
|
+
resource.permalink
|
12
|
+
else
|
13
|
+
# TODO: URL generation strategy
|
14
|
+
"/one/two/three"
|
15
|
+
end
|
16
|
+
|
17
|
+
new(path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(path)
|
21
|
+
@path = path
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
@path
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/yarrow.rb
CHANGED
@@ -4,6 +4,7 @@ require "kramdown"
|
|
4
4
|
require "toml-rb"
|
5
5
|
require "mustache"
|
6
6
|
require "parallel"
|
7
|
+
require "addressable/template"
|
7
8
|
|
8
9
|
require "extensions/mementus"
|
9
10
|
|
@@ -28,11 +29,11 @@ require "yarrow/content/expansion/directory_merge"
|
|
28
29
|
require "yarrow/content/expansion/traversal"
|
29
30
|
require "yarrow/content/resource"
|
30
31
|
require "yarrow/web/manifest"
|
32
|
+
require "yarrow/web/url"
|
31
33
|
require "yarrow/web/document"
|
32
34
|
require "yarrow/web/generator"
|
33
35
|
require "yarrow/web/template"
|
34
|
-
require "yarrow/output/
|
35
|
-
require "yarrow/output/web/indexed_file"
|
36
|
+
require "yarrow/output/build"
|
36
37
|
require "yarrow/content_map"
|
37
38
|
require "yarrow/server"
|
38
39
|
require "yarrow/server/livereload"
|
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.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Rickerby
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -297,12 +297,10 @@ files:
|
|
297
297
|
- bin/yarrow-server
|
298
298
|
- lib/extensions/mementus.rb
|
299
299
|
- lib/yarrow.rb
|
300
|
-
- lib/yarrow/assets.rb
|
301
|
-
- lib/yarrow/assets/manifest.rb
|
302
|
-
- lib/yarrow/assets/pipeline.rb
|
303
300
|
- lib/yarrow/config.rb
|
304
301
|
- lib/yarrow/configuration.rb
|
305
302
|
- lib/yarrow/console_runner.rb
|
303
|
+
- lib/yarrow/content/collection.rb
|
306
304
|
- lib/yarrow/content/expansion/aggregator.rb
|
307
305
|
- lib/yarrow/content/expansion/basename_merge.rb
|
308
306
|
- lib/yarrow/content/expansion/directory_merge.rb
|
@@ -330,8 +328,7 @@ files:
|
|
330
328
|
- lib/yarrow/generator.rb
|
331
329
|
- lib/yarrow/help.txt
|
332
330
|
- lib/yarrow/logging.rb
|
333
|
-
- lib/yarrow/output/
|
334
|
-
- lib/yarrow/output/web/indexed_file.rb
|
331
|
+
- lib/yarrow/output/build.rb
|
335
332
|
- lib/yarrow/process/expand_content.rb
|
336
333
|
- lib/yarrow/process/extract_source.rb
|
337
334
|
- lib/yarrow/process/project_manifest.rb
|
@@ -348,15 +345,14 @@ files:
|
|
348
345
|
- lib/yarrow/schema/value.rb
|
349
346
|
- lib/yarrow/server.rb
|
350
347
|
- lib/yarrow/server/livereload.rb
|
351
|
-
- lib/yarrow/source/graph.rb
|
352
348
|
- lib/yarrow/symbols.rb
|
353
|
-
- lib/yarrow/tools/front_matter.rb
|
354
349
|
- lib/yarrow/version.rb
|
355
350
|
- lib/yarrow/web/document.rb
|
356
351
|
- lib/yarrow/web/generator.rb
|
357
352
|
- lib/yarrow/web/manifest.rb
|
358
353
|
- lib/yarrow/web/static_asset.rb
|
359
354
|
- lib/yarrow/web/template.rb
|
355
|
+
- lib/yarrow/web/url.rb
|
360
356
|
- yarrow.gemspec
|
361
357
|
homepage: http://rubygemspec.org/gems/yarrow
|
362
358
|
licenses:
|
@@ -1,118 +0,0 @@
|
|
1
|
-
# TODO: where else is this used?
|
2
|
-
require 'json'
|
3
|
-
|
4
|
-
module Yarrow
|
5
|
-
module Assets
|
6
|
-
##
|
7
|
-
# Provides access to the bundle of compiled CSS and JS assets.
|
8
|
-
#
|
9
|
-
# This is currently based on the output structure of the JSON manifest file
|
10
|
-
# generated by Sprockets, but this class isn't coupled to the Sprockets API
|
11
|
-
# so could be used as a generic manifest reader.
|
12
|
-
#
|
13
|
-
# - `logical_path` represents the core named path to an asset sans version, eg: `main.css`
|
14
|
-
# - `digest_path` represents the versioned instance of an asset with associated digest,
|
15
|
-
# eg: `main-4362eea15558e73d3663de653cdeb81e.css`
|
16
|
-
class Manifest
|
17
|
-
##
|
18
|
-
# Initializes the manifest from a Sprockets-style JSON file.
|
19
|
-
#
|
20
|
-
# If no assets directory is given, looks for a manifest in the main output directory.
|
21
|
-
#
|
22
|
-
# @param config [Yarrow::Configuration]
|
23
|
-
def initialize(config)
|
24
|
-
raise Yarrow::ConfigurationError if config.assets.nil?
|
25
|
-
|
26
|
-
if config.assets.output_dir
|
27
|
-
manifest_path = Pathname.new(config.assets.output_dir) + config.assets.manifest_file
|
28
|
-
else
|
29
|
-
manifest_path = Pathname.new(config.output_dir) + config.assets.manifest_file
|
30
|
-
end
|
31
|
-
|
32
|
-
if File.exists?(manifest_path)
|
33
|
-
manifest_data = JSON.parse(File.read(manifest_path))
|
34
|
-
|
35
|
-
@manifest_index = if manifest_data.key?('assets')
|
36
|
-
manifest_data['assets']
|
37
|
-
else
|
38
|
-
manifest_data
|
39
|
-
end
|
40
|
-
else
|
41
|
-
@manifest_index = {}
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
##
|
46
|
-
# True if the named asset exists.
|
47
|
-
#
|
48
|
-
# @param logical_path [String]
|
49
|
-
# @return [Boolean]
|
50
|
-
def exists?(logical_path)
|
51
|
-
@manifest_index.key? logical_path
|
52
|
-
end
|
53
|
-
|
54
|
-
##
|
55
|
-
# Returns the generated digest path to a named asset.
|
56
|
-
#
|
57
|
-
# @param logical_path [String]
|
58
|
-
# @return [String]
|
59
|
-
def digest_path(logical_path)
|
60
|
-
@manifest_index[logical_path]
|
61
|
-
end
|
62
|
-
|
63
|
-
##
|
64
|
-
# Returns the list of named assets in the manifest.
|
65
|
-
#
|
66
|
-
# @return [Array<String>]
|
67
|
-
def logical_paths
|
68
|
-
@manifest_index.keys
|
69
|
-
end
|
70
|
-
|
71
|
-
##
|
72
|
-
# Returns the list of generated digest paths in the manifest.
|
73
|
-
#
|
74
|
-
# @return [Array<String>]
|
75
|
-
def digest_paths
|
76
|
-
@manifest_index.values
|
77
|
-
end
|
78
|
-
|
79
|
-
##
|
80
|
-
# Returns the list of named CSS assets in the manifest.
|
81
|
-
#
|
82
|
-
# @return [Array<String>]
|
83
|
-
def css_logical_paths
|
84
|
-
select_by_extension(logical_paths, '.css')
|
85
|
-
end
|
86
|
-
|
87
|
-
##
|
88
|
-
# Returns the list of named JS assets in the manifest.
|
89
|
-
#
|
90
|
-
# @return [Array<String>]
|
91
|
-
def js_logical_paths
|
92
|
-
select_by_extension(logical_paths, '.js')
|
93
|
-
end
|
94
|
-
|
95
|
-
##
|
96
|
-
# Returns the list of generated CSS assets in the manifest.
|
97
|
-
#
|
98
|
-
# @return [Array<String>]
|
99
|
-
def css_digest_paths
|
100
|
-
select_by_extension(digest_paths, '.css')
|
101
|
-
end
|
102
|
-
|
103
|
-
##
|
104
|
-
# Returns the list of generated JS assets in the manifest.
|
105
|
-
#
|
106
|
-
# @return [Array<String>]
|
107
|
-
def js_digest_paths
|
108
|
-
select_by_extension(digest_paths, '.js')
|
109
|
-
end
|
110
|
-
|
111
|
-
private
|
112
|
-
|
113
|
-
def select_by_extension(collection, ext)
|
114
|
-
collection.select { |asset| asset.end_with?(ext) }
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
@@ -1,126 +0,0 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
require 'fileutils'
|
3
|
-
require 'sprockets'
|
4
|
-
|
5
|
-
module Yarrow
|
6
|
-
module Assets
|
7
|
-
##
|
8
|
-
# Processes static assets using Sprockets.
|
9
|
-
class Pipeline
|
10
|
-
|
11
|
-
include Loggable
|
12
|
-
|
13
|
-
attr_reader :input_dir, :output_dir, :append_paths, :bundles, :assets
|
14
|
-
|
15
|
-
##
|
16
|
-
# @param config [Yarrow::Configuration]
|
17
|
-
def initialize(config)
|
18
|
-
raise Yarrow::ConfigurationError if config.assets.nil?
|
19
|
-
|
20
|
-
@input_dir = config.assets.input_dir || default_input_dir
|
21
|
-
|
22
|
-
if config.assets.output_dir
|
23
|
-
@output_dir = config.assets.output_dir
|
24
|
-
else
|
25
|
-
@output_dir = config.output_dir || default_output_dir
|
26
|
-
end
|
27
|
-
|
28
|
-
@append_paths = []
|
29
|
-
|
30
|
-
case config.assets.append_paths
|
31
|
-
when Array
|
32
|
-
@append_paths = config.assets.append_paths
|
33
|
-
when '*'
|
34
|
-
@append_paths = Dir[@input_dir + '/*'].select do |path|
|
35
|
-
File.directory?(path)
|
36
|
-
end.map do |path|
|
37
|
-
File.basename(path)
|
38
|
-
end
|
39
|
-
when String
|
40
|
-
@append_paths << config.assets.append_paths
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
##
|
45
|
-
# Compiles an asset manifest and processed output files from the given input bundles.
|
46
|
-
# Also generates a manifest linking each output bundle to its given input name.
|
47
|
-
#
|
48
|
-
# @param bundles [Array<String>]
|
49
|
-
def compile(bundles = [])
|
50
|
-
bundles.each do |bundle|
|
51
|
-
if bundle.include? '*'
|
52
|
-
Dir["#{@input_dir}/#{bundle}"].each do |asset|
|
53
|
-
logger.info "Compiling: #{asset}"
|
54
|
-
manifest.compile(File.basename(asset))
|
55
|
-
end
|
56
|
-
else
|
57
|
-
logger.info "Compiling: #{bundle}"
|
58
|
-
manifest.compile(bundle)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
##
|
64
|
-
# Copy the given files to the output path without processing or renaming.
|
65
|
-
#
|
66
|
-
# @param bundle [Array<String>]
|
67
|
-
def copy(bundles = [])
|
68
|
-
bundles.each do |bundle|
|
69
|
-
FileUtils.cp_r "#{@input_dir}/#{bundle}", "#{@output_dir}/#{bundle}"
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
##
|
74
|
-
# Purges redundant compiled assets from the output path.
|
75
|
-
#
|
76
|
-
# @example Purge all assets except those created in the last 10 minutes
|
77
|
-
# pipeline.purge(0, )
|
78
|
-
#
|
79
|
-
# @param keep [Integer] Number of previous revisions to keep. Defaults to 2.
|
80
|
-
# @param age [Integer] Purge all assets older than this date. Defaults to 1 hour.
|
81
|
-
def purge(keep = 2, age = 3600)
|
82
|
-
# TODO: upgrade to Sprockets 3.0 to support the age arg
|
83
|
-
manifest.clean(keep)
|
84
|
-
end
|
85
|
-
|
86
|
-
##
|
87
|
-
# Access instance of the Sprockets environment.
|
88
|
-
#
|
89
|
-
# @return [Sprockets::Environment]
|
90
|
-
def environment
|
91
|
-
# TODO: decouple dependency on Sprockets
|
92
|
-
@environment ||= create_environment
|
93
|
-
end
|
94
|
-
|
95
|
-
private
|
96
|
-
|
97
|
-
def default_input_dir
|
98
|
-
"#{Dir.pwd}/assets"
|
99
|
-
end
|
100
|
-
|
101
|
-
def default_output_dir
|
102
|
-
"#{Dir.pwd}/public/assets"
|
103
|
-
end
|
104
|
-
|
105
|
-
def manifest_file_path
|
106
|
-
"#{@output_dir}/manifest.json"
|
107
|
-
end
|
108
|
-
|
109
|
-
def manifest
|
110
|
-
Sprockets::Manifest.new(environment, manifest_file_path)
|
111
|
-
end
|
112
|
-
|
113
|
-
def create_environment
|
114
|
-
environment = Sprockets::Environment.new(@input_dir)
|
115
|
-
|
116
|
-
@append_paths.each do |path|
|
117
|
-
environment.append_path path
|
118
|
-
end
|
119
|
-
|
120
|
-
environment
|
121
|
-
end
|
122
|
-
|
123
|
-
end
|
124
|
-
|
125
|
-
end
|
126
|
-
end
|
data/lib/yarrow/assets.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
module Yarrow
|
2
|
-
module Output
|
3
|
-
# Provides a data context for rendering a template.
|
4
|
-
#
|
5
|
-
# Methods provided by this class become available as named variables in
|
6
|
-
# Mustache templates.
|
7
|
-
class Context
|
8
|
-
def initialize(attributes)
|
9
|
-
metaclass = class << self; self; end
|
10
|
-
attributes.each do |name, value|
|
11
|
-
metaclass.send :define_method, name, lambda { value }
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module Yarrow
|
2
|
-
module Output
|
3
|
-
module Web
|
4
|
-
class IndexedFile
|
5
|
-
WRITE_MODE = 'w+:UTF-8'.freeze
|
6
|
-
|
7
|
-
# @return [String] Basename reflecting the server convention (usually: index.html)
|
8
|
-
def index_name
|
9
|
-
@index_name ||= config.index_name || 'index.html'
|
10
|
-
end
|
11
|
-
|
12
|
-
# @return [String] Docroot of the output target
|
13
|
-
def docroot
|
14
|
-
@docroot ||= config.output_dir || 'public'
|
15
|
-
end
|
16
|
-
|
17
|
-
# Write an output file to the specified path under the docroot.
|
18
|
-
#
|
19
|
-
# @param path [String]
|
20
|
-
# @param content [String]
|
21
|
-
def write(path, content)
|
22
|
-
# If the target path is a directory,
|
23
|
-
# generate a default index filename.
|
24
|
-
if path[path.length-1] == '/'
|
25
|
-
path = "#{path}#{index_name}"
|
26
|
-
end
|
27
|
-
|
28
|
-
target_path = Pathname.new("#{docroot}#{path}")
|
29
|
-
|
30
|
-
ensure_dir_exists!(target_path.dirname)
|
31
|
-
|
32
|
-
File.open(target_path.to_s, WRITE_MODE) do |file|
|
33
|
-
file.puts(content)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def ensure_dir_exists!(target)
|
38
|
-
unless File.directory?(target)
|
39
|
-
FileUtils.mkdir_p(target)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
data/lib/yarrow/source/graph.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
module Yarrow
|
2
|
-
module Tools
|
3
|
-
# @deprecated
|
4
|
-
# Maintained here as it is still used in a number of places but needs to be removed soon
|
5
|
-
module FrontMatter
|
6
|
-
|
7
|
-
def read_split_content(path, options={})
|
8
|
-
extract_split_content(File.read(path, :encoding => 'utf-8'), options)
|
9
|
-
end
|
10
|
-
|
11
|
-
def extract_split_content(text, options={})
|
12
|
-
pattern = /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
13
|
-
if text =~ pattern
|
14
|
-
content = text.sub(pattern, "")
|
15
|
-
|
16
|
-
begin
|
17
|
-
if options.key?(:symbolize_keys)
|
18
|
-
meta = YAML.load($1, symbolize_names: true)
|
19
|
-
else
|
20
|
-
meta = YAML.load($1)
|
21
|
-
end
|
22
|
-
return [content, meta]
|
23
|
-
rescue Psych::SyntaxError => error
|
24
|
-
if defined? ::Logger
|
25
|
-
# todo: application wide logger
|
26
|
-
#logger = ::Logger.new(STDOUT)
|
27
|
-
#logger.error "#{error.message}"
|
28
|
-
end
|
29
|
-
return [content, nil]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
[text, nil]
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|