blackboard 3.1.6 → 3.1.7

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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +132 -0
  3. data/exe/jekyll +55 -0
  4. data/lib/jekyll.rb +179 -0
  5. data/lib/jekyll/cleaner.rb +105 -0
  6. data/lib/jekyll/collection.rb +205 -0
  7. data/lib/jekyll/command.rb +65 -0
  8. data/lib/jekyll/commands/build.rb +77 -0
  9. data/lib/jekyll/commands/clean.rb +42 -0
  10. data/lib/jekyll/commands/doctor.rb +114 -0
  11. data/lib/jekyll/commands/help.rb +31 -0
  12. data/lib/jekyll/commands/new.rb +82 -0
  13. data/lib/jekyll/commands/serve.rb +205 -0
  14. data/lib/jekyll/commands/serve/servlet.rb +61 -0
  15. data/lib/jekyll/configuration.rb +348 -0
  16. data/lib/jekyll/converter.rb +48 -0
  17. data/lib/jekyll/converters/identity.rb +21 -0
  18. data/lib/jekyll/converters/markdown.rb +92 -0
  19. data/lib/jekyll/converters/markdown/kramdown_parser.rb +117 -0
  20. data/lib/jekyll/converters/markdown/rdiscount_parser.rb +33 -0
  21. data/lib/jekyll/converters/markdown/redcarpet_parser.rb +102 -0
  22. data/lib/jekyll/converters/smartypants.rb +34 -0
  23. data/lib/jekyll/convertible.rb +300 -0
  24. data/lib/jekyll/deprecator.rb +46 -0
  25. data/lib/jekyll/document.rb +447 -0
  26. data/lib/jekyll/drops/collection_drop.rb +22 -0
  27. data/lib/jekyll/drops/document_drop.rb +60 -0
  28. data/lib/jekyll/drops/drop.rb +200 -0
  29. data/lib/jekyll/drops/excerpt_drop.rb +15 -0
  30. data/lib/jekyll/drops/jekyll_drop.rb +33 -0
  31. data/lib/jekyll/drops/site_drop.rb +38 -0
  32. data/lib/jekyll/drops/unified_payload_drop.rb +25 -0
  33. data/lib/jekyll/drops/url_drop.rb +83 -0
  34. data/lib/jekyll/entry_filter.rb +72 -0
  35. data/lib/jekyll/errors.rb +10 -0
  36. data/lib/jekyll/excerpt.rb +124 -0
  37. data/lib/jekyll/external.rb +59 -0
  38. data/lib/jekyll/filters.rb +367 -0
  39. data/lib/jekyll/frontmatter_defaults.rb +188 -0
  40. data/lib/jekyll/generator.rb +3 -0
  41. data/lib/jekyll/hooks.rb +101 -0
  42. data/lib/jekyll/layout.rb +49 -0
  43. data/lib/jekyll/liquid_extensions.rb +22 -0
  44. data/lib/jekyll/liquid_renderer.rb +39 -0
  45. data/lib/jekyll/liquid_renderer/file.rb +50 -0
  46. data/lib/jekyll/liquid_renderer/table.rb +94 -0
  47. data/lib/jekyll/log_adapter.rb +115 -0
  48. data/lib/jekyll/mime.types +800 -0
  49. data/lib/jekyll/page.rb +180 -0
  50. data/lib/jekyll/plugin.rb +96 -0
  51. data/lib/jekyll/plugin_manager.rb +95 -0
  52. data/lib/jekyll/publisher.rb +21 -0
  53. data/lib/jekyll/reader.rb +126 -0
  54. data/lib/jekyll/readers/collection_reader.rb +20 -0
  55. data/lib/jekyll/readers/data_reader.rb +69 -0
  56. data/lib/jekyll/readers/layout_reader.rb +53 -0
  57. data/lib/jekyll/readers/page_reader.rb +21 -0
  58. data/lib/jekyll/readers/post_reader.rb +62 -0
  59. data/lib/jekyll/readers/static_file_reader.rb +21 -0
  60. data/lib/jekyll/regenerator.rb +175 -0
  61. data/lib/jekyll/related_posts.rb +56 -0
  62. data/lib/jekyll/renderer.rb +194 -0
  63. data/lib/jekyll/site.rb +392 -0
  64. data/lib/jekyll/static_file.rb +141 -0
  65. data/lib/jekyll/stevenson.rb +58 -0
  66. data/lib/jekyll/tags/highlight.rb +122 -0
  67. data/lib/jekyll/tags/include.rb +190 -0
  68. data/lib/jekyll/tags/post_url.rb +88 -0
  69. data/lib/jekyll/url.rb +136 -0
  70. data/lib/jekyll/utils.rb +300 -0
  71. data/lib/jekyll/utils/ansi.rb +59 -0
  72. data/lib/jekyll/utils/platforms.rb +30 -0
  73. data/lib/jekyll/version.rb +3 -0
  74. data/lib/site_template/.gitignore +3 -0
  75. data/lib/site_template/_config.yml +24 -0
  76. data/lib/site_template/_includes/footer.html +38 -0
  77. data/lib/site_template/_includes/head.html +12 -0
  78. data/lib/site_template/_includes/header.html +27 -0
  79. data/lib/site_template/_includes/icon-github.html +1 -0
  80. data/lib/site_template/_includes/icon-github.svg +1 -0
  81. data/lib/site_template/_includes/icon-twitter.html +1 -0
  82. data/lib/site_template/_includes/icon-twitter.svg +1 -0
  83. data/lib/site_template/_layouts/default.html +20 -0
  84. data/lib/site_template/_layouts/page.html +14 -0
  85. data/lib/site_template/_layouts/post.html +15 -0
  86. data/lib/site_template/_pages/about.md +15 -0
  87. data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +25 -0
  88. data/lib/site_template/_sass/_base.scss +206 -0
  89. data/lib/site_template/_sass/_layout.scss +242 -0
  90. data/lib/site_template/_sass/_syntax-highlighting.scss +71 -0
  91. data/lib/site_template/css/main.scss +53 -0
  92. data/lib/site_template/feed.xml +30 -0
  93. data/lib/site_template/index.html +23 -0
  94. data/lib/theme_template/CODE_OF_CONDUCT.md.erb +74 -0
  95. data/lib/theme_template/Gemfile +2 -0
  96. data/lib/theme_template/LICENSE.txt.erb +21 -0
  97. data/lib/theme_template/README.md.erb +46 -0
  98. data/lib/theme_template/Rakefile.erb +74 -0
  99. data/lib/theme_template/_layouts/default.html +1 -0
  100. data/lib/theme_template/_layouts/page.html +5 -0
  101. data/lib/theme_template/_layouts/post.html +5 -0
  102. data/lib/theme_template/example/_config.yml.erb +1 -0
  103. data/lib/theme_template/example/_post.md +12 -0
  104. data/lib/theme_template/example/index.html +14 -0
  105. data/lib/theme_template/example/style.scss +7 -0
  106. data/lib/theme_template/gitignore.erb +4 -0
  107. data/lib/theme_template/theme.gemspec.erb +22 -0
  108. metadata +109 -2
@@ -0,0 +1,194 @@
1
+ # encoding: UTF-8
2
+
3
+ module Jekyll
4
+ class Renderer
5
+ attr_reader :document, :site, :payload
6
+
7
+ def initialize(site, document, site_payload = nil)
8
+ @site = site
9
+ @document = document
10
+ @payload = site_payload || site.site_payload
11
+ end
12
+
13
+ # Determine which converters to use based on this document's
14
+ # extension.
15
+ #
16
+ # Returns an array of Converter instances.
17
+ def converters
18
+ @converters ||= site.converters.select { |c| c.matches(document.extname) }
19
+ end
20
+
21
+ # Determine the extname the outputted file should have
22
+ #
23
+ # Returns the output extname including the leading period.
24
+ def output_ext
25
+ @output_ext ||= (permalink_ext || converter_output_ext)
26
+ end
27
+
28
+ ######################
29
+ ## DAT RENDER THO
30
+ ######################
31
+
32
+ def run
33
+ Jekyll.logger.debug "Rendering:", document.relative_path
34
+
35
+ payload["page"] = document.to_liquid
36
+
37
+ if document.respond_to? :pager
38
+ payload["paginator"] = document.pager.to_liquid
39
+ end
40
+
41
+ if document.is_a?(Document) && document.collection.label == 'posts'
42
+ payload['site']['related_posts'] = document.related_posts
43
+ end
44
+
45
+ # render and transform content (this becomes the final content of the object)
46
+ payload['highlighter_prefix'] = converters.first.highlighter_prefix
47
+ payload['highlighter_suffix'] = converters.first.highlighter_suffix
48
+
49
+ Jekyll.logger.debug "Pre-Render Hooks:", document.relative_path
50
+ document.trigger_hooks(:pre_render, payload)
51
+
52
+ info = {
53
+ :filters => [Jekyll::Filters],
54
+ :registers => { :site => site, :page => payload['page'] }
55
+ }
56
+
57
+ output = document.content
58
+
59
+ if document.render_with_liquid?
60
+ Jekyll.logger.debug "Rendering Liquid:", document.relative_path
61
+ output = render_liquid(output, payload, info, document.path)
62
+ end
63
+
64
+ Jekyll.logger.debug "Rendering Markup:", document.relative_path
65
+ output = convert(output)
66
+ document.content = output
67
+
68
+ if document.place_in_layout?
69
+ Jekyll.logger.debug "Rendering Layout:", document.relative_path
70
+ place_in_layouts(
71
+ output,
72
+ payload,
73
+ info
74
+ )
75
+ else
76
+ output
77
+ end
78
+ end
79
+
80
+ # Convert the given content using the converters which match this renderer's document.
81
+ #
82
+ # content - the raw, unconverted content
83
+ #
84
+ # Returns the converted content.
85
+ def convert(content)
86
+ converters.reduce(content) do |output, converter|
87
+ begin
88
+ converter.convert output
89
+ rescue => e
90
+ Jekyll.logger.error "Conversion error:", "#{converter.class} encountered an error while converting '#{document.relative_path}':"
91
+ Jekyll.logger.error("", e.to_s)
92
+ raise e
93
+ end
94
+ end
95
+ end
96
+
97
+ # Render the given content with the payload and info
98
+ #
99
+ # content -
100
+ # payload -
101
+ # info -
102
+ # path - (optional) the path to the file, for use in ex
103
+ #
104
+ # Returns the content, rendered by Liquid.
105
+ def render_liquid(content, payload, info, path = nil)
106
+ site.liquid_renderer.file(path).parse(content).render!(payload, info)
107
+ rescue Tags::IncludeTagError => e
108
+ Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{e.path}, included in #{path || document.relative_path}"
109
+ raise e
110
+ rescue Exception => e
111
+ Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{path || document.relative_path}"
112
+ raise e
113
+ end
114
+
115
+ # Checks if the layout specified in the document actually exists
116
+ #
117
+ # layout - the layout to check
118
+ #
119
+ # Returns true if the layout is invalid, false if otherwise
120
+ def invalid_layout?(layout)
121
+ !document.data["layout"].nil? && layout.nil?
122
+ end
123
+
124
+ # Render layouts and place given content inside.
125
+ #
126
+ # content - the content to be placed in the layout
127
+ #
128
+ #
129
+ # Returns the content placed in the Liquid-rendered layouts
130
+ def place_in_layouts(content, payload, info)
131
+ output = content.dup
132
+ layout = site.layouts[document.data["layout"]]
133
+
134
+ Jekyll.logger.warn("Build Warning:", "Layout '#{document.data["layout"]}' requested in #{document.relative_path} does not exist.") if invalid_layout? layout
135
+
136
+ used = Set.new([layout])
137
+
138
+ # Reset the payload layout data to ensure it starts fresh for each page.
139
+ payload["layout"] = nil
140
+
141
+ while layout
142
+ payload['content'] = output
143
+ payload['page'] = document.to_liquid
144
+ payload['layout'] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
145
+
146
+ output = render_liquid(
147
+ layout.content,
148
+ payload,
149
+ info,
150
+ File.join(site.config['layouts_dir'], layout.name)
151
+ )
152
+
153
+ # Add layout to dependency tree
154
+ site.regenerator.add_dependency(
155
+ site.in_source_dir(document.path),
156
+ site.in_source_dir(layout.path)
157
+ ) if document.write?
158
+
159
+ if layout = site.layouts[layout.data["layout"]]
160
+ if used.include?(layout)
161
+ layout = nil # avoid recursive chain
162
+ else
163
+ used << layout
164
+ end
165
+ end
166
+ end
167
+
168
+ output
169
+ end
170
+
171
+ private
172
+
173
+ def permalink_ext
174
+ if document.permalink && !document.permalink.end_with?("/")
175
+ permalink_ext = File.extname(document.permalink)
176
+ permalink_ext unless permalink_ext.empty?
177
+ end
178
+ end
179
+
180
+ def converter_output_ext
181
+ if output_exts.size == 1
182
+ output_exts.last
183
+ else
184
+ output_exts[-2]
185
+ end
186
+ end
187
+
188
+ def output_exts
189
+ @output_exts ||= converters.map do |c|
190
+ c.output_ext(document.extname)
191
+ end.compact
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,392 @@
1
+ # encoding: UTF-8
2
+ require 'csv'
3
+
4
+ module Jekyll
5
+ class Site
6
+ attr_reader :source, :dest, :config
7
+ attr_accessor :layouts, :pages, :static_files, :drafts,
8
+ :exclude, :include, :lsi, :highlighter, :permalink_style,
9
+ :time, :future, :unpublished, :safe, :plugins, :limit_posts,
10
+ :show_drafts, :keep_files, :baseurl, :data, :file_read_opts,
11
+ :gems, :plugin_manager
12
+
13
+ attr_accessor :converters, :generators, :reader
14
+ attr_reader :regenerator, :liquid_renderer
15
+
16
+ # Public: Initialize a new Site.
17
+ #
18
+ # config - A Hash containing site configuration details.
19
+ def initialize(config)
20
+ @config = config.clone
21
+
22
+ %w(safe lsi highlighter baseurl exclude include future unpublished
23
+ show_drafts limit_posts keep_files gems).each do |opt|
24
+ self.send("#{opt}=", config[opt])
25
+ end
26
+
27
+ # Source and destination may not be changed after the site has been created.
28
+ @source = File.expand_path(config['source']).freeze
29
+ @dest = File.expand_path(config['destination']).freeze
30
+
31
+ @reader = Jekyll::Reader.new(self)
32
+
33
+ # Initialize incremental regenerator
34
+ @regenerator = Regenerator.new(self)
35
+
36
+ @liquid_renderer = LiquidRenderer.new(self)
37
+
38
+ self.plugin_manager = Jekyll::PluginManager.new(self)
39
+ self.plugins = plugin_manager.plugins_path
40
+
41
+ self.file_read_opts = {}
42
+ self.file_read_opts[:encoding] = config['encoding'] if config['encoding']
43
+
44
+ self.permalink_style = config['permalink'].to_sym
45
+
46
+ Jekyll.sites << self
47
+
48
+ reset
49
+ setup
50
+ end
51
+
52
+ # Public: Read, process, and write this Site to output.
53
+ #
54
+ # Returns nothing.
55
+ def process
56
+ reset
57
+ read
58
+ generate
59
+ render
60
+ cleanup
61
+ write
62
+ print_stats
63
+ end
64
+
65
+ def print_stats
66
+ if @config['profile']
67
+ puts @liquid_renderer.stats_table
68
+ end
69
+ end
70
+
71
+ # Reset Site details.
72
+ #
73
+ # Returns nothing
74
+ def reset
75
+ self.time = (config['time'] ? Utils.parse_date(config['time'].to_s, "Invalid time in _config.yml.") : Time.now)
76
+ self.layouts = {}
77
+ self.pages = []
78
+ self.static_files = []
79
+ self.data = {}
80
+ @collections = nil
81
+ @regenerator.clear_cache
82
+ @liquid_renderer.reset
83
+
84
+ if limit_posts < 0
85
+ raise ArgumentError, "limit_posts must be a non-negative number"
86
+ end
87
+
88
+ Jekyll::Hooks.trigger :site, :after_reset, self
89
+ end
90
+
91
+ # Load necessary libraries, plugins, converters, and generators.
92
+ #
93
+ # Returns nothing.
94
+ def setup
95
+ ensure_not_in_dest
96
+
97
+ plugin_manager.conscientious_require
98
+
99
+ self.converters = instantiate_subclasses(Jekyll::Converter)
100
+ self.generators = instantiate_subclasses(Jekyll::Generator)
101
+ end
102
+
103
+ # Check that the destination dir isn't the source dir or a directory
104
+ # parent to the source dir.
105
+ def ensure_not_in_dest
106
+ dest_pathname = Pathname.new(dest)
107
+ Pathname.new(source).ascend do |path|
108
+ if path == dest_pathname
109
+ raise Errors::FatalException.new "Destination directory cannot be or contain the Source directory."
110
+ end
111
+ end
112
+ end
113
+
114
+ # The list of collections and their corresponding Jekyll::Collection instances.
115
+ # If config['collections'] is set, a new instance is created for each item in the collection.
116
+ # If config['collections'] is not set, a new hash is returned.
117
+ #
118
+ # Returns a Hash containing collection name-to-instance pairs.
119
+ def collections
120
+ @collections ||= Hash[collection_names.map { |coll| [coll, Jekyll::Collection.new(self, coll)] } ]
121
+ end
122
+
123
+ # The list of collection names.
124
+ #
125
+ # Returns an array of collection names from the configuration,
126
+ # or an empty array if the `collections` key is not set.
127
+ def collection_names
128
+ case config['collections']
129
+ when Hash
130
+ config['collections'].keys
131
+ when Array
132
+ config['collections']
133
+ when nil
134
+ []
135
+ else
136
+ raise ArgumentError, "Your `collections` key must be a hash or an array."
137
+ end
138
+ end
139
+
140
+ # Read Site data from disk and load it into internal data structures.
141
+ #
142
+ # Returns nothing.
143
+ def read
144
+ reader.read
145
+ limit_posts!
146
+ Jekyll::Hooks.trigger :site, :post_read, self
147
+ end
148
+
149
+ # Run each of the Generators.
150
+ #
151
+ # Returns nothing.
152
+ def generate
153
+ generators.each do |generator|
154
+ generator.generate(self)
155
+ end
156
+ end
157
+
158
+ # Render the site to the destination.
159
+ #
160
+ # Returns nothing.
161
+ def render
162
+ relative_permalinks_are_deprecated
163
+
164
+ payload = site_payload
165
+
166
+ Jekyll::Hooks.trigger :site, :pre_render, self, payload
167
+
168
+ collections.each do |_, collection|
169
+ collection.docs.each do |document|
170
+ if regenerator.regenerate?(document)
171
+ document.output = Jekyll::Renderer.new(self, document, payload).run
172
+ document.trigger_hooks(:post_render)
173
+ end
174
+ end
175
+ end
176
+
177
+ pages.flatten.each do |page|
178
+ if regenerator.regenerate?(page)
179
+ page.output = Jekyll::Renderer.new(self, page, payload).run
180
+ page.trigger_hooks(:post_render)
181
+ end
182
+ end
183
+
184
+ Jekyll::Hooks.trigger :site, :post_render, self, payload
185
+ rescue Errno::ENOENT
186
+ # ignore missing layout dir
187
+ end
188
+
189
+ # Remove orphaned files and empty directories in destination.
190
+ #
191
+ # Returns nothing.
192
+ def cleanup
193
+ site_cleaner.cleanup!
194
+ end
195
+
196
+ # Write static files, pages, and posts.
197
+ #
198
+ # Returns nothing.
199
+ def write
200
+ each_site_file do |item|
201
+ item.write(dest) if regenerator.regenerate?(item)
202
+ end
203
+ regenerator.write_metadata
204
+ Jekyll::Hooks.trigger :site, :post_write, self
205
+ end
206
+
207
+ def posts
208
+ collections['posts'] ||= Collection.new(self, 'posts')
209
+ end
210
+
211
+ # Construct a Hash of Posts indexed by the specified Post attribute.
212
+ #
213
+ # post_attr - The String name of the Post attribute.
214
+ #
215
+ # Examples
216
+ #
217
+ # post_attr_hash('categories')
218
+ # # => { 'tech' => [<Post A>, <Post B>],
219
+ # # 'ruby' => [<Post B>] }
220
+ #
221
+ # Returns the Hash: { attr => posts } where
222
+ # attr - One of the values for the requested attribute.
223
+ # posts - The Array of Posts with the given attr value.
224
+ def post_attr_hash(post_attr)
225
+ # Build a hash map based on the specified post attribute ( post attr =>
226
+ # array of posts ) then sort each array in reverse order.
227
+ hash = Hash.new { |h, key| h[key] = [] }
228
+ posts.docs.each { |p| p.data[post_attr].each { |t| hash[t] << p } if p.data[post_attr] }
229
+ hash.values.each { |posts| posts.sort!.reverse! }
230
+ hash
231
+ end
232
+
233
+ def tags
234
+ post_attr_hash('tags')
235
+ end
236
+
237
+ def categories
238
+ post_attr_hash('categories')
239
+ end
240
+
241
+ # Prepare site data for site payload. The method maintains backward compatibility
242
+ # if the key 'data' is already used in _config.yml.
243
+ #
244
+ # Returns the Hash to be hooked to site.data.
245
+ def site_data
246
+ config['data'] || data
247
+ end
248
+
249
+ # The Hash payload containing site-wide data.
250
+ #
251
+ # Returns the Hash: { "site" => data } where data is a Hash with keys:
252
+ # "time" - The Time as specified in the configuration or the
253
+ # current time if none was specified.
254
+ # "posts" - The Array of Posts, sorted chronologically by post date
255
+ # and then title.
256
+ # "pages" - The Array of all Pages.
257
+ # "html_pages" - The Array of HTML Pages.
258
+ # "categories" - The Hash of category values and Posts.
259
+ # See Site#post_attr_hash for type info.
260
+ # "tags" - The Hash of tag values and Posts.
261
+ # See Site#post_attr_hash for type info.
262
+ def site_payload
263
+ Drops::UnifiedPayloadDrop.new self
264
+ end
265
+ alias_method :to_liquid, :site_payload
266
+
267
+ # Get the implementation class for the given Converter.
268
+ # Returns the Converter instance implementing the given Converter.
269
+ # klass - The Class of the Converter to fetch.
270
+
271
+ def find_converter_instance(klass)
272
+ converters.find { |klass_| klass_.instance_of?(klass) } || \
273
+ raise("No Converters found for #{klass}")
274
+ end
275
+
276
+ # klass - class or module containing the subclasses.
277
+ # Returns array of instances of subclasses of parameter.
278
+ # Create array of instances of the subclasses of the class or module
279
+ # passed in as argument.
280
+
281
+ def instantiate_subclasses(klass)
282
+ klass.descendants.select { |c| !safe || c.safe }.sort.map do |c|
283
+ c.new(config)
284
+ end
285
+ end
286
+
287
+ # Warns the user if permanent links are relative to the parent
288
+ # directory. As this is a deprecated function of Jekyll.
289
+ #
290
+ # Returns
291
+ def relative_permalinks_are_deprecated
292
+ if config['relative_permalinks']
293
+ Jekyll.logger.abort_with "Since v3.0, permalinks for pages" \
294
+ " in subfolders must be relative to the" \
295
+ " site source directory, not the parent" \
296
+ " directory. Check http://jekyllrb.com/docs/upgrading/"\
297
+ " for more info."
298
+ end
299
+ end
300
+
301
+ # Get the to be written documents
302
+ #
303
+ # Returns an Array of Documents which should be written
304
+ def docs_to_write
305
+ documents.select(&:write?)
306
+ end
307
+
308
+ # Get all the documents
309
+ #
310
+ # Returns an Array of all Documents
311
+ def documents
312
+ collections.reduce(Set.new) do |docs, (_, collection)|
313
+ docs + collection.docs + collection.files
314
+ end.to_a
315
+ end
316
+
317
+ def each_site_file
318
+ %w(pages static_files docs_to_write).each do |type|
319
+ send(type).each do |item|
320
+ yield item
321
+ end
322
+ end
323
+ end
324
+
325
+ # Returns the FrontmatterDefaults or creates a new FrontmatterDefaults
326
+ # if it doesn't already exist.
327
+ #
328
+ # Returns The FrontmatterDefaults
329
+ def frontmatter_defaults
330
+ @frontmatter_defaults ||= FrontmatterDefaults.new(self)
331
+ end
332
+
333
+ # Whether to perform a full rebuild without incremental regeneration
334
+ #
335
+ # Returns a Boolean: true for a full rebuild, false for normal build
336
+ def incremental?(override = {})
337
+ override['incremental'] || config['incremental']
338
+ end
339
+
340
+ # Returns the publisher or creates a new publisher if it doesn't
341
+ # already exist.
342
+ #
343
+ # Returns The Publisher
344
+ def publisher
345
+ @publisher ||= Publisher.new(self)
346
+ end
347
+
348
+ # Public: Prefix a given path with the source directory.
349
+ #
350
+ # paths - (optional) path elements to a file or directory within the
351
+ # source directory
352
+ #
353
+ # Returns a path which is prefixed with the source directory.
354
+ def in_source_dir(*paths)
355
+ paths.reduce(source) do |base, path|
356
+ Jekyll.sanitized_path(base, path)
357
+ end
358
+ end
359
+
360
+ # Public: Prefix a given path with the destination directory.
361
+ #
362
+ # paths - (optional) path elements to a file or directory within the
363
+ # destination directory
364
+ #
365
+ # Returns a path which is prefixed with the destination directory.
366
+ def in_dest_dir(*paths)
367
+ paths.reduce(dest) do |base, path|
368
+ Jekyll.sanitized_path(base, path)
369
+ end
370
+ end
371
+
372
+ private
373
+
374
+ # Limits the current posts; removes the posts which exceed the limit_posts
375
+ #
376
+ # Returns nothing
377
+ def limit_posts!
378
+ if limit_posts > 0
379
+ limit = posts.docs.length < limit_posts ? posts.docs.length : limit_posts
380
+ self.posts.docs = posts.docs[-limit, limit]
381
+ end
382
+ end
383
+
384
+ # Returns the Cleaner or creates a new Cleaner if it doesn't
385
+ # already exist.
386
+ #
387
+ # Returns The Cleaner
388
+ def site_cleaner
389
+ @site_cleaner ||= Cleaner.new(self)
390
+ end
391
+ end
392
+ end