jekyll-sheafy 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -1
- data/README.md +5 -5
- data/lib/jekyll/sheafy/dependencies.rb +55 -20
- data/lib/jekyll/sheafy/directed_graph.rb +8 -14
- data/lib/jekyll/sheafy/references.rb +34 -29
- data/lib/jekyll/sheafy/taxa.rb +22 -1
- data/lib/jekyll/sheafy/template_error.rb +25 -0
- data/lib/jekyll/sheafy/version.rb +1 -1
- data/lib/jekyll/sheafy.rb +15 -3
- metadata +46 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ec5d4f41ee3fca018fca579929acf04ad876ff525de337d6e385e8949226f62
|
4
|
+
data.tar.gz: 3e3feffb64ce77917d63fc53506bed3310b1dc3d4f52f0dd7dd66ba615f14e74
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25b689459a2f27e2399463f31a24220b76875ea97e0f37c533ae975ed1c43f0b6369618c959bcb6502062565c61bf9b1b1ddb5b803bc2207ad08251ade16126f
|
7
|
+
data.tar.gz: 1d0d6d01edf37590ec5b41529eddca5778743cbe3c899bd44ca6630ebe15b7fdf5a1f4b082caa534e1b64e733fb343721fc14093572092dfe7a490768c5e3983
|
data/CHANGELOG.md
CHANGED
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [0.3.0] - 2022-02-01
|
11
|
+
|
12
|
+
### Added
|
13
|
+
|
14
|
+
- `inheritable` config key (array of strings, validated) to define attributes which are inherited from parent node.
|
15
|
+
- `referents` variable containing list of referents (i.e. the targets of all references in the current node).
|
16
|
+
- `root` variable containing the root node of the tree the current node belongs to.
|
17
|
+
- `predecessors`/`successors` variables containing the siblings preceeding/following the current node.
|
18
|
+
|
19
|
+
### Changed
|
20
|
+
|
21
|
+
- Error message are a bit more rational.
|
22
|
+
- `taxa` configuration key is now validated; it must be an hash valued in hashes.
|
23
|
+
- `references.matchers` configuration key is now validated; it must be an array of regexps containing a single named capture "slug".
|
24
|
+
|
10
25
|
## [0.2.0] - 2022-01-29
|
11
26
|
|
12
27
|
### Added
|
@@ -20,5 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
20
35
|
- Structure to represent directed graphs.
|
21
36
|
- Topological checks for rooted forests.
|
22
37
|
|
23
|
-
[unreleased]: https://github.com/paolobrasolin/jekyll-sheafy/compare/0.
|
38
|
+
[unreleased]: https://github.com/paolobrasolin/jekyll-sheafy/compare/0.3.0...HEAD
|
39
|
+
[0.3.0]: https://github.com/paolobrasolin/jekyll-sheafy/compare/0.2.0...0.3.0
|
40
|
+
[0.2.0]: https://github.com/paolobrasolin/jekyll-sheafy/compare/0.1.0...0.2.0
|
24
41
|
[0.1.0]: https://github.com/paolobrasolin/jekyll-sheafy/releases/tag/0.1.0
|
data/README.md
CHANGED
@@ -40,6 +40,7 @@ sheafy:
|
|
40
40
|
references:
|
41
41
|
matchers: [] # ...
|
42
42
|
taxa: {} # ...
|
43
|
+
inheritable: [] # ...
|
43
44
|
```
|
44
45
|
|
45
46
|
### Node variables
|
@@ -57,14 +58,18 @@ sheafy:
|
|
57
58
|
|
58
59
|
#### Dependencies
|
59
60
|
|
61
|
+
- `root`
|
60
62
|
- `ancestors`
|
61
63
|
- `parent`
|
62
64
|
- `subroot`
|
63
65
|
- `children`
|
66
|
+
- `predecessors`
|
67
|
+
- `successors`
|
64
68
|
|
65
69
|
#### References
|
66
70
|
|
67
71
|
- `referrers`
|
72
|
+
- `referents`
|
68
73
|
|
69
74
|
#### Numbering
|
70
75
|
|
@@ -75,11 +80,6 @@ sheafy:
|
|
75
80
|
|
76
81
|
These are the features you can expect in the future:
|
77
82
|
|
78
|
-
- Enable `referents` variable w/ nodes references by the current one
|
79
|
-
- `root` variable w/ root node of the tree
|
80
|
-
- `siblings` variable or some variant of it to enable navigation between adjacent nodes at the same depth
|
81
|
-
- Prev/next node navigation
|
82
|
-
- Variable inheritance from parent/root node
|
83
83
|
- Search feature
|
84
84
|
|
85
85
|
Of course any feedback is welcome!
|
@@ -4,9 +4,10 @@ module Jekyll
|
|
4
4
|
module Sheafy
|
5
5
|
module Dependencies
|
6
6
|
RE_INCLUDE_TAG = /^@include{(?<slug>.+?)}$/
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
|
8
|
+
class Error < TemplateError; end
|
9
|
+
|
10
|
+
InvalidConfig = Error.build("Invalid config: %s is not an %s.")
|
10
11
|
|
11
12
|
def self.process(nodes)
|
12
13
|
adjacency_list = build_adjacency_list(nodes)
|
@@ -26,6 +27,7 @@ module Jekyll
|
|
26
27
|
attribute_ancestors!(node)
|
27
28
|
attribute_depth!(node)
|
28
29
|
attribute_clicks!(node)
|
30
|
+
attribute_inheritable!(node)
|
29
31
|
end
|
30
32
|
|
31
33
|
# NOTE: this pass is separate to have data available in layouts.
|
@@ -34,6 +36,8 @@ module Jekyll
|
|
34
36
|
end
|
35
37
|
end
|
36
38
|
|
39
|
+
#==[ Graph building ]=====================================================
|
40
|
+
|
37
41
|
def self.scan_includes(node)
|
38
42
|
node.content.scan(RE_INCLUDE_TAG).flatten
|
39
43
|
end
|
@@ -42,16 +46,31 @@ module Jekyll
|
|
42
46
|
nodes_index.transform_values(&method(:scan_includes))
|
43
47
|
end
|
44
48
|
|
49
|
+
def self.build_rooted_forest!(adjacency_list)
|
50
|
+
Sheafy::DirectedGraph[adjacency_list].
|
51
|
+
tap(&:ensure_rooted_forest!)
|
52
|
+
rescue Jekyll::Sheafy::DirectedGraph::Error => error
|
53
|
+
raise StandardError.new(<<~MESSAGE)
|
54
|
+
Sheafy processing error! The nodes dependency graph MUST be a directed rooted forest. #{error.message}
|
55
|
+
MESSAGE
|
56
|
+
end
|
57
|
+
|
45
58
|
def self.denormalize_adjacency_list!(list, index)
|
46
59
|
# TODO: handle missing nodes
|
47
60
|
list.transform_keys!(&index)
|
48
61
|
list.values.each { |children| children.map!(&index) }
|
49
62
|
end
|
50
63
|
|
64
|
+
#==[ Data generation ]====================================================
|
65
|
+
|
51
66
|
def self.attribute_neighbors!(list)
|
52
67
|
list.each do |parent, children|
|
53
68
|
parent.data["children"] = children
|
54
|
-
children.
|
69
|
+
children.each_with_index do |child, index|
|
70
|
+
child.data["parent"] ||= parent
|
71
|
+
child.data["predecessors"] = children.take(index)
|
72
|
+
child.data["successors"] = children.drop(index.succ)
|
73
|
+
end
|
55
74
|
end
|
56
75
|
end
|
57
76
|
|
@@ -62,6 +81,7 @@ module Jekyll
|
|
62
81
|
ancestors = [*parent.data["ancestors"], parent]
|
63
82
|
node.data["ancestors"] = ancestors
|
64
83
|
end
|
84
|
+
node.data["root"] = parent&.data&.[]("root") || node
|
65
85
|
end
|
66
86
|
|
67
87
|
def self.attribute_depth!(node)
|
@@ -73,8 +93,8 @@ module Jekyll
|
|
73
93
|
node.data["clicks"] ||= [
|
74
94
|
{ "clicker" => node.data["clicker"], "value" => 0 },
|
75
95
|
]
|
76
|
-
node.data["children"]
|
77
|
-
group_by { |child| child.data["clicker"] }
|
96
|
+
node.data["children"]&.
|
97
|
+
group_by { |child| child.data["clicker"] }&.
|
78
98
|
each do |clicker, children|
|
79
99
|
children.each_with_index do |child, index|
|
80
100
|
clicks = node.data["clicks"].dup
|
@@ -84,22 +104,22 @@ module Jekyll
|
|
84
104
|
end
|
85
105
|
end
|
86
106
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
when Sheafy::DirectedGraph::IndegreeError then "node reuse"
|
96
|
-
else raise StandardError.new("Malformed dependency graph!")
|
97
|
-
end
|
98
|
-
raise StandardError.new(<<~MESSAGE)
|
99
|
-
Error in dependency graph topology, #{message} detected: #{error.payload}
|
100
|
-
MESSAGE
|
107
|
+
INHERITABLE_PATH = ["sheafy", "inheritable"]
|
108
|
+
|
109
|
+
def self.attribute_inheritable!(node)
|
110
|
+
inheritable = node.site.config.dig(*INHERITABLE_PATH) || []
|
111
|
+
return unless (parent = node.data["parent"])
|
112
|
+
inherited = parent.data.slice(*inheritable)
|
113
|
+
# TODO: how/when do we need to clone/dup here?
|
114
|
+
node.data.merge!(**inherited) { |key, left, right| left }
|
101
115
|
end
|
102
116
|
|
117
|
+
#==[ Layout flattening ]==================================================
|
118
|
+
|
119
|
+
SUBLAYOUT_KEY = "sublayout"
|
120
|
+
SUBLAYOUT_DEFAULT_VALUE = "sheafy/node/default"
|
121
|
+
SUBROOT_KEY = "subroot"
|
122
|
+
|
103
123
|
def self.apply_sublayout(resource, content, subroot)
|
104
124
|
sublayout = resource.data.fetch(SUBLAYOUT_KEY, SUBLAYOUT_DEFAULT_VALUE)
|
105
125
|
# NOTE: all this mess is just to adhere to Jekyll's internals
|
@@ -133,6 +153,21 @@ module Jekyll
|
|
133
153
|
end
|
134
154
|
apply_sublayout(resource, content, subroot)
|
135
155
|
end
|
156
|
+
|
157
|
+
#==[ Config validation ]==================================================
|
158
|
+
|
159
|
+
def self.validate_config!(config)
|
160
|
+
case (inheritables = config.dig(*INHERITABLE_PATH))
|
161
|
+
when nil
|
162
|
+
when Array
|
163
|
+
inheritables.each_with_index do |inheritable, index|
|
164
|
+
next if inheritable.is_a?(String)
|
165
|
+
raise InvalidConfig.new([*INHERITABLE_PATH, index].join("."), "string")
|
166
|
+
end
|
167
|
+
else
|
168
|
+
raise InvalidConfig.new(INHERITABLE_PATH.join("."), "array")
|
169
|
+
end
|
170
|
+
end
|
136
171
|
end
|
137
172
|
end
|
138
173
|
end
|
@@ -1,23 +1,17 @@
|
|
1
1
|
require "tsort"
|
2
|
+
require "jekyll/sheafy/template_error"
|
2
3
|
|
3
4
|
module Jekyll
|
4
5
|
module Sheafy
|
5
6
|
class DirectedGraph < Hash
|
6
|
-
class
|
7
|
-
attr_reader :payload
|
7
|
+
class Error < TemplateError; end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
class MissingKeysError < PayloadError; end
|
16
|
-
class InvalidValuesError < PayloadError; end
|
17
|
-
class MultipleEdgesError < PayloadError; end
|
18
|
-
class LoopsError < PayloadError; end
|
19
|
-
class CyclesError < PayloadError; end
|
20
|
-
class IndegreeError < PayloadError; end
|
9
|
+
MissingKeysError = Error.build("Missing keys detected: %s.")
|
10
|
+
InvalidValuesError = Error.build("Invalid values detected: %s.")
|
11
|
+
MultipleEdgesError = Error.build("Parallel edges detected: %s.")
|
12
|
+
LoopsError = Error.build("Loops detected: %s.")
|
13
|
+
CyclesError = Error.build("Cycles detected: %s.")
|
14
|
+
IndegreeError = Error.build("Nodes with indegree > 1 detected: %s.")
|
21
15
|
|
22
16
|
def ensure_rooted_forest!
|
23
17
|
ensure_valid!
|
@@ -1,47 +1,37 @@
|
|
1
1
|
require "safe_yaml"
|
2
|
+
require "jekyll/sheafy/template_error"
|
3
|
+
|
2
4
|
# NOTE: allows for rexexp entries in mathers array in config
|
3
5
|
SafeYAML::OPTIONS[:whitelisted_tags].push("!ruby/regexp")
|
4
6
|
|
5
7
|
module Jekyll
|
6
8
|
module Sheafy
|
7
9
|
module References
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
"matchers" => [
|
14
|
-
/{%\s*ref (?<slug>.+?)\s*%}/,
|
15
|
-
],
|
16
|
-
}
|
17
|
-
@@config = DEFAULT_CONFIG
|
10
|
+
MATCHERS_PATH = ["sheafy", "references", "matchers"]
|
11
|
+
DEFAULT_MATCHERS = [
|
12
|
+
/{%\s*ref (?<slug>.+?)\s*%}/,
|
13
|
+
]
|
14
|
+
SLUG_CAPTURE_NAME = "slug"
|
18
15
|
REFERRERS_KEY = "referrers"
|
16
|
+
REFERENTS_KEY = "referents"
|
19
17
|
|
20
|
-
|
21
|
-
return if matcher.names.include?("slug")
|
22
|
-
raise InvalidMatcher.new(<<~ERROR)
|
23
|
-
Sheafy configuration error: the matcher #{matcher} is missing a capturing group named "slug".
|
24
|
-
ERROR
|
25
|
-
end
|
18
|
+
class Error < TemplateError; end
|
26
19
|
|
27
|
-
|
28
|
-
overrides = config.fetch(CONFIG_KEY, {})
|
29
|
-
overrides["matchers"]&.each(&method(:validate_matcher!))
|
30
|
-
@@config = Jekyll::Utils.deep_merge_hashes(DEFAULT_CONFIG, overrides)
|
31
|
-
end
|
20
|
+
InvalidMatcher = Error.build("Invalid reference matcher: %s should have one capture group named '#{SLUG_CAPTURE_NAME}'.")
|
32
21
|
|
33
|
-
def self.process(nodes_index
|
34
|
-
load_config(config)
|
22
|
+
def self.process(nodes_index)
|
35
23
|
adjacency_list = build_adjacency_list(nodes_index)
|
36
24
|
denormalize_adjacency_list!(adjacency_list, nodes_index)
|
37
|
-
# NOTE: topology is arbitrary so no single pass technique is possible.
|
38
|
-
nodes_index.values.each { |node| node.data[REFERRERS_KEY] = [] }
|
39
25
|
attribute_neighbors!(adjacency_list)
|
40
26
|
end
|
41
27
|
|
28
|
+
#==[ Graph building ]=====================================================
|
29
|
+
|
42
30
|
def self.scan_references(node)
|
43
|
-
|
44
|
-
|
31
|
+
matchers = node.site.config.dig(*MATCHERS_PATH) || DEFAULT_MATCHERS
|
32
|
+
matchers.flat_map do |matcher|
|
33
|
+
index = matcher.named_captures.fetch(SLUG_CAPTURE_NAME).fetch(0).pred
|
34
|
+
node.content.scan(matcher).map { |captures| captures.fetch(index) }
|
45
35
|
end
|
46
36
|
end
|
47
37
|
|
@@ -55,16 +45,31 @@ module Jekyll
|
|
55
45
|
list.values.each { |children| children.map!(&index) }
|
56
46
|
end
|
57
47
|
|
48
|
+
#==[ Data generation ]====================================================
|
49
|
+
|
58
50
|
def self.attribute_neighbors!(list)
|
51
|
+
# NOTE: topology is arbitrary so no single pass technique is possible.
|
52
|
+
list.keys.each { |node| node.data[REFERRERS_KEY] = [] }
|
59
53
|
list.each do |referrer, referents|
|
60
|
-
|
61
|
-
# referrer.data["referents"] = referents.uniq
|
54
|
+
referrer.data[REFERENTS_KEY] = referents.uniq
|
62
55
|
referents.each do |referent|
|
63
56
|
next if referent.data[REFERRERS_KEY].include?(referrer)
|
64
57
|
referent.data[REFERRERS_KEY] << referrer
|
65
58
|
end
|
66
59
|
end
|
67
60
|
end
|
61
|
+
|
62
|
+
#==[ Config validation ]==================================================
|
63
|
+
|
64
|
+
def self.validate_config!(config)
|
65
|
+
config.dig(*MATCHERS_PATH)&.each(&method(:validate_matcher!))
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.validate_matcher!(matcher)
|
69
|
+
valid = matcher.named_captures.key?(SLUG_CAPTURE_NAME)
|
70
|
+
valid &&= matcher.named_captures.fetch(SLUG_CAPTURE_NAME).one?
|
71
|
+
raise InvalidMatcher.new(matcher) unless valid
|
72
|
+
end
|
68
73
|
end
|
69
74
|
end
|
70
75
|
end
|
data/lib/jekyll/sheafy/taxa.rb
CHANGED
@@ -1,18 +1,39 @@
|
|
1
|
+
require "jekyll/sheafy/template_error"
|
2
|
+
|
1
3
|
module Jekyll
|
2
4
|
module Sheafy
|
3
5
|
module Taxa
|
6
|
+
TAXA_PATH = ["sheafy", "taxa"]
|
4
7
|
TAXON_KEY = "taxon"
|
5
8
|
|
9
|
+
class Error < TemplateError; end
|
10
|
+
|
11
|
+
InvalidTaxon = Error.build("Invalid taxon: %s should be an hash.")
|
12
|
+
|
6
13
|
def self.process(nodes_index)
|
7
14
|
nodes_index.values.each(&method(:apply_taxon!))
|
8
15
|
end
|
9
16
|
|
17
|
+
#==[ Data generation ]====================================================
|
18
|
+
|
10
19
|
def self.apply_taxon!(node)
|
11
20
|
taxon_name = node.data[TAXON_KEY]
|
12
|
-
taxon_data = node.site.config.dig(
|
21
|
+
taxon_data = node.site.config.dig(*TAXA_PATH, taxon_name) || {}
|
13
22
|
# TODO: emit warning on undefined taxon
|
14
23
|
node.data.merge!(taxon_data) { |key, left, right| left }
|
15
24
|
end
|
25
|
+
|
26
|
+
#==[ Config validation ]==================================================
|
27
|
+
|
28
|
+
def self.validate_config!(config)
|
29
|
+
config.dig(*TAXA_PATH)&.each_pair do |taxon_key, taxon_value|
|
30
|
+
validate_taxon!(taxon_key, taxon_value)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.validate_taxon!(taxon_key, taxon_value)
|
35
|
+
raise InvalidTaxon.new(taxon_key) unless taxon_value.is_a?(Hash)
|
36
|
+
end
|
16
37
|
end
|
17
38
|
end
|
18
39
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Jekyll
|
2
|
+
module Sheafy
|
3
|
+
# NOTE: be careful in wielding magick!
|
4
|
+
class TemplateError < StandardError
|
5
|
+
attr_reader :payload
|
6
|
+
|
7
|
+
def initialize(*payload)
|
8
|
+
@payload = payload
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
self.class.instance_variable_get(:@template) % payload
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.build(template)
|
16
|
+
raise ArgumentError.new(<<~MESSAGE) unless template.is_a?(String)
|
17
|
+
wrong type of argument (given #{template.class}, expected String)
|
18
|
+
MESSAGE
|
19
|
+
Class.new(self) do
|
20
|
+
@template = template
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/jekyll/sheafy.rb
CHANGED
@@ -2,17 +2,25 @@ require "jekyll"
|
|
2
2
|
require "jekyll/sheafy/dependencies"
|
3
3
|
require "jekyll/sheafy/references"
|
4
4
|
require "jekyll/sheafy/taxa"
|
5
|
+
require "jekyll/sheafy/template_error"
|
5
6
|
require "jekyll/sheafy/version"
|
6
7
|
|
7
8
|
module Jekyll
|
8
9
|
module Sheafy
|
9
|
-
|
10
|
+
def self.validate_config!(site)
|
11
|
+
Jekyll::Sheafy::Taxa.validate_config!(site.config)
|
12
|
+
Jekyll::Sheafy::References.validate_config!(site.config)
|
13
|
+
Jekyll::Sheafy::Dependencies.validate_config!(site.config)
|
14
|
+
rescue Jekyll::Sheafy::TemplateError => error
|
15
|
+
raise StandardError.new(<<~MESSAGE)
|
16
|
+
Sheafy configuration error! #{error.message}
|
17
|
+
MESSAGE
|
18
|
+
end
|
10
19
|
|
11
20
|
def self.process(site)
|
12
|
-
config = site.config.fetch(CONFIG_KEY, {})
|
13
21
|
nodes_index = build_nodes_index(site)
|
14
22
|
Jekyll::Sheafy::Taxa.process(nodes_index)
|
15
|
-
Jekyll::Sheafy::References.process(nodes_index
|
23
|
+
Jekyll::Sheafy::References.process(nodes_index)
|
16
24
|
Jekyll::Sheafy::Dependencies.process(nodes_index)
|
17
25
|
end
|
18
26
|
|
@@ -24,6 +32,10 @@ module Jekyll
|
|
24
32
|
end
|
25
33
|
end
|
26
34
|
|
35
|
+
Jekyll::Hooks.register :site, :after_init do |site|
|
36
|
+
Jekyll::Sheafy::validate_config!(site)
|
37
|
+
end
|
38
|
+
|
27
39
|
Jekyll::Hooks.register :site, :post_read, priority: 30 do |site|
|
28
40
|
Jekyll::Sheafy.process(site)
|
29
41
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-sheafy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paolo Brasolin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-01-
|
11
|
+
date: 2022-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -44,6 +44,34 @@ dependencies:
|
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 11.1.3
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: guard-rspec
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 4.7.3
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 4.7.3
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: guard
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 2.18.0
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 2.18.0
|
47
75
|
- !ruby/object:Gem::Dependency
|
48
76
|
name: rspec
|
49
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,6 +100,20 @@ dependencies:
|
|
72
100
|
- - "~>"
|
73
101
|
- !ruby/object:Gem::Version
|
74
102
|
version: 0.13.0
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: simplecov-lcov
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.8.0
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 0.8.0
|
75
117
|
- !ruby/object:Gem::Dependency
|
76
118
|
name: simplecov
|
77
119
|
requirement: !ruby/object:Gem::Requirement
|
@@ -103,6 +145,7 @@ files:
|
|
103
145
|
- lib/jekyll/sheafy/directed_graph.rb
|
104
146
|
- lib/jekyll/sheafy/references.rb
|
105
147
|
- lib/jekyll/sheafy/taxa.rb
|
148
|
+
- lib/jekyll/sheafy/template_error.rb
|
106
149
|
- lib/jekyll/sheafy/version.rb
|
107
150
|
homepage: https://github.com/paolobrasolin/jekyll-sheafy
|
108
151
|
licenses:
|
@@ -128,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
171
|
- !ruby/object:Gem::Version
|
129
172
|
version: '0'
|
130
173
|
requirements: []
|
131
|
-
rubygems_version: 3.1.
|
174
|
+
rubygems_version: 3.1.4
|
132
175
|
signing_key:
|
133
176
|
specification_version: 4
|
134
177
|
summary: Brew your own Stacks Project with Jekyll!
|