nanoc-conref-fs 0.5.0 → 0.6.0
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 +4 -4
- data/README.md +123 -54
- data/lib/nanoc-conref-fs/ancestry.rb +98 -0
- data/lib/nanoc-conref-fs/conref-filter.rb +27 -0
- data/lib/nanoc-conref-fs/conref-fs.rb +107 -164
- data/lib/nanoc-conref-fs/conrefifier.rb +78 -14
- data/lib/nanoc-conref-fs/datafiles.rb +51 -34
- data/lib/nanoc-conref-fs/variables.rb +30 -0
- data/lib/nanoc-conref-fs.rb +9 -1
- data/nanoc-conref-fs.gemspec +1 -1
- data/test/ancestry_test.rb +79 -0
- data/test/conref_fs_test.rb +15 -77
- data/test/datafiles_test.rb +6 -10
- data/test/fixtures/Rules +14 -2
- data/test/fixtures/content/maliciousness/asterisk_double.html +1 -1
- data/test/fixtures/content/maliciousness/asterisk_single.html +1 -1
- data/test/fixtures/content/multiple/single_var.html +14 -0
- data/test/fixtures/content/multiple/single_var.md +5 -0
- data/test/fixtures/content/multiple/single_var_x.html +14 -0
- data/test/fixtures/content/obfuscation/admonitions.html +8 -8
- data/test/fixtures/content/obfuscation/octicon.html +2 -2
- data/test/fixtures/data/variables/product.yml +9 -0
- data/test/fixtures/layouts/retrieve.html +1 -1
- data/test/fixtures/nanoc.yaml +10 -0
- data/test/test_helper.rb +6 -0
- data/test/variable_mixin_test.rb +7 -5
- metadata +13 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdb225742e914ae1ac3f39c539c290a2c91aabf0
|
4
|
+
data.tar.gz: 694937b4c238491409411370271cc9d5d061c0c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9edf0b62eb28ea4fb128303e7cb442f79b32916b6b562c08f784e09b3d4396e16043a9c96d43837f4b341d4be3a62668168c4a0335c75d42b572318040e34e27
|
7
|
+
data.tar.gz: f6cbdd94a675dadc4b3dc2b91704909b415f91c718baf57a85e10e8581d665b32aa93e7f174d5bef783c41b98f4a38649cce52ed3b4a463515f9f69d629c81a2
|
data/README.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# nanoc-conref-fs
|
2
2
|
|
3
|
-
This gem adds a new Filesystem type called `ConrefFS
|
3
|
+
This gem adds a new Filesystem type to Nanoc called `ConrefFS`. This filesystem permits you to use reusable content and Liquid variables in your content to generate multiple outputs from a single source. It makes heavy use of item representations (or `rep`s for short).
|
4
4
|
|
5
|
-
The idea is that you have a set of YAML files in a data folder which act as your reusables. You can apply
|
5
|
+
The idea is that you have a set of YAML files in a data folder which act as your reusables. You can apply these reusables throughout your content.
|
6
6
|
|
7
7
|
[](https://travis-ci.org/gjtorikian/nanoc-conref-fs)
|
8
8
|
|
9
|
-
|
9
|
+
To get started, set the data source in your *nanoc.yaml* file:
|
10
10
|
|
11
11
|
``` yml
|
12
12
|
data_sources:
|
@@ -14,7 +14,18 @@ data_sources:
|
|
14
14
|
type: conref-fs
|
15
15
|
```
|
16
16
|
|
17
|
-
|
17
|
+
You'll probably also want to provide a list of `rep`s which define all the item reps available to your site. For example:
|
18
|
+
|
19
|
+
``` yml
|
20
|
+
data_sources:
|
21
|
+
-
|
22
|
+
type: conref-fs
|
23
|
+
reps:
|
24
|
+
- :default
|
25
|
+
- :X
|
26
|
+
```
|
27
|
+
|
28
|
+
**NOTE:** If you use this library with Nanoc's ERB filter, and want to use `render`, you'll need to monkey-patch an alias to avoid conflicts with Liquid:
|
18
29
|
|
19
30
|
``` ruby
|
20
31
|
require 'nanoc-conref-fs'
|
@@ -27,64 +38,100 @@ Nanoc::Helpers::Rendering.module_eval do
|
|
27
38
|
end
|
28
39
|
```
|
29
40
|
|
30
|
-
Then, use `renderp`
|
41
|
+
Then, you can use `renderp` just as you would with `render`.
|
31
42
|
|
32
43
|
## Usage
|
33
44
|
|
34
|
-
Nearly all the usage of this gem relies on a *data* folder, sibling to your *content* and *layouts* folders. See [the test fixture](test/fixtures/data) for an example.
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
45
|
+
Nearly all the usage of this gem relies on a *data* folder, sibling to your *content* and *layouts* folders. See [the test fixture](test/fixtures/data) for an example. You can change this with the `data_dir` config option:
|
46
|
+
|
47
|
+
``` yml
|
48
|
+
data_sources:
|
49
|
+
-
|
50
|
+
type: conref-fs
|
51
|
+
data_dir: 'somewhere_else'
|
52
|
+
reps:
|
53
|
+
- :default
|
54
|
+
- :X
|
55
|
+
```
|
56
|
+
|
57
|
+
Then, you can [construct a data folder filled with YAML files](https://github.com/gjtorikian/nanoc-conref-fs/tree/master/test/fixtures/data). These act as the source of your reusable content.
|
58
|
+
|
59
|
+
Finally, you'll need some relevant keys added to your *nanoc.yaml* file.
|
60
|
+
|
61
|
+
### Data folder variables
|
62
|
+
|
63
|
+
The `data_variables` key applies additional/dynamic values to your data files, based on their path. For example, the following `data_variables` configuration adds a `version` attribute to every data file, whose value is `dotcom`:
|
64
|
+
|
65
|
+
``` yaml
|
66
|
+
data_variables:
|
67
|
+
-
|
68
|
+
scope:
|
69
|
+
path: ""
|
70
|
+
values:
|
71
|
+
version: "dotcom"
|
72
|
+
```
|
73
|
+
|
74
|
+
You could add to this key to indicate that any data file called *changed* instead has a version of `something_different`:
|
75
|
+
|
76
|
+
``` yaml
|
77
|
+
data_variables:
|
78
|
+
-
|
79
|
+
scope:
|
80
|
+
path: ""
|
81
|
+
values:
|
82
|
+
version: "dotcom"
|
83
|
+
-
|
84
|
+
scope:
|
85
|
+
path: "changed"
|
86
|
+
values:
|
87
|
+
version: "2.0"
|
88
|
+
```
|
89
|
+
|
90
|
+
In addition to `path`, you can provide an array of `reps` to define which `reps` should receive which version:
|
91
|
+
|
92
|
+
``` yaml
|
93
|
+
data_variables:
|
94
|
+
-
|
95
|
+
scope:
|
96
|
+
path: "feature"
|
97
|
+
values:
|
98
|
+
version: "dotcom"
|
99
|
+
-
|
100
|
+
scope:
|
101
|
+
path: "feature"
|
102
|
+
reps:
|
103
|
+
- :X
|
104
|
+
values:
|
105
|
+
version: "something_else"
|
106
|
+
```
|
107
|
+
|
108
|
+
In this example, any data folder with a path containing "feature" will have `page.version` equal to `dotcom`. However, if you're constructing for the `:X` item representation, `page.version` becomes `something_else`.
|
109
|
+
|
110
|
+
### Page variables
|
111
|
+
|
112
|
+
Similarly, the `page_variables` also use `scope`s, `rep`s, and `value`s to determine variables:
|
113
|
+
|
114
|
+
``` yaml
|
115
|
+
page_variables:
|
116
|
+
-
|
117
|
+
scope:
|
118
|
+
path: ""
|
119
|
+
values:
|
120
|
+
version: "dotcom"
|
121
|
+
-
|
122
|
+
scope:
|
123
|
+
path: "different"
|
124
|
+
values:
|
125
|
+
version: "2.0"
|
126
|
+
```
|
127
|
+
|
128
|
+
In this case, every file path will get a `version` of `dotcom`, but any file matching `different` will get a version of 2.0.
|
82
129
|
|
83
130
|
See the tests for further usage of these conditionals. In both cases, `path` is converted into a Ruby regular expression before being matched against a filename.
|
84
131
|
|
85
132
|
### Associating files with data
|
86
133
|
|
87
|
-
If you have a special `data_association` value
|
134
|
+
If you have a special `data_association` value in your `scope`, additional metadata to items will be applied:
|
88
135
|
|
89
136
|
* An attribute called `:parents`, which adds the parent "map topic" to an item.
|
90
137
|
* An attribute called `:children`, which adds any children of a "map topic."
|
@@ -96,3 +143,25 @@ You can retrieve the stored data at any time (for example, in a layout) by calli
|
|
96
143
|
### Retrieving data files
|
97
144
|
|
98
145
|
You can fetch anything in the *data* folder by passing in a string, demarcated with `.`s, to `VariableMixin.fetch_data_file`. For example, `VariableMixin.fetch_data_file('reusables.intro')` will fetch the file in *data/reusables/intro.yml*.
|
146
|
+
|
147
|
+
### Ignoring content
|
148
|
+
|
149
|
+
You can use the `create_ignore_rules` method to construct ignore rules for your content. For example, say you have a category file that looks like this:
|
150
|
+
|
151
|
+
``` yaml
|
152
|
+
Something:
|
153
|
+
- Blah1
|
154
|
+
{% if page.version == 'dotcom' %}
|
155
|
+
- Blah2
|
156
|
+
{% endif %}
|
157
|
+
```
|
158
|
+
|
159
|
+
By default, Nanoc will try to compile and layout a page for `Blah2` for every item rep, even though it probably shouldn't.
|
160
|
+
|
161
|
+
You can use `create_ignore_rules`, passing in an item rep and a category file to generate ignore rules. For example:
|
162
|
+
|
163
|
+
``` ruby
|
164
|
+
ConrefFS.create_ignore_rules(:X, 'categories.category').each do |f|
|
165
|
+
ignore f, rep: :X
|
166
|
+
end
|
167
|
+
```
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module NanocConrefFS
|
2
|
+
module Ancestry
|
3
|
+
def create_parents(toc, meta)
|
4
|
+
if toc.is_a?(Array)
|
5
|
+
find_array_parents(toc, meta[:title])
|
6
|
+
elsif toc.is_a?(Hash)
|
7
|
+
find_hash_parents(toc, meta[:title])
|
8
|
+
end
|
9
|
+
end
|
10
|
+
module_function :create_parents
|
11
|
+
|
12
|
+
def create_children(toc, meta)
|
13
|
+
if toc.is_a?(Array)
|
14
|
+
find_array_children(toc, meta[:title])
|
15
|
+
elsif toc.is_a?(Hash)
|
16
|
+
find_hash_children(toc, meta[:title])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
module_function :create_children
|
20
|
+
|
21
|
+
# Given a category file that's an array, this method finds
|
22
|
+
# the parent of an item
|
23
|
+
def find_array_parents(toc, title)
|
24
|
+
parents = ''
|
25
|
+
toc.each do |item|
|
26
|
+
if item.is_a?(Hash)
|
27
|
+
parents = find_hash_parents(item, title)
|
28
|
+
break unless parents.empty?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
parents
|
32
|
+
end
|
33
|
+
module_function :find_array_parents
|
34
|
+
|
35
|
+
# Given a category file that's a hash, this method finds
|
36
|
+
# the parent of an item
|
37
|
+
def find_hash_parents(toc, title)
|
38
|
+
parents = ''
|
39
|
+
toc.each_key do |key|
|
40
|
+
toc[key].each do |item|
|
41
|
+
if item.is_a?(Hash)
|
42
|
+
if item.keys.include?(title)
|
43
|
+
parents = key
|
44
|
+
break
|
45
|
+
else
|
46
|
+
if item[item.keys.first].include?(title)
|
47
|
+
parents = key
|
48
|
+
break
|
49
|
+
end
|
50
|
+
end
|
51
|
+
elsif title == item
|
52
|
+
parents = key
|
53
|
+
break
|
54
|
+
end
|
55
|
+
end
|
56
|
+
break unless parents.empty?
|
57
|
+
end
|
58
|
+
parents
|
59
|
+
end
|
60
|
+
module_function :find_hash_parents
|
61
|
+
|
62
|
+
# Given a category file that's an array, this method finds
|
63
|
+
# the children of an item, probably a map topic
|
64
|
+
def find_array_children(toc, title)
|
65
|
+
children = ''
|
66
|
+
toc.each do |item|
|
67
|
+
next unless item.is_a?(Hash)
|
68
|
+
item.each_pair do |key, values|
|
69
|
+
if key == title
|
70
|
+
children = values.flatten
|
71
|
+
break
|
72
|
+
end
|
73
|
+
end
|
74
|
+
break unless children.empty?
|
75
|
+
end
|
76
|
+
children
|
77
|
+
end
|
78
|
+
module_function :find_array_children
|
79
|
+
|
80
|
+
# Given a category file that's a hash, this method finds
|
81
|
+
# the children of an item, probably a map topic
|
82
|
+
def find_hash_children(toc, title)
|
83
|
+
children = ''
|
84
|
+
toc.each_key do |key|
|
85
|
+
toc[key].each do |item|
|
86
|
+
next unless item.is_a?(Hash)
|
87
|
+
unless item[title].nil?
|
88
|
+
children = item.values.flatten
|
89
|
+
break
|
90
|
+
end
|
91
|
+
end
|
92
|
+
break unless children.empty?
|
93
|
+
end
|
94
|
+
children
|
95
|
+
end
|
96
|
+
module_function :find_hash_children
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Nanoc
|
2
|
+
class ItemView
|
3
|
+
# allows apply_attributes to create new item attributes
|
4
|
+
def []=(key, value)
|
5
|
+
unwrap.attributes[key] = value
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module Nanoc::HashExtensions
|
11
|
+
alias_method :original_freeze, :__nanoc_freeze_recursively
|
12
|
+
|
13
|
+
# prevents the item's frozen attributes from remaining frozen
|
14
|
+
def __nanoc_freeze_recursively
|
15
|
+
return if caller.first =~ %r{base/entities/document.rb}
|
16
|
+
original_freeze
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class ConrefFSFilter < Nanoc::Filter
|
21
|
+
identifier :'conref-fs-filter'
|
22
|
+
|
23
|
+
def run(content, _)
|
24
|
+
ConrefFS.apply_attributes(@config, item, @rep.name)
|
25
|
+
NanocConrefFS::Conrefifier.liquify(@config, path: @item[:filename], content: content, rep: @rep.name)
|
26
|
+
end
|
27
|
+
end
|
@@ -1,202 +1,145 @@
|
|
1
1
|
require_relative 'conrefifier'
|
2
|
-
|
3
|
-
# Unsure why attr_accessor does not work here
|
4
|
-
module VariableMixin
|
5
|
-
def self.variables
|
6
|
-
@variables
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.variables=(variables)
|
10
|
-
@variables = variables
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.fetch_data_file(association)
|
14
|
-
reference = association.split('.')
|
15
|
-
variables = VariableMixin.variables
|
16
|
-
data = variables['site']['data']
|
17
|
-
while key = reference.shift
|
18
|
-
data = data[key]
|
19
|
-
end
|
20
|
-
data
|
21
|
-
end
|
22
|
-
end
|
2
|
+
require 'active_support/core_ext/string'
|
23
3
|
|
24
4
|
class ConrefFS < Nanoc::DataSource
|
25
5
|
include Nanoc::DataSources::Filesystem
|
26
|
-
include
|
6
|
+
include NanocConrefFS::Variables
|
7
|
+
include NanocConrefFS::Ancestry
|
27
8
|
|
28
9
|
identifier :'conref-fs'
|
29
10
|
|
30
11
|
# Before iterating over the file objects, this method loads the data folder
|
31
12
|
# and applies it to an ivar for later usage.
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
39
|
-
super
|
13
|
+
def up
|
14
|
+
data_files = NanocConrefFS::Datafiles.collect_data(data_dir_name)
|
15
|
+
NanocConrefFS::Variables.data_files = data_files
|
16
|
+
NanocConrefFS::Variables.variables = {}
|
17
|
+
reps = @config[:reps] || [:default]
|
18
|
+
reps.each { |rep| ConrefFS.load_data_folder(@site_config, rep) }
|
40
19
|
end
|
41
20
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
21
|
+
def data_dir_name
|
22
|
+
config.fetch(:data_dir) { |_| 'data' }
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.load_data_folder(config, rep)
|
26
|
+
return unless NanocConrefFS::Variables.variables[rep].nil?
|
27
|
+
data_files = NanocConrefFS::Variables.data_files
|
28
|
+
data = NanocConrefFS::Datafiles.process(data_files, config, rep)
|
29
|
+
NanocConrefFS::Variables.variables[rep] = { 'site' => { 'config' => config, 'data' => data } }
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.apply_attributes(config, item, rep)
|
33
|
+
page_vars = NanocConrefFS::Conrefifier.file_variables(config[:page_variables], item[:filename], rep)
|
34
|
+
|
35
|
+
frontmatter_vars = { :page => page_vars }.merge(NanocConrefFS::Variables.variables[rep])
|
36
|
+
|
46
37
|
unless page_vars[:data_association].nil?
|
47
38
|
association = page_vars[:data_association]
|
48
|
-
toc =
|
49
|
-
|
50
|
-
|
51
|
-
elsif toc.is_a?(Hash)
|
52
|
-
find_hash_parents(toc, meta['title'])
|
53
|
-
end
|
54
|
-
|
55
|
-
meta[:children] = if toc.is_a?(Array)
|
56
|
-
find_array_children(toc, meta['title'])
|
57
|
-
elsif toc.is_a?(Hash)
|
58
|
-
find_hash_children(toc, meta['title'])
|
59
|
-
end
|
60
|
-
end
|
61
|
-
page_vars.each_pair do |name, value|
|
62
|
-
meta[name.to_s] = value
|
39
|
+
toc = NanocConrefFS::Variables.fetch_data_file(association, rep)
|
40
|
+
item[:parents] = NanocConrefFS::Ancestry::create_parents(toc, item.attributes)
|
41
|
+
item[:children] = NanocConrefFS::Ancestry::create_children(toc, item.attributes)
|
63
42
|
end
|
64
|
-
[meta, content]
|
65
|
-
end
|
66
43
|
|
67
|
-
|
68
|
-
|
69
|
-
def find_array_parents(toc, title)
|
70
|
-
parents = ''
|
71
|
-
toc.each do |item|
|
72
|
-
if item.is_a?(Hash)
|
73
|
-
parents = find_hash_parents(item, title)
|
74
|
-
break unless parents.empty?
|
75
|
-
end
|
44
|
+
page_vars.each_pair do |key, value|
|
45
|
+
item[key] = value
|
76
46
|
end
|
77
|
-
parents
|
78
|
-
end
|
79
47
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
else
|
91
|
-
if item[item.keys.first].include?(title)
|
92
|
-
parents = key
|
93
|
-
break
|
94
|
-
end
|
95
|
-
end
|
96
|
-
elsif title == item
|
97
|
-
parents = key
|
98
|
-
break
|
48
|
+
item.attributes.each_pair do |key, value|
|
49
|
+
if value.is_a?(Array)
|
50
|
+
item[key] = value.map do |arr_v|
|
51
|
+
return arr_v unless arr_v =~ NanocConrefFS::Conrefifier::SINGLE_SUB
|
52
|
+
NanocConrefFS::Conrefifier.apply_liquid(arr_v, frontmatter_vars)
|
53
|
+
end
|
54
|
+
else
|
55
|
+
if value =~ NanocConrefFS::Conrefifier::SINGLE_SUB
|
56
|
+
value = NanocConrefFS::Conrefifier.apply_liquid(value, frontmatter_vars)
|
57
|
+
item[key] = value
|
99
58
|
end
|
100
59
|
end
|
101
|
-
break unless parents.empty?
|
102
60
|
end
|
103
|
-
parents
|
104
61
|
end
|
105
62
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
63
|
+
# There are a lot of problems when trying to parse liquid
|
64
|
+
# out of the frontmatter—all of them dealing with collision between
|
65
|
+
# the { character in Liquid and its signfigance in YAML. We'll overload
|
66
|
+
# the parse method here to resolve those issues ahead of time.
|
67
|
+
def parse(content_filename, meta_filename, _kind)
|
68
|
+
# Read data
|
69
|
+
data = read(content_filename)
|
70
|
+
|
71
|
+
# Check presence of metadata section
|
72
|
+
return [{}, data] if data !~ /\A-{3,5}\s*$/
|
73
|
+
|
74
|
+
# Split data
|
75
|
+
pieces = data.split(/^(-{5}|-{3})[ \t]*\r?\n?/, 3)
|
76
|
+
if pieces.size < 4
|
77
|
+
raise RuntimeError.new(
|
78
|
+
"The file '#{content_filename}' appears to start with a metadata section (three or five dashes at the top) but it does not seem to be in the correct format.",
|
79
|
+
)
|
121
80
|
end
|
122
81
|
|
123
|
-
#
|
124
|
-
|
125
|
-
def find_hash_children(toc, title)
|
126
|
-
children = ''
|
127
|
-
toc.keys.each do |key|
|
128
|
-
toc[key].each do |item|
|
129
|
-
next unless item.is_a?(Hash)
|
130
|
-
unless item[title].nil?
|
131
|
-
children = item.values.flatten
|
132
|
-
break
|
133
|
-
end
|
134
|
-
end
|
135
|
-
break unless children.empty?
|
136
|
-
end
|
137
|
-
children
|
138
|
-
end
|
82
|
+
# N.B. the only change to the original function
|
83
|
+
pieces[2].gsub!(/^([^:]+): (\{\{.+)/, '\1: \'\2\'')
|
139
84
|
|
140
|
-
|
141
|
-
# (demarcated by Liquid's {{ }} tags) using both the data/ folder and any variables defined
|
142
|
-
# within the nanoc.yaml config file
|
143
|
-
def read(filename)
|
144
|
-
content = ''
|
85
|
+
# Parse
|
145
86
|
begin
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
content = File.read(filename)
|
150
|
-
return content unless filename.start_with?('content', 'layouts')
|
151
|
-
|
152
|
-
# we must obfuscate essential ExtendedMarkdownFilter content
|
153
|
-
content = content.gsub(/\{\{\s*#(\S+)\s*\}\}/, '[[#\1]]')
|
154
|
-
content = content.gsub(/\{\{\s*\/(\S+)\s*\}\}/, '[[/\1]]')
|
155
|
-
content = content.gsub(/\{\{\s*(octicon-\S+\s*[^\}]+)\s*\}\}/, '[[\1]]')
|
156
|
-
rescue => e
|
157
|
-
raise "Could not read #{filename}: #{e.inspect}"
|
87
|
+
meta = YAML.load(pieces[2]) || {}
|
88
|
+
rescue Exception => e
|
89
|
+
raise "Could not parse YAML for #{content_filename}: #{e.message}"
|
158
90
|
end
|
91
|
+
verify_meta(meta, content_filename)
|
92
|
+
content = pieces[4]
|
159
93
|
|
160
|
-
|
161
|
-
|
94
|
+
# Done
|
95
|
+
[meta, content]
|
96
|
+
end
|
162
97
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
98
|
+
def self.create_ignore_rules(rep, file)
|
99
|
+
current_articles = NanocConrefFS::Variables.fetch_data_file(file, rep)
|
100
|
+
current_articles = flatten_list(current_articles).flatten
|
101
|
+
current_articles = fix_nested_content(current_articles)
|
167
102
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
103
|
+
basic_yaml = NanocConrefFS::Variables.data_files["data/#{file.tr!('.', '/')}.yml"]
|
104
|
+
basic_yaml.gsub!(/\{%.+/, '')
|
105
|
+
full_file = YAML.load(basic_yaml)
|
106
|
+
|
107
|
+
full_user_articles = flatten_list(full_file).flatten
|
108
|
+
full_user_articles = fix_nested_content(full_user_articles)
|
109
|
+
|
110
|
+
blacklisted_articles = full_user_articles - current_articles
|
111
|
+
blacklisted_articles.map do |article|
|
112
|
+
"#{article.parameterize}.md"
|
113
|
+
end
|
114
|
+
end
|
177
115
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
asterisk_match = asterisk_match.sub(/\*{2}(.+?)\*{2}/, ': <strong>\1</strong>')
|
187
|
-
end
|
188
|
-
asterisk_match
|
116
|
+
def self.flatten_list(arr)
|
117
|
+
result = []
|
118
|
+
return result unless arr
|
119
|
+
arr.each do |item|
|
120
|
+
if item.is_a?(Hash)
|
121
|
+
item.each_pair do |key, value|
|
122
|
+
result << key
|
123
|
+
result.concat(value)
|
189
124
|
end
|
125
|
+
else
|
126
|
+
result << item
|
190
127
|
end
|
128
|
+
end
|
191
129
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
130
|
+
result
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.fix_nested_content(articles)
|
134
|
+
articles.delete_if do |i|
|
135
|
+
if i.is_a? Hash
|
136
|
+
articles.concat(i.keys.concat(i.values).flatten)
|
137
|
+
true
|
138
|
+
else
|
139
|
+
false
|
140
|
+
end
|
199
141
|
end
|
142
|
+
articles
|
200
143
|
end
|
201
144
|
|
202
145
|
# This method is extracted from the Nanoc default FS
|