nanoc3 3.2.4 → 3.3.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.
- metadata +14 -313
- data/.gemtest +0 -0
- data/ChangeLog +0 -3
- data/Gemfile +0 -29
- data/LICENSE +0 -19
- data/NEWS.md +0 -449
- data/README.md +0 -108
- data/Rakefile +0 -14
- data/bin/nanoc3 +0 -12
- data/doc/yardoc_templates/default/layout/html/footer.erb +0 -10
- data/lib/nanoc3.rb +0 -28
- data/lib/nanoc3/base.rb +0 -49
- data/lib/nanoc3/base/compilation/checksum_store.rb +0 -57
- data/lib/nanoc3/base/compilation/compiled_content_cache.rb +0 -62
- data/lib/nanoc3/base/compilation/compiler.rb +0 -455
- data/lib/nanoc3/base/compilation/compiler_dsl.rb +0 -214
- data/lib/nanoc3/base/compilation/dependency_tracker.rb +0 -196
- data/lib/nanoc3/base/compilation/filter.rb +0 -165
- data/lib/nanoc3/base/compilation/item_rep_proxy.rb +0 -102
- data/lib/nanoc3/base/compilation/item_rep_recorder_proxy.rb +0 -88
- data/lib/nanoc3/base/compilation/outdatedness_checker.rb +0 -223
- data/lib/nanoc3/base/compilation/outdatedness_reasons.rb +0 -46
- data/lib/nanoc3/base/compilation/rule.rb +0 -73
- data/lib/nanoc3/base/compilation/rule_context.rb +0 -84
- data/lib/nanoc3/base/compilation/rule_memory_calculator.rb +0 -40
- data/lib/nanoc3/base/compilation/rule_memory_store.rb +0 -53
- data/lib/nanoc3/base/compilation/rules_collection.rb +0 -231
- data/lib/nanoc3/base/context.rb +0 -47
- data/lib/nanoc3/base/core_ext.rb +0 -6
- data/lib/nanoc3/base/core_ext/array.rb +0 -62
- data/lib/nanoc3/base/core_ext/hash.rb +0 -63
- data/lib/nanoc3/base/core_ext/pathname.rb +0 -26
- data/lib/nanoc3/base/core_ext/string.rb +0 -46
- data/lib/nanoc3/base/directed_graph.rb +0 -275
- data/lib/nanoc3/base/errors.rb +0 -174
- data/lib/nanoc3/base/memoization.rb +0 -67
- data/lib/nanoc3/base/notification_center.rb +0 -84
- data/lib/nanoc3/base/ordered_hash.rb +0 -200
- data/lib/nanoc3/base/plugin_registry.rb +0 -165
- data/lib/nanoc3/base/result_data/item_rep.rb +0 -488
- data/lib/nanoc3/base/source_data/code_snippet.rb +0 -58
- data/lib/nanoc3/base/source_data/configuration.rb +0 -24
- data/lib/nanoc3/base/source_data/data_source.rb +0 -234
- data/lib/nanoc3/base/source_data/item.rb +0 -301
- data/lib/nanoc3/base/source_data/layout.rb +0 -130
- data/lib/nanoc3/base/source_data/site.rb +0 -361
- data/lib/nanoc3/base/store.rb +0 -135
- data/lib/nanoc3/cli.rb +0 -133
- data/lib/nanoc3/cli/command.rb +0 -139
- data/lib/nanoc3/cli/commands/autocompile.rb +0 -60
- data/lib/nanoc3/cli/commands/compile.rb +0 -280
- data/lib/nanoc3/cli/commands/create_item.rb +0 -62
- data/lib/nanoc3/cli/commands/create_layout.rb +0 -75
- data/lib/nanoc3/cli/commands/create_site.rb +0 -410
- data/lib/nanoc3/cli/commands/debug.rb +0 -119
- data/lib/nanoc3/cli/commands/info.rb +0 -98
- data/lib/nanoc3/cli/commands/nanoc.rb +0 -37
- data/lib/nanoc3/cli/commands/update.rb +0 -72
- data/lib/nanoc3/cli/commands/view.rb +0 -84
- data/lib/nanoc3/cli/commands/watch.rb +0 -125
- data/lib/nanoc3/cli/error_handler.rb +0 -193
- data/lib/nanoc3/cli/logger.rb +0 -91
- data/lib/nanoc3/data_sources.rb +0 -29
- data/lib/nanoc3/data_sources/deprecated/delicious.rb +0 -42
- data/lib/nanoc3/data_sources/deprecated/last_fm.rb +0 -87
- data/lib/nanoc3/data_sources/deprecated/twitter.rb +0 -38
- data/lib/nanoc3/data_sources/filesystem.rb +0 -299
- data/lib/nanoc3/data_sources/filesystem_unified.rb +0 -116
- data/lib/nanoc3/data_sources/filesystem_verbose.rb +0 -86
- data/lib/nanoc3/extra.rb +0 -22
- data/lib/nanoc3/extra/auto_compiler.rb +0 -103
- data/lib/nanoc3/extra/chick.rb +0 -125
- data/lib/nanoc3/extra/core_ext.rb +0 -4
- data/lib/nanoc3/extra/core_ext/enumerable.rb +0 -33
- data/lib/nanoc3/extra/core_ext/time.rb +0 -19
- data/lib/nanoc3/extra/deployers.rb +0 -11
- data/lib/nanoc3/extra/deployers/rsync.rb +0 -114
- data/lib/nanoc3/extra/file_proxy.rb +0 -40
- data/lib/nanoc3/extra/validators.rb +0 -12
- data/lib/nanoc3/extra/validators/links.rb +0 -264
- data/lib/nanoc3/extra/validators/w3c.rb +0 -95
- data/lib/nanoc3/extra/vcs.rb +0 -66
- data/lib/nanoc3/extra/vcses.rb +0 -17
- data/lib/nanoc3/extra/vcses/bazaar.rb +0 -25
- data/lib/nanoc3/extra/vcses/dummy.rb +0 -24
- data/lib/nanoc3/extra/vcses/git.rb +0 -25
- data/lib/nanoc3/extra/vcses/mercurial.rb +0 -25
- data/lib/nanoc3/extra/vcses/subversion.rb +0 -25
- data/lib/nanoc3/filters.rb +0 -53
- data/lib/nanoc3/filters/asciidoc.rb +0 -38
- data/lib/nanoc3/filters/bluecloth.rb +0 -19
- data/lib/nanoc3/filters/coderay.rb +0 -21
- data/lib/nanoc3/filters/colorize_syntax.rb +0 -261
- data/lib/nanoc3/filters/erb.rb +0 -35
- data/lib/nanoc3/filters/erubis.rb +0 -27
- data/lib/nanoc3/filters/haml.rb +0 -27
- data/lib/nanoc3/filters/kramdown.rb +0 -20
- data/lib/nanoc3/filters/less.rb +0 -53
- data/lib/nanoc3/filters/markaby.rb +0 -20
- data/lib/nanoc3/filters/maruku.rb +0 -20
- data/lib/nanoc3/filters/mustache.rb +0 -24
- data/lib/nanoc3/filters/rainpress.rb +0 -19
- data/lib/nanoc3/filters/rdiscount.rb +0 -22
- data/lib/nanoc3/filters/rdoc.rb +0 -33
- data/lib/nanoc3/filters/redcarpet.rb +0 -27
- data/lib/nanoc3/filters/redcloth.rb +0 -47
- data/lib/nanoc3/filters/relativize_paths.rb +0 -45
- data/lib/nanoc3/filters/rubypants.rb +0 -20
- data/lib/nanoc3/filters/sass.rb +0 -66
- data/lib/nanoc3/filters/slim.rb +0 -25
- data/lib/nanoc3/filters/typogruby.rb +0 -23
- data/lib/nanoc3/filters/uglify_js.rb +0 -42
- data/lib/nanoc3/helpers.rb +0 -16
- data/lib/nanoc3/helpers/blogging.rb +0 -319
- data/lib/nanoc3/helpers/breadcrumbs.rb +0 -40
- data/lib/nanoc3/helpers/capturing.rb +0 -138
- data/lib/nanoc3/helpers/filtering.rb +0 -50
- data/lib/nanoc3/helpers/html_escape.rb +0 -55
- data/lib/nanoc3/helpers/link_to.rb +0 -151
- data/lib/nanoc3/helpers/rendering.rb +0 -140
- data/lib/nanoc3/helpers/tagging.rb +0 -71
- data/lib/nanoc3/helpers/text.rb +0 -44
- data/lib/nanoc3/helpers/xml_sitemap.rb +0 -76
- data/lib/nanoc3/tasks.rb +0 -10
- data/lib/nanoc3/tasks/clean.rake +0 -16
- data/lib/nanoc3/tasks/clean.rb +0 -29
- data/lib/nanoc3/tasks/deploy/rsync.rake +0 -14
- data/lib/nanoc3/tasks/validate.rake +0 -92
- data/nanoc3.gemspec +0 -49
- data/tasks/doc.rake +0 -16
- data/tasks/test.rake +0 -44
- data/test/base/core_ext/array_spec.rb +0 -73
- data/test/base/core_ext/hash_spec.rb +0 -98
- data/test/base/core_ext/pathname_spec.rb +0 -27
- data/test/base/core_ext/string_spec.rb +0 -37
- data/test/base/test_checksum_store.rb +0 -35
- data/test/base/test_code_snippet.rb +0 -31
- data/test/base/test_compiler.rb +0 -316
- data/test/base/test_compiler_dsl.rb +0 -161
- data/test/base/test_context.rb +0 -31
- data/test/base/test_data_source.rb +0 -46
- data/test/base/test_dependency_tracker.rb +0 -262
- data/test/base/test_directed_graph.rb +0 -283
- data/test/base/test_filter.rb +0 -83
- data/test/base/test_item.rb +0 -179
- data/test/base/test_item_rep.rb +0 -553
- data/test/base/test_layout.rb +0 -59
- data/test/base/test_memoization.rb +0 -90
- data/test/base/test_notification_center.rb +0 -34
- data/test/base/test_outdatedness_checker.rb +0 -394
- data/test/base/test_plugin.rb +0 -30
- data/test/base/test_rule.rb +0 -19
- data/test/base/test_rule_context.rb +0 -65
- data/test/base/test_site.rb +0 -190
- data/test/cli/commands/test_compile.rb +0 -33
- data/test/cli/commands/test_create_item.rb +0 -14
- data/test/cli/commands/test_create_layout.rb +0 -28
- data/test/cli/commands/test_create_site.rb +0 -24
- data/test/cli/commands/test_help.rb +0 -12
- data/test/cli/commands/test_info.rb +0 -11
- data/test/cli/commands/test_update.rb +0 -10
- data/test/cli/test_cli.rb +0 -102
- data/test/cli/test_error_handler.rb +0 -29
- data/test/cli/test_logger.rb +0 -10
- data/test/data_sources/test_filesystem.rb +0 -433
- data/test/data_sources/test_filesystem_unified.rb +0 -536
- data/test/data_sources/test_filesystem_verbose.rb +0 -357
- data/test/extra/core_ext/test_enumerable.rb +0 -30
- data/test/extra/core_ext/test_time.rb +0 -15
- data/test/extra/deployers/test_rsync.rb +0 -232
- data/test/extra/test_auto_compiler.rb +0 -417
- data/test/extra/test_file_proxy.rb +0 -19
- data/test/extra/test_vcs.rb +0 -22
- data/test/extra/validators/test_links.rb +0 -51
- data/test/extra/validators/test_w3c.rb +0 -47
- data/test/filters/test_asciidoc.rb +0 -22
- data/test/filters/test_bluecloth.rb +0 -18
- data/test/filters/test_coderay.rb +0 -44
- data/test/filters/test_colorize_syntax.rb +0 -283
- data/test/filters/test_erb.rb +0 -99
- data/test/filters/test_erubis.rb +0 -70
- data/test/filters/test_haml.rb +0 -96
- data/test/filters/test_kramdown.rb +0 -18
- data/test/filters/test_less.rb +0 -113
- data/test/filters/test_markaby.rb +0 -24
- data/test/filters/test_maruku.rb +0 -18
- data/test/filters/test_mustache.rb +0 -25
- data/test/filters/test_rainpress.rb +0 -29
- data/test/filters/test_rdiscount.rb +0 -31
- data/test/filters/test_rdoc.rb +0 -18
- data/test/filters/test_redcarpet.rb +0 -63
- data/test/filters/test_redcloth.rb +0 -33
- data/test/filters/test_relativize_paths.rb +0 -332
- data/test/filters/test_rubypants.rb +0 -18
- data/test/filters/test_sass.rb +0 -229
- data/test/filters/test_slim.rb +0 -35
- data/test/filters/test_typogruby.rb +0 -21
- data/test/filters/test_uglify_js.rb +0 -30
- data/test/gem_loader.rb +0 -11
- data/test/helper.rb +0 -179
- data/test/helpers/test_blogging.rb +0 -754
- data/test/helpers/test_breadcrumbs.rb +0 -81
- data/test/helpers/test_capturing.rb +0 -41
- data/test/helpers/test_filtering.rb +0 -106
- data/test/helpers/test_html_escape.rb +0 -32
- data/test/helpers/test_link_to.rb +0 -249
- data/test/helpers/test_rendering.rb +0 -89
- data/test/helpers/test_tagging.rb +0 -87
- data/test/helpers/test_text.rb +0 -24
- data/test/helpers/test_xml_sitemap.rb +0 -103
- data/test/tasks/test_clean.rb +0 -67
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
module Nanoc3::DataSources
|
|
4
|
-
|
|
5
|
-
# Provides functionality common across all filesystem data sources.
|
|
6
|
-
module Filesystem
|
|
7
|
-
|
|
8
|
-
# The VCS that will be called when adding, deleting and moving files. If
|
|
9
|
-
# no VCS has been set, or if the VCS has been set to `nil`, a dummy VCS
|
|
10
|
-
# will be returned.
|
|
11
|
-
#
|
|
12
|
-
# @return [Nanoc3::Extra::VCS, nil] The VCS that will be used.
|
|
13
|
-
def vcs
|
|
14
|
-
@vcs ||= Nanoc3::Extra::VCSes::Dummy.new
|
|
15
|
-
end
|
|
16
|
-
attr_writer :vcs
|
|
17
|
-
|
|
18
|
-
# See {Nanoc3::DataSource#up}.
|
|
19
|
-
def up
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# See {Nanoc3::DataSource#down}.
|
|
23
|
-
def down
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# See {Nanoc3::DataSource#setup}.
|
|
27
|
-
def setup
|
|
28
|
-
# Create directories
|
|
29
|
-
%w( content layouts ).each do |dir|
|
|
30
|
-
FileUtils.mkdir_p(dir)
|
|
31
|
-
vcs.add(dir)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# See {Nanoc3::DataSource#items}.
|
|
36
|
-
def items
|
|
37
|
-
load_objects('content', 'item', Nanoc3::Item)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# See {Nanoc3::DataSource#layouts}.
|
|
41
|
-
def layouts
|
|
42
|
-
load_objects('layouts', 'layout', Nanoc3::Layout)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# See {Nanoc3::DataSource#create_item}.
|
|
46
|
-
def create_item(content, attributes, identifier, params={})
|
|
47
|
-
create_object('content', content, attributes, identifier, params)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# See {Nanoc3::DataSource#create_layout}.
|
|
51
|
-
def create_layout(content, attributes, identifier, params={})
|
|
52
|
-
create_object('layouts', content, attributes, identifier, params)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
private
|
|
56
|
-
|
|
57
|
-
# Creates a new object (item or layout) on disk in dir_name according to
|
|
58
|
-
# the given identifier. The file will have its attributes taken from the
|
|
59
|
-
# attributes hash argument and its content from the content argument.
|
|
60
|
-
def create_object(dir_name, content, attributes, identifier, params={})
|
|
61
|
-
raise NotImplementedError.new(
|
|
62
|
-
"#{self.class} does not implement ##{name}"
|
|
63
|
-
)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Creates instances of klass corresponding to the files in dir_name. The
|
|
67
|
-
# kind attribute indicates the kind of object that is being loaded and is
|
|
68
|
-
# used solely for debugging purposes.
|
|
69
|
-
#
|
|
70
|
-
# This particular implementation loads objects from a filesystem-based
|
|
71
|
-
# data source where content and attributes can be spread over two separate
|
|
72
|
-
# files. The content and meta-file are optional (but at least one of them
|
|
73
|
-
# needs to be present, obviously) and the content file can start with a
|
|
74
|
-
# metadata section.
|
|
75
|
-
#
|
|
76
|
-
# @see Nanoc3::DataSources::Filesystem#load_objects
|
|
77
|
-
def load_objects(dir_name, kind, klass)
|
|
78
|
-
all_split_files_in(dir_name).map do |base_filename, (meta_ext, content_ext)|
|
|
79
|
-
# Get filenames
|
|
80
|
-
meta_filename = filename_for(base_filename, meta_ext)
|
|
81
|
-
content_filename = filename_for(base_filename, content_ext)
|
|
82
|
-
|
|
83
|
-
# Read content and metadata
|
|
84
|
-
is_binary = !!(content_filename && !@site.config[:text_extensions].include?(File.extname(content_filename)[1..-1]))
|
|
85
|
-
if is_binary && klass == Nanoc3::Item
|
|
86
|
-
meta = (meta_filename && YAML.load_file(meta_filename)) || {}
|
|
87
|
-
content_or_filename = content_filename
|
|
88
|
-
else
|
|
89
|
-
meta, content_or_filename = parse(content_filename, meta_filename, kind)
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# Get attributes
|
|
93
|
-
attributes = {
|
|
94
|
-
:filename => content_filename,
|
|
95
|
-
:content_filename => content_filename,
|
|
96
|
-
:meta_filename => meta_filename,
|
|
97
|
-
:extension => content_filename ? ext_of(content_filename)[1..-1] : nil,
|
|
98
|
-
# WARNING :file is deprecated; please create a File object manually
|
|
99
|
-
# using the :content_filename or :meta_filename attributes.
|
|
100
|
-
# TODO [in nanoc 4.0] remove me
|
|
101
|
-
:file => content_filename ? Nanoc3::Extra::FileProxy.new(content_filename) : nil
|
|
102
|
-
}.merge(meta)
|
|
103
|
-
|
|
104
|
-
# Get identifier
|
|
105
|
-
if meta_filename
|
|
106
|
-
identifier = identifier_for_filename(meta_filename[(dir_name.length+1)..-1])
|
|
107
|
-
elsif content_filename
|
|
108
|
-
identifier = identifier_for_filename(content_filename[(dir_name.length+1)..-1])
|
|
109
|
-
else
|
|
110
|
-
raise RuntimeError, "meta_filename and content_filename are both nil"
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
# Get modification times
|
|
114
|
-
meta_mtime = meta_filename ? File.stat(meta_filename).mtime : nil
|
|
115
|
-
content_mtime = content_filename ? File.stat(content_filename).mtime : nil
|
|
116
|
-
if meta_mtime && content_mtime
|
|
117
|
-
mtime = meta_mtime > content_mtime ? meta_mtime : content_mtime
|
|
118
|
-
elsif meta_mtime
|
|
119
|
-
mtime = meta_mtime
|
|
120
|
-
elsif content_mtime
|
|
121
|
-
mtime = content_mtime
|
|
122
|
-
else
|
|
123
|
-
raise RuntimeError, "meta_mtime and content_mtime are both nil"
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
# Create layout object
|
|
127
|
-
klass.new(
|
|
128
|
-
content_or_filename, attributes, identifier,
|
|
129
|
-
:binary => is_binary, :mtime => mtime
|
|
130
|
-
)
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
# Finds all items/layouts/... in the given base directory. Returns a hash
|
|
135
|
-
# in which the keys are the file's dirname + basenames, and the values a
|
|
136
|
-
# pair consisting of the metafile extension and the content file
|
|
137
|
-
# extension. The meta file extension or the content file extension can be
|
|
138
|
-
# nil, but not both. Backup files are ignored. For example:
|
|
139
|
-
#
|
|
140
|
-
# {
|
|
141
|
-
# 'content/foo' => [ 'yaml', 'html' ],
|
|
142
|
-
# 'content/bar' => [ 'yaml', nil ],
|
|
143
|
-
# 'content/qux' => [ nil, 'html' ]
|
|
144
|
-
# }
|
|
145
|
-
def all_split_files_in(dir_name)
|
|
146
|
-
# Get all good file names
|
|
147
|
-
filenames = Dir[dir_name + '/**/*'].select { |i| File.file?(i) }
|
|
148
|
-
filenames.reject! { |fn| fn =~ /(~|\.orig|\.rej|\.bak)$/ }
|
|
149
|
-
|
|
150
|
-
# Group by identifier
|
|
151
|
-
grouped_filenames = filenames.group_by { |fn| basename_of(fn) }
|
|
152
|
-
|
|
153
|
-
# Convert values into metafile/content file extension tuple
|
|
154
|
-
grouped_filenames.each_pair do |key, filenames|
|
|
155
|
-
# Divide
|
|
156
|
-
meta_filenames = filenames.select { |fn| ext_of(fn) == '.yaml' }
|
|
157
|
-
content_filenames = filenames.select { |fn| ext_of(fn) != '.yaml' }
|
|
158
|
-
|
|
159
|
-
# Check number of files per type
|
|
160
|
-
if ![ 0, 1 ].include?(meta_filenames.size)
|
|
161
|
-
raise RuntimeError, "Found #{meta_filenames.size} meta files for #{key}; expected 0 or 1"
|
|
162
|
-
end
|
|
163
|
-
if ![ 0, 1 ].include?(content_filenames.size)
|
|
164
|
-
raise RuntimeError, "Found #{content_filenames.size} content files for #{key}; expected 0 or 1"
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
# Reorder elements and convert to extnames
|
|
168
|
-
filenames[0] = meta_filenames[0] ? 'yaml' : nil
|
|
169
|
-
filenames[1] = content_filenames[0] ? ext_of(content_filenames[0])[1..-1] || '': nil
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
# Done
|
|
173
|
-
grouped_filenames
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
# Returns the filename for the given base filename and the extension.
|
|
177
|
-
#
|
|
178
|
-
# If the extension is nil, this function should return nil as well.
|
|
179
|
-
#
|
|
180
|
-
# A simple implementation would simply concatenate the base filename, a
|
|
181
|
-
# period and an extension (which is what the
|
|
182
|
-
# {Nanoc3::DataSources::FilesystemCompact} data source does), but other
|
|
183
|
-
# data sources may prefer to implement this differently (for example,
|
|
184
|
-
# {Nanoc3::DataSources::FilesystemVerbose} doubles the last part of the
|
|
185
|
-
# basename before concatenating it with a period and the extension).
|
|
186
|
-
def filename_for(base_filename, ext)
|
|
187
|
-
raise NotImplementedError.new(
|
|
188
|
-
"#{self.class} does not implement #filename_for"
|
|
189
|
-
)
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
# Returns the identifier that corresponds with the given filename, which
|
|
193
|
-
# can be the content filename or the meta filename.
|
|
194
|
-
def identifier_for_filename(filename)
|
|
195
|
-
raise NotImplementedError.new(
|
|
196
|
-
"#{self.class} does not implement #identifier_for_filename"
|
|
197
|
-
)
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
# Returns the base name of filename, i.e. filename with the first or all
|
|
201
|
-
# extensions stripped off. By default, all extensions are stripped off,
|
|
202
|
-
# but when allow_periods_in_identifiers is set to true in the site
|
|
203
|
-
# configuration, only the last extension will be stripped .
|
|
204
|
-
def basename_of(filename)
|
|
205
|
-
filename.sub(extension_regex, '')
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
# Returns the extension(s) of filename. Supports multiple extensions.
|
|
209
|
-
# Includes the leading period.
|
|
210
|
-
def ext_of(filename)
|
|
211
|
-
filename =~ extension_regex ? $1 : ''
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
# Returns a regex that is used for determining the extension of a file
|
|
215
|
-
# name. The first match group will be the entire extension, including the
|
|
216
|
-
# leading period.
|
|
217
|
-
def extension_regex
|
|
218
|
-
if @config && @config[:allow_periods_in_identifiers]
|
|
219
|
-
/(\.[^\/\.]+$)/
|
|
220
|
-
else
|
|
221
|
-
/(\.[^\/]+$)/
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
# Parses the file named `filename` and returns an array with its first
|
|
226
|
-
# element a hash with the file's metadata, and with its second element the
|
|
227
|
-
# file content itself.
|
|
228
|
-
def parse(content_filename, meta_filename, kind)
|
|
229
|
-
# Read content and metadata from separate files
|
|
230
|
-
if meta_filename
|
|
231
|
-
content = content_filename ? read(content_filename) : ''
|
|
232
|
-
meta = YAML.load(read(meta_filename)) || {}
|
|
233
|
-
|
|
234
|
-
return [ meta, content ]
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
# Read data
|
|
238
|
-
data = read(content_filename)
|
|
239
|
-
|
|
240
|
-
# Check presence of metadata section
|
|
241
|
-
if data !~ /\A-{3,5}\s*$/
|
|
242
|
-
return [ {}, data ]
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
# Split data
|
|
246
|
-
pieces = data.split(/^(-{5}|-{3})\s*$/)
|
|
247
|
-
if pieces.size < 4
|
|
248
|
-
raise RuntimeError.new(
|
|
249
|
-
"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."
|
|
250
|
-
)
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
# Parse
|
|
254
|
-
meta = YAML.load(pieces[2]) || {}
|
|
255
|
-
content = pieces[4..-1].join.strip
|
|
256
|
-
|
|
257
|
-
# Done
|
|
258
|
-
[ meta, content ]
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
# Reads the content of the file with the given name and returns a string
|
|
262
|
-
# in UTF-8 encoding. The original encoding of the string is derived from
|
|
263
|
-
# the default external encoding, but this can be overridden by the
|
|
264
|
-
# “encoding” configuration attribute in the data source configuration.
|
|
265
|
-
def read(filename)
|
|
266
|
-
# Read
|
|
267
|
-
begin
|
|
268
|
-
data = File.read(filename)
|
|
269
|
-
rescue => e
|
|
270
|
-
raise RuntimeError.new("Could not read #{filename}: #{e.inspect}")
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
# Fix
|
|
274
|
-
if data.respond_to?(:encode!)
|
|
275
|
-
if @config && @config[:encoding]
|
|
276
|
-
original_encoding = Encoding.find(@config[:encoding])
|
|
277
|
-
data.force_encoding(@config[:encoding])
|
|
278
|
-
else
|
|
279
|
-
original_encoding = data.encoding
|
|
280
|
-
end
|
|
281
|
-
|
|
282
|
-
data.encode!('UTF-8') rescue raise_encoding_error(filename, original_encoding)
|
|
283
|
-
raise_encoding_error(filename, original_encoding) if !data.valid_encoding?
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
# Remove UTF-8 BOM (ugly)
|
|
287
|
-
data.gsub!("\xEF\xBB\xBF", '')
|
|
288
|
-
|
|
289
|
-
data
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
# Raises an invalid encoding error for the given filename and encoding.
|
|
293
|
-
def raise_encoding_error(filename, encoding)
|
|
294
|
-
raise RuntimeError.new("Could not read #{filename} because the file is not valid #{encoding}.")
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
end
|
|
298
|
-
|
|
299
|
-
end
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
module Nanoc3::DataSources
|
|
4
|
-
|
|
5
|
-
# The filesystem_unified data source stores its items and layouts in nested
|
|
6
|
-
# directories. Items and layouts are represented by one or two files; if it
|
|
7
|
-
# is represented using one file, the metadata can be contained in this file.
|
|
8
|
-
# The root directory for items is the `content` directory; for layouts, this
|
|
9
|
-
# is the `layouts` directory.
|
|
10
|
-
#
|
|
11
|
-
# The metadata for items and layouts can be stored in a separate file with
|
|
12
|
-
# the same base name but with the `.yaml` extension. If such a file is
|
|
13
|
-
# found, metadata is read from that file. Alternatively, the content file
|
|
14
|
-
# itself can start with a metadata section: it can be stored at the top of
|
|
15
|
-
# the file, between `---` (three dashes) separators. For example:
|
|
16
|
-
#
|
|
17
|
-
# ---
|
|
18
|
-
# title: "Moo!"
|
|
19
|
-
# ---
|
|
20
|
-
# h1. Hello!
|
|
21
|
-
#
|
|
22
|
-
# The metadata section can be omitted. If the file does not start with
|
|
23
|
-
# three or five dashes, the entire file will be considered as content.
|
|
24
|
-
#
|
|
25
|
-
# The identifier of items and layouts is determined as follows. A file with
|
|
26
|
-
# an `index.*` filename, such as `index.txt`, will have the filesystem path
|
|
27
|
-
# with the `index.*` part stripped as a identifier. For example:
|
|
28
|
-
#
|
|
29
|
-
# foo/bar/index.html → /foo/bar/
|
|
30
|
-
#
|
|
31
|
-
# In other cases, the identifier is calculated by stripping the extension.
|
|
32
|
-
# If the `allow_periods_in_identifiers` attribute in the configuration is
|
|
33
|
-
# true, only the last extension will be stripped if the file has multiple
|
|
34
|
-
# extensions; if it is false or unset, all extensions will be stripped.
|
|
35
|
-
# For example:
|
|
36
|
-
#
|
|
37
|
-
# (`allow_periods_in_identifiers` set to true)
|
|
38
|
-
# foo.entry.html → /foo.entry/
|
|
39
|
-
#
|
|
40
|
-
# (`allow_periods_in_identifiers` set to false)
|
|
41
|
-
# foo.html.erb → /foo/
|
|
42
|
-
#
|
|
43
|
-
# Note that each item must have an unique identifier. nanoc will display an
|
|
44
|
-
# error if two items with the same identifier are found.
|
|
45
|
-
#
|
|
46
|
-
# Some more examples:
|
|
47
|
-
#
|
|
48
|
-
# content/index.html → /
|
|
49
|
-
# content/foo.html → /foo/
|
|
50
|
-
# content/foo/index.html → /foo/
|
|
51
|
-
# content/foo/bar.html → /foo/bar/
|
|
52
|
-
# content/foo/bar.baz.html → /foo/bar/ OR /foo/bar.baz/
|
|
53
|
-
# content/foo/bar/index.html → /foo/bar/
|
|
54
|
-
# content/foo.bar/index.html → /foo.bar/
|
|
55
|
-
#
|
|
56
|
-
# The file extension does not determine the filters to run on items; the
|
|
57
|
-
# Rules file is used to specify processing instructors for each item.
|
|
58
|
-
class FilesystemUnified < Nanoc3::DataSource
|
|
59
|
-
|
|
60
|
-
include Nanoc3::DataSources::Filesystem
|
|
61
|
-
|
|
62
|
-
private
|
|
63
|
-
|
|
64
|
-
# See {Nanoc3::DataSources::Filesystem#create_object}.
|
|
65
|
-
def create_object(dir_name, content, attributes, identifier, params={})
|
|
66
|
-
# Check for periods
|
|
67
|
-
if (@config.nil? || !@config[:allow_periods_in_identifiers]) && identifier.include?('.')
|
|
68
|
-
raise RuntimeError,
|
|
69
|
-
"Attempted to create an object in #{dir_name} with identifier #{identifier} containing a period, but allow_periods_in_identifiers is not enabled in the site configuration. (Enabling allow_periods_in_identifiers may cause the site to break, though.)"
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# Determine path
|
|
73
|
-
ext = params[:extension] || '.html'
|
|
74
|
-
path = dir_name + (identifier == '/' ? '/index.html' : identifier[0..-2] + ext)
|
|
75
|
-
parent_path = File.dirname(path)
|
|
76
|
-
|
|
77
|
-
# Notify
|
|
78
|
-
Nanoc3::NotificationCenter.post(:file_created, path)
|
|
79
|
-
|
|
80
|
-
# Write item
|
|
81
|
-
FileUtils.mkdir_p(parent_path)
|
|
82
|
-
File.open(path, 'w') do |io|
|
|
83
|
-
meta = attributes.stringify_keys
|
|
84
|
-
unless meta == {}
|
|
85
|
-
io.write(YAML.dump(meta).strip + "\n")
|
|
86
|
-
io.write("---\n\n")
|
|
87
|
-
end
|
|
88
|
-
io.write(content)
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# See {Nanoc3::DataSources::Filesystem#filename_for}.
|
|
93
|
-
def filename_for(base_filename, ext)
|
|
94
|
-
if ext.nil?
|
|
95
|
-
nil
|
|
96
|
-
elsif ext.empty?
|
|
97
|
-
base_filename
|
|
98
|
-
else
|
|
99
|
-
base_filename + '.' + ext
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# Returns the identifier derived from the given filename, first stripping
|
|
104
|
-
# the given directory name off the filename.
|
|
105
|
-
def identifier_for_filename(filename)
|
|
106
|
-
if filename =~ /(^|\/)index\.[^\/]+$/
|
|
107
|
-
regex = ((@config && @config[:allow_periods_in_identifiers]) ? /\/?index\.[^\/\.]+$/ : /\/?index\.[^\/]+$/)
|
|
108
|
-
else
|
|
109
|
-
regex = ((@config && @config[:allow_periods_in_identifiers]) ? /\.[^\/\.]+$/ : /\.[^\/]+$/)
|
|
110
|
-
end
|
|
111
|
-
filename.sub(regex, '').cleaned_identifier
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
end
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
module Nanoc3::DataSources
|
|
4
|
-
|
|
5
|
-
# The filesystem_verbose data source is the old data source for a new nanoc
|
|
6
|
-
# site. It stores all data as files on the hard disk.
|
|
7
|
-
#
|
|
8
|
-
# None of the methods are documented in this file. See {Nanoc3::DataSource}
|
|
9
|
-
# for documentation on the overridden methods instead.
|
|
10
|
-
#
|
|
11
|
-
# The filesystem_verbose data source stores its items and layouts in nested
|
|
12
|
-
# directories. Each directory represents a single item or layout. The root
|
|
13
|
-
# directory for items is the `content` directory; for layouts it is the
|
|
14
|
-
# `layouts` directory.
|
|
15
|
-
#
|
|
16
|
-
# Every directory has a content file and a meta file. The content file
|
|
17
|
-
# contains the actual item content, while the meta file contains the item’s
|
|
18
|
-
# or the layout’s metadata, formatted as YAML.
|
|
19
|
-
#
|
|
20
|
-
# Both content files and meta files are named after its parent directory
|
|
21
|
-
# (i.e. item). For example, an item/layout named `foo` will have a directory
|
|
22
|
-
# named `foo`, with e.g. a `foo.markdown` content file and a `foo.yaml` meta
|
|
23
|
-
# file.
|
|
24
|
-
#
|
|
25
|
-
# Content file extensions are not used for determining the filter that
|
|
26
|
-
# should be run; the meta file defines the list of filters. The meta file
|
|
27
|
-
# extension must always be `.yaml`, though.
|
|
28
|
-
#
|
|
29
|
-
# For backwards compatibility, content files can also have the `index`
|
|
30
|
-
# basename. Similarly, meta files can have the `meta` basename. For example,
|
|
31
|
-
# a parent directory named `foo` can have an `index.txt` content file and a
|
|
32
|
-
# `meta.yaml` meta file.
|
|
33
|
-
#
|
|
34
|
-
# The identifier is calculated by stripping the extension; if there is more
|
|
35
|
-
# than one extension, only the last extension is stripped and the previous
|
|
36
|
-
# extensions will be part of the identifier.
|
|
37
|
-
class FilesystemVerbose < Nanoc3::DataSource
|
|
38
|
-
|
|
39
|
-
include Nanoc3::DataSources::Filesystem
|
|
40
|
-
|
|
41
|
-
private
|
|
42
|
-
|
|
43
|
-
# See {Nanoc3::DataSources::Filesystem#create_object}.
|
|
44
|
-
def create_object(dir_name, content, attributes, identifier, params={})
|
|
45
|
-
# Determine base path
|
|
46
|
-
last_component = identifier.split('/')[-1] || dir_name
|
|
47
|
-
base_path = dir_name + identifier + last_component
|
|
48
|
-
|
|
49
|
-
# Get filenames
|
|
50
|
-
ext = params[:extension] || '.html'
|
|
51
|
-
dir_path = dir_name + identifier
|
|
52
|
-
meta_filename = dir_name + identifier + last_component + '.yaml'
|
|
53
|
-
content_filename = dir_name + identifier + last_component + ext
|
|
54
|
-
|
|
55
|
-
# Notify
|
|
56
|
-
Nanoc3::NotificationCenter.post(:file_created, meta_filename)
|
|
57
|
-
Nanoc3::NotificationCenter.post(:file_created, content_filename)
|
|
58
|
-
|
|
59
|
-
# Create files
|
|
60
|
-
FileUtils.mkdir_p(dir_path)
|
|
61
|
-
File.open(meta_filename, 'w') { |io| io.write(YAML.dump(attributes.stringify_keys)) }
|
|
62
|
-
File.open(content_filename, 'w') { |io| io.write(content) }
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# See {Nanoc3::DataSources::Filesystem#filename_for}.
|
|
66
|
-
def filename_for(base_filename, ext)
|
|
67
|
-
return nil if ext.nil?
|
|
68
|
-
|
|
69
|
-
last_component = base_filename[%r{[^/]+$}]
|
|
70
|
-
possibilities = [
|
|
71
|
-
base_filename + (ext.empty? ? '' : '.' + ext), # foo/bar.html
|
|
72
|
-
base_filename + '/' + last_component + (ext.empty? ? '' : '.' + ext), # foo/bar/bar.html
|
|
73
|
-
base_filename + '/' + 'index' + (ext.empty? ? '' : '.' + ext) # foo/bar/index.html
|
|
74
|
-
]
|
|
75
|
-
|
|
76
|
-
possibilities.find { |p| File.file?(p) }
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# See {Nanoc3::DataSources::Filesystem#identifier_for_filename}.
|
|
80
|
-
def identifier_for_filename(filename)
|
|
81
|
-
filename.sub(/[^\/]+\.yaml$/, '')
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
end
|