nanoc 4.9.9 → 4.10.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/NEWS.md +15 -0
- data/lib/nanoc/base/errors.rb +6 -0
- data/lib/nanoc/base/feature.rb +2 -2
- data/lib/nanoc/base/services/filter.rb +1 -1
- data/lib/nanoc/data_sources/filesystem.rb +42 -20
- data/lib/nanoc/data_sources/filesystem/parser.rb +5 -0
- data/lib/nanoc/filters/sass.rb +138 -30
- data/lib/nanoc/helpers/breadcrumbs.rb +32 -3
- data/lib/nanoc/version.rb +1 -1
- metadata +2 -3
- data/lib/nanoc/filters/sass/sass_filesystem_importer.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 046c9869b2f916776a4f0fe741916842cbbc68b584e11b606abac58b854a9f44
|
4
|
+
data.tar.gz: aeb902ad7fca66c89b63d46e2e9e8508c08e1cc3cdeb8dcbf0c45698d8c6a905
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93124b5f9eab590c046853ef39aa1c58516a365f2f721e7f1de73a34c0c4916ea1c3331a6c5db5e218e5921b0ef77abb5b50f5caf832d832eb0cc328133d58a8
|
7
|
+
data.tar.gz: f3c544d01d70da7ac4379311208fd57932ba26ca157b039fdda05d4c96f8c7f6fbe93a45376ad4bf4e2cf3c10e5c2e9a6157a8b729dd58006a675b9ffc3a48ce
|
data/NEWS.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# Nanoc news
|
2
2
|
|
3
|
+
## 4.10.0 (2018-10-14)
|
4
|
+
|
5
|
+
Features:
|
6
|
+
|
7
|
+
* Added source map support to the Sass filter (#1365) [Gregory Pakosz]
|
8
|
+
* Added a `nanoc()` Sass function (#1365) [Gregory Pakosz]
|
9
|
+
|
10
|
+
Fixes:
|
11
|
+
|
12
|
+
* Ensured breadcrumb trail always ends in item itself (#1367)
|
13
|
+
|
14
|
+
Enhancemens:
|
15
|
+
|
16
|
+
* Made Nanoc error when meta-file cannot be unambiguously associated (#1370)
|
17
|
+
|
3
18
|
## 4.9.9 (2018-10-06)
|
4
19
|
|
5
20
|
Fixes:
|
data/lib/nanoc/base/errors.rb
CHANGED
@@ -236,6 +236,12 @@ module Nanoc::Int
|
|
236
236
|
end
|
237
237
|
end
|
238
238
|
|
239
|
+
class AmbiguousMetadataAssociation < Generic
|
240
|
+
def initialize(content_filenames, meta_filename)
|
241
|
+
super("There are multiple content files (#{content_filenames.join(', ')}) that could match the file containing metadata (#{meta_filename}).")
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
239
245
|
class InternalInconsistency < Generic
|
240
246
|
end
|
241
247
|
end
|
data/lib/nanoc/base/feature.rb
CHANGED
@@ -93,8 +93,8 @@ end
|
|
93
93
|
|
94
94
|
# Tracking issue:
|
95
95
|
# https://github.com/nanoc/features/issues/24
|
96
|
-
Nanoc::Feature.define('live_cmd', version: '4.
|
96
|
+
Nanoc::Feature.define('live_cmd', version: '4.10')
|
97
97
|
|
98
98
|
# Tracking issue:
|
99
99
|
# https://github.com/nanoc/features/issues/40
|
100
|
-
Nanoc::Feature.define('toml', version: '4.
|
100
|
+
Nanoc::Feature.define('toml', version: '4.10')
|
@@ -34,7 +34,7 @@ module Nanoc
|
|
34
34
|
class << self
|
35
35
|
def define(ident, &block)
|
36
36
|
filter_class = Class.new(::Nanoc::Filter) { identifier(ident) }
|
37
|
-
filter_class.send(:define_method, :run) do |content, params|
|
37
|
+
filter_class.send(:define_method, :run) do |content, params = {}|
|
38
38
|
instance_exec(content, params, &block)
|
39
39
|
end
|
40
40
|
end
|
@@ -176,30 +176,49 @@ module Nanoc::DataSources
|
|
176
176
|
|
177
177
|
return [] if dir_name.nil?
|
178
178
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
identifier,
|
194
|
-
content_checksum_data: content_checksum_data_for(proto_doc),
|
195
|
-
attributes_checksum_data: attributes_checksum_data_for(proto_doc, content_filename, meta_filename),
|
196
|
-
)
|
197
|
-
end
|
179
|
+
each_content_meta_pair_in(dir_name) do |content_filename, meta_filename|
|
180
|
+
proto_doc = read_proto_document(content_filename, meta_filename, klass)
|
181
|
+
|
182
|
+
content = content_for(proto_doc, content_filename)
|
183
|
+
attributes = attributes_for(proto_doc, content_filename, meta_filename)
|
184
|
+
identifier = identifier_for(content_filename, meta_filename, dir_name)
|
185
|
+
|
186
|
+
res << klass.new(
|
187
|
+
content,
|
188
|
+
attributes,
|
189
|
+
identifier,
|
190
|
+
content_checksum_data: content_checksum_data_for(proto_doc),
|
191
|
+
attributes_checksum_data: attributes_checksum_data_for(proto_doc, content_filename, meta_filename),
|
192
|
+
)
|
198
193
|
end
|
199
194
|
|
200
195
|
res
|
201
196
|
end
|
202
197
|
|
198
|
+
# Enumerates each pair of content file and meta file. If there is ambiguity, it will raise an error.
|
199
|
+
def each_content_meta_pair_in(dir_name)
|
200
|
+
all_split_files_in(dir_name).each do |base_filename, (meta_ext, content_exts)|
|
201
|
+
meta_filename = filename_for(base_filename, meta_ext)
|
202
|
+
content_filenames = content_exts.map { |e| filename_for(base_filename, e) }
|
203
|
+
|
204
|
+
have_possible_ambiguity = meta_filename && content_filenames.size > 1
|
205
|
+
if have_possible_ambiguity && content_filenames.count { |fn| !parser.frontmatter?(fn) } != 1
|
206
|
+
raise Nanoc::Int::Errors::AmbiguousMetadataAssociation.new(content_filenames, meta_filename)
|
207
|
+
end
|
208
|
+
|
209
|
+
content_filenames.each do |content_filename|
|
210
|
+
real_meta_filename =
|
211
|
+
if have_possible_ambiguity && parser.frontmatter?(content_filename)
|
212
|
+
nil
|
213
|
+
else
|
214
|
+
meta_filename
|
215
|
+
end
|
216
|
+
|
217
|
+
yield(content_filename, real_meta_filename)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
203
222
|
def content_checksum_data_for(proto_doc)
|
204
223
|
data = proto_doc.content_checksum_data
|
205
224
|
data ? Digest::SHA1.digest(data) : nil
|
@@ -379,8 +398,11 @@ module Nanoc::DataSources
|
|
379
398
|
end
|
380
399
|
end
|
381
400
|
|
401
|
+
def parser
|
402
|
+
@parser ||= Parser.new(config: @config)
|
403
|
+
end
|
404
|
+
|
382
405
|
def parse(content_filename, meta_filename)
|
383
|
-
parser = Parser.new(config: @config)
|
384
406
|
parser.call(content_filename, meta_filename)
|
385
407
|
end
|
386
408
|
end
|
data/lib/nanoc/filters/sass.rb
CHANGED
@@ -1,45 +1,153 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Nanoc::Filters
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
4
|
+
Nanoc::Filter.define(:sass) do |content, params = {}|
|
5
|
+
include Sass
|
6
|
+
css(self, @item_rep, content, params)
|
7
|
+
end
|
8
|
+
|
9
|
+
Nanoc::Filter.define(:sass_sourcemap) do |content, params = {}|
|
10
|
+
include Sass
|
11
|
+
sourcemap(self, @item_rep, content, params)
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'sass'
|
15
|
+
|
16
|
+
module Sass
|
17
|
+
def css(filter, rep, content, params)
|
18
|
+
css, = render(filter, rep, content, params)
|
19
|
+
css
|
20
|
+
end
|
21
|
+
|
22
|
+
def sourcemap(filter, rep, content, params)
|
23
|
+
_, sourcemap = render(filter, rep, content, params)
|
24
|
+
sourcemap
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def render(filter, rep, content, params = {})
|
30
|
+
importer = NanocSassImporter.new(filter)
|
31
|
+
|
17
32
|
options = params.merge(
|
18
|
-
|
19
|
-
|
33
|
+
load_paths: [importer, *params[:load_paths]&.reject { |p| p.is_a?(String) && %r{^content/} =~ p }],
|
34
|
+
importer: importer,
|
35
|
+
filename: rep.item.identifier.to_s,
|
36
|
+
cache: false,
|
20
37
|
)
|
38
|
+
sourcemap_path = options.delete(:sourcemap_path)
|
39
|
+
|
21
40
|
engine = ::Sass::Engine.new(content, options)
|
22
|
-
engine.render
|
41
|
+
css, sourcemap = sourcemap_path ? engine.render_with_sourcemap(sourcemap_path) : engine.render
|
42
|
+
[css, sourcemap&.to_json(css_uri: rep.path, type: rep.path.nil? ? :inline : :auto)]
|
23
43
|
end
|
24
44
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
45
|
+
# @api private
|
46
|
+
class NanocSassImporter < ::Sass::Importers::Filesystem
|
47
|
+
attr_reader :filter
|
48
|
+
|
49
|
+
def initialize(filter)
|
50
|
+
@filter = filter
|
51
|
+
super('.')
|
52
|
+
end
|
53
|
+
|
54
|
+
def find_relative(name, base_identifier, options)
|
55
|
+
base_raw_filename = filter.items[base_identifier].raw_filename
|
56
|
+
|
57
|
+
# we can't resolve a relative filename from an in-memory item
|
58
|
+
return unless base_raw_filename
|
59
|
+
|
60
|
+
raw_filename, syntax = ::Sass::Util.destructure(find_real_file(File.dirname(base_raw_filename), name, options))
|
61
|
+
return unless raw_filename
|
62
|
+
|
63
|
+
item = raw_filename_to_item(raw_filename)
|
64
|
+
# it doesn't make sense to import a file, from Nanoc's content if the corresponding item has been deleted
|
65
|
+
raise "unable to map #{raw_filename} to any item" if item.nil?
|
66
|
+
|
67
|
+
filter.depend_on([item])
|
68
|
+
|
69
|
+
options[:syntax] = syntax
|
70
|
+
options[:filename] = item.identifier.to_s
|
71
|
+
options[:importer] = self
|
72
|
+
::Sass::Engine.new(item.raw_content, options)
|
73
|
+
end
|
74
|
+
|
75
|
+
def find(identifier, options)
|
76
|
+
items = filter.items.find_all(identifier)
|
77
|
+
return if items.empty?
|
78
|
+
|
79
|
+
content = if items.size == 1
|
80
|
+
items.first.compiled_content
|
81
|
+
else
|
82
|
+
items.map { |item| %(@import "#{item.identifier}";) }.join("\n")
|
83
|
+
end
|
84
|
+
|
85
|
+
options[:syntax] = :scss
|
86
|
+
options[:filename] = identifier.to_s
|
87
|
+
options[:importer] = self
|
88
|
+
::Sass::Engine.new(content, options)
|
89
|
+
end
|
90
|
+
|
91
|
+
def key(identifier, _options)
|
92
|
+
[self.class.name + ':' + root, identifier.to_s]
|
93
|
+
end
|
94
|
+
|
95
|
+
def public_url(identifier, _sourcemap_directory)
|
96
|
+
path = filter.items[identifier].path
|
97
|
+
return path unless path.nil?
|
98
|
+
|
99
|
+
raw_filename = filter.items[identifier].raw_filename
|
100
|
+
return if raw_filename.nil?
|
101
|
+
|
102
|
+
::Sass::Util.file_uri_from_path(raw_filename)
|
103
|
+
end
|
104
|
+
|
105
|
+
def to_s
|
106
|
+
'Nanoc Sass Importer'
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.raw_filename_to_item_map_for_config(config, items)
|
110
|
+
@raw_filename_to_item_map ||= {}
|
111
|
+
@raw_filename_to_item_map[config.object_id] ||=
|
112
|
+
{}.tap do |map|
|
113
|
+
items.each do |item|
|
114
|
+
if item.raw_filename
|
115
|
+
path = Pathname.new(item.raw_filename).realpath.to_s
|
116
|
+
map[path] = item
|
117
|
+
end
|
33
118
|
end
|
34
119
|
end
|
35
|
-
|
36
|
-
|
120
|
+
end
|
121
|
+
|
122
|
+
def raw_filename_to_item(filename)
|
123
|
+
realpath = Pathname.new(filename).realpath.to_s
|
37
124
|
|
38
|
-
|
39
|
-
|
125
|
+
map = self.class.raw_filename_to_item_map_for_config(filter.config, filter.items)
|
126
|
+
map[realpath]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
40
130
|
|
41
|
-
|
42
|
-
|
131
|
+
module ::Sass::Script::Functions
|
132
|
+
def nanoc(string, params)
|
133
|
+
assert_type string, :String
|
134
|
+
assert_type params, :Hash
|
135
|
+
result = options[:importer].filter.instance_eval(string.value)
|
136
|
+
case result
|
137
|
+
when TrueClass, FalseClass
|
138
|
+
bool(result)
|
139
|
+
when Array
|
140
|
+
list(result, :comma)
|
141
|
+
when Hash
|
142
|
+
map(result)
|
143
|
+
when nil
|
144
|
+
null
|
145
|
+
when Numeric
|
146
|
+
number(result)
|
147
|
+
else
|
148
|
+
params['unquote'] ? unquoted_string(result) : quoted_string(result)
|
149
|
+
end
|
43
150
|
end
|
151
|
+
declare :nanoc, [:string], var_kwargs: true
|
44
152
|
end
|
45
153
|
end
|
@@ -33,6 +33,34 @@ module Nanoc::Helpers
|
|
33
33
|
|
34
34
|
# @return [Array]
|
35
35
|
def breadcrumbs_trail
|
36
|
+
# The design of this function is a little complicated.
|
37
|
+
#
|
38
|
+
# We can’t use #parent_of from the ChildParent helper, because the
|
39
|
+
# breadcrumb trail can have gaps. For example, the breadcrumbs trail for
|
40
|
+
# /software/oink.md might be /index.md -> nil -> /software/oink.md if
|
41
|
+
# there is no item matching /software.* or /software/index.*.
|
42
|
+
#
|
43
|
+
# What this function does instead is something more complicated:
|
44
|
+
#
|
45
|
+
# 1. It creates an ordered prefix list, based on the identifier of the
|
46
|
+
# item to create a breadcrumbs trail for. For example,
|
47
|
+
# /software/oink.md might have the prefix list
|
48
|
+
# ['', '/software', '/software/oink.md'].
|
49
|
+
#
|
50
|
+
# 2. For each of the elements in that list, it will create a list of
|
51
|
+
# patterns could match zero or more items. For example, the element
|
52
|
+
# '/software' would correspond to the pattern '/software.*'.
|
53
|
+
#
|
54
|
+
# 3. For each of the elements in that list, and for each pattern for that
|
55
|
+
# element, it will find any matching element. For example, the
|
56
|
+
# pattern '/software.*' (coming from the prefix /software) would match
|
57
|
+
# the item /software.md.
|
58
|
+
#
|
59
|
+
# 4. Return the list of items, with the last element replaced by the item
|
60
|
+
# for which the breadcrumb is generated for -- while ancestral items
|
61
|
+
# in the breadcrumbs trail can have a bit of ambiguity, the item for
|
62
|
+
# which to generate the breadcrumbs trail is fixed.
|
63
|
+
|
36
64
|
# e.g. ['', '/foo', '/foo/bar']
|
37
65
|
components = item.identifier.components
|
38
66
|
prefixes = components.inject(['']) { |acc, elem| acc + [acc.last + '/' + elem] }
|
@@ -40,9 +68,9 @@ module Nanoc::Helpers
|
|
40
68
|
if @item.identifier.legacy?
|
41
69
|
prefixes.map { |pr| @items[Nanoc::Identifier.new('/' + pr, type: :legacy)] }
|
42
70
|
else
|
43
|
-
prefixes
|
44
|
-
|
45
|
-
.map do |pr|
|
71
|
+
ancestral_prefixes = prefixes.reject { |pr| pr =~ /^\/index\./ }[0..-2]
|
72
|
+
ancestral_items =
|
73
|
+
ancestral_prefixes.map do |pr|
|
46
74
|
if pr == ''
|
47
75
|
@items['/index.*']
|
48
76
|
else
|
@@ -50,6 +78,7 @@ module Nanoc::Helpers
|
|
50
78
|
prefix_patterns.lazy.map { |pat| @items[pat] }.find(&:itself)
|
51
79
|
end
|
52
80
|
end
|
81
|
+
ancestral_items + [item]
|
53
82
|
end
|
54
83
|
end
|
55
84
|
end
|
data/lib/nanoc/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nanoc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Defreyne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-10-
|
11
|
+
date: 2018-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -401,7 +401,6 @@ files:
|
|
401
401
|
- lib/nanoc/filters/relativize_paths.rb
|
402
402
|
- lib/nanoc/filters/rubypants.rb
|
403
403
|
- lib/nanoc/filters/sass.rb
|
404
|
-
- lib/nanoc/filters/sass/sass_filesystem_importer.rb
|
405
404
|
- lib/nanoc/filters/slim.rb
|
406
405
|
- lib/nanoc/filters/typogruby.rb
|
407
406
|
- lib/nanoc/filters/uglify_js.rb
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# @api private
|
4
|
-
class ::Sass::Importers::Filesystem
|
5
|
-
alias _orig_find _find
|
6
|
-
|
7
|
-
def _find(dir, name, options)
|
8
|
-
# Find filename
|
9
|
-
full_filename, _syntax = ::Sass::Util.destructure(find_real_file(dir, name, options))
|
10
|
-
return nil if full_filename.nil?
|
11
|
-
|
12
|
-
# Create dependency
|
13
|
-
filter = options[:nanoc_current_filter]
|
14
|
-
if filter
|
15
|
-
item = filter.imported_filename_to_item(full_filename)
|
16
|
-
filter.depend_on([item]) unless item.nil?
|
17
|
-
end
|
18
|
-
|
19
|
-
# Call original _find
|
20
|
-
_orig_find(dir, name, options)
|
21
|
-
end
|
22
|
-
end
|