jekyll 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of jekyll might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1bd7e49f4d0c08e3a671d21444bc80a53ef6c4a0
4
- data.tar.gz: 8eec4bc8581b8abd01c7bf077b79980af61537b7
3
+ metadata.gz: 45083d9a5aaf050f5b5dc16a09c7d4001db30856
4
+ data.tar.gz: 4bfa431a22f2d147963b49e6664584a43f9cdbc3
5
5
  SHA512:
6
- metadata.gz: 6688a5be7d34576575ec1098fe5f80c2f625c6a4eefa5869bcb64a9ce41fe8d5c05424c9105fbcdc88f44512fa663aafd458da75e0672b1bd97b328c42af65a0
7
- data.tar.gz: 0ce421c5435ad40f8cf231e38891a6949a827a75964b7c2c426654f2746507ed1f77a1cba06be22f709bc77cd7949a81cedf6510c629d3ee463fb41d957cefde
6
+ metadata.gz: 289e5fd56eccf356d07eca309241ac9ef9a11c020bd218c394d1499d2984d88c49e842697e07b0d576147ee3b1937d7046d290e31a3d49430f4373e168f0de49
7
+ data.tar.gz: 11c5a946bbb64cfbb560db1a28be0534131391b3353a1e55e5ae3aa05bccc2cf28386a879bb91b9ce9068173d63747409df80b1694e54ef8779ce12f0697c65f
@@ -41,7 +41,7 @@ module Jekyll
41
41
  doc.read
42
42
  docs << doc
43
43
  else
44
- relative_dir = File.join(relative_directory, File.dirname(file_path)).chomp("/.")
44
+ relative_dir = Jekyll.sanitized_path(relative_directory, File.dirname(file_path)).chomp("/.")
45
45
  files << StaticFile.new(site, site.source, relative_dir, File.basename(full_path), self)
46
46
  end
47
47
  end
@@ -51,7 +51,7 @@ module Jekyll
51
51
  c.option 'config', '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
52
52
  c.option 'future', '--future', 'Publishes posts with a future date'
53
53
  c.option 'limit_posts', '--limit_posts MAX_POSTS', Integer, 'Limits the number of posts to parse and publish'
54
- c.option 'watch', '-w', '--watch', 'Watch for changes and rebuild'
54
+ c.option 'watch', '-w', '--[no-]watch', 'Watch for changes and rebuild'
55
55
  c.option 'force_polling', '--force_polling', 'Force watch to use polling'
56
56
  c.option 'lsi', '--lsi', 'Use LSI for improved related posts'
57
57
  c.option 'show_drafts', '-D', '--drafts', 'Render posts in the _drafts folder'
@@ -3,78 +3,80 @@ require 'erb'
3
3
  module Jekyll
4
4
  module Commands
5
5
  class New < Command
6
- def self.init_with_program(prog)
7
- prog.command(:new) do |c|
8
- c.syntax 'new PATH'
9
- c.description 'Creates a new Jekyll site scaffold in PATH'
10
-
11
- c.option 'force', '--force', 'Force creation even if PATH already exists'
12
- c.option 'blank', '--blank', 'Creates scaffolding but with empty files'
13
-
14
- c.action do |args, options|
15
- Jekyll::Commands::New.process(args, options)
6
+ class << self
7
+ def init_with_program(prog)
8
+ prog.command(:new) do |c|
9
+ c.syntax 'new PATH'
10
+ c.description 'Creates a new Jekyll site scaffold in PATH'
11
+
12
+ c.option 'force', '--force', 'Force creation even if PATH already exists'
13
+ c.option 'blank', '--blank', 'Creates scaffolding but with empty files'
14
+
15
+ c.action do |args, options|
16
+ Jekyll::Commands::New.process(args, options)
17
+ end
16
18
  end
17
19
  end
18
- end
19
20
 
20
- def self.process(args, options = {})
21
- raise ArgumentError.new('You must specify a path.') if args.empty?
21
+ def process(args, options = {})
22
+ raise ArgumentError.new('You must specify a path.') if args.empty?
22
23
 
23
- new_blog_path = File.expand_path(args.join(" "), Dir.pwd)
24
- FileUtils.mkdir_p new_blog_path
25
- if preserve_source_location?(new_blog_path, options)
26
- Jekyll.logger.abort_with "Conflict:", "#{new_blog_path} exists and is not empty."
27
- end
24
+ new_blog_path = File.expand_path(args.join(" "), Dir.pwd)
25
+ FileUtils.mkdir_p new_blog_path
26
+ if preserve_source_location?(new_blog_path, options)
27
+ Jekyll.logger.abort_with "Conflict:", "#{new_blog_path} exists and is not empty."
28
+ end
28
29
 
29
- if options["blank"]
30
- create_blank_site new_blog_path
31
- else
32
- create_sample_files new_blog_path
30
+ if options["blank"]
31
+ create_blank_site new_blog_path
32
+ else
33
+ create_sample_files new_blog_path
33
34
 
34
- File.open(File.expand_path(initialized_post_name, new_blog_path), "w") do |f|
35
- f.write(scaffold_post_content)
35
+ File.open(File.expand_path(initialized_post_name, new_blog_path), "w") do |f|
36
+ f.write(scaffold_post_content)
37
+ end
36
38
  end
37
- end
38
39
 
39
- Jekyll.logger.info "New jekyll site installed in #{new_blog_path}."
40
- end
40
+ Jekyll.logger.info "New jekyll site installed in #{new_blog_path}."
41
+ end
41
42
 
42
- def self.create_blank_site(path)
43
- Dir.chdir(path) do
44
- FileUtils.mkdir(%w(_layouts _posts _drafts))
45
- FileUtils.touch("index.html")
43
+ def create_blank_site(path)
44
+ Dir.chdir(path) do
45
+ FileUtils.mkdir(%w(_layouts _posts _drafts))
46
+ FileUtils.touch("index.html")
47
+ end
46
48
  end
47
- end
48
49
 
49
- def self.scaffold_post_content
50
- ERB.new(File.read(File.expand_path(scaffold_path, site_template))).result
51
- end
50
+ def scaffold_post_content
51
+ ERB.new(File.read(File.expand_path(scaffold_path, site_template))).result
52
+ end
52
53
 
53
- # Internal: Gets the filename of the sample post to be created
54
- #
55
- # Returns the filename of the sample post, as a String
56
- def self.initialized_post_name
57
- "_posts/#{Time.now.strftime('%Y-%m-%d')}-welcome-to-jekyll.markdown"
58
- end
54
+ # Internal: Gets the filename of the sample post to be created
55
+ #
56
+ # Returns the filename of the sample post, as a String
57
+ def initialized_post_name
58
+ "_posts/#{Time.now.strftime('%Y-%m-%d')}-welcome-to-jekyll.markdown"
59
+ end
59
60
 
60
- private
61
+ private
61
62
 
62
- def self.preserve_source_location?(path, options)
63
- !options["force"] && !Dir["#{path}/**/*"].empty?
64
- end
63
+ def preserve_source_location?(path, options)
64
+ !options["force"] && !Dir["#{path}/**/*"].empty?
65
+ end
65
66
 
66
- def self.create_sample_files(path)
67
- FileUtils.cp_r site_template + '/.', path
68
- FileUtils.rm File.expand_path(scaffold_path, path)
69
- end
67
+ def create_sample_files(path)
68
+ FileUtils.cp_r site_template + '/.', path
69
+ FileUtils.rm File.expand_path(scaffold_path, path)
70
+ end
70
71
 
71
- def self.site_template
72
- File.expand_path("../../site_template", File.dirname(__FILE__))
73
- end
72
+ def site_template
73
+ File.expand_path("../../site_template", File.dirname(__FILE__))
74
+ end
74
75
 
75
- def self.scaffold_path
76
- "_posts/0000-00-00-welcome-to-jekyll.markdown.erb"
77
- end
76
+ def scaffold_path
77
+ "_posts/0000-00-00-welcome-to-jekyll.markdown.erb"
78
+ end
79
+ end
78
80
  end
79
81
  end
80
82
  end
@@ -20,7 +20,8 @@ module Jekyll
20
20
  c.option 'skip_initial_build', '--skip-initial-build', 'Skips the initial site build which occurs before the server is started.'
21
21
 
22
22
  c.action do |args, options|
23
- options["serving"] ||= true
23
+ options["serving"] = true
24
+ options["watch"] = true unless options.key?("watch")
24
25
  Jekyll::Commands::Build.process(options)
25
26
  Jekyll::Commands::Serve.process(options)
26
27
  end
@@ -211,7 +211,7 @@ module Jekyll
211
211
  if config.key?('auto') || config.key?('watch')
212
212
  Jekyll.logger.warn "Deprecation:", "Auto-regeneration can no longer" +
213
213
  " be set from your configuration file(s). Use the"+
214
- " --watch/-w command-line option instead."
214
+ " --[no-]watch/-w command-line option instead."
215
215
  config.delete('auto')
216
216
  config.delete('watch')
217
217
  end
@@ -67,6 +67,7 @@ module Jekyll
67
67
  converter.convert output
68
68
  rescue => e
69
69
  Jekyll.logger.error "Conversion error:", "#{converter.class} encountered an error converting '#{path}'."
70
+ Jekyll.logger.error("Conversion error:", e.to_s)
70
71
  raise e
71
72
  end
72
73
  end
@@ -162,16 +163,14 @@ module Jekyll
162
163
 
163
164
  # Determine whether the file should be rendered with Liquid.
164
165
  #
165
- # Returns false if the document is either an asset file or a yaml file,
166
- # true otherwise.
166
+ # Always returns true.
167
167
  def render_with_liquid?
168
- !coffeescript_file?
168
+ true
169
169
  end
170
170
 
171
171
  # Determine whether the file should be placed into layouts.
172
172
  #
173
- # Returns false if the document is either an asset file or a yaml file,
174
- # true otherwise.
173
+ # Returns false if the document is an asset file.
175
174
  def place_in_layout?
176
175
  !asset_file?
177
176
  end
@@ -128,7 +128,9 @@ module Jekyll
128
128
  {
129
129
  collection: collection.label,
130
130
  path: cleaned_relative_path,
131
- output_ext: Jekyll::Renderer.new(site, self).output_ext
131
+ output_ext: Jekyll::Renderer.new(site, self).output_ext,
132
+ name: Utils.slugify(basename(".*")),
133
+ title: Utils.slugify(data['title']) || Utils.slugify(basename(".*"))
132
134
  }
133
135
  end
134
136
 
@@ -47,6 +47,17 @@ module Jekyll
47
47
  converter.convert(input)
48
48
  end
49
49
 
50
+ # Slugify a filename or title.
51
+ #
52
+ # input - The filename or title to slugify.
53
+ #
54
+ # Returns the given filename or title as a lowercase String, with every
55
+ # sequence of spaces and non-alphanumeric characters replaced with a
56
+ # hyphen.
57
+ def slugify(input)
58
+ Utils.slugify(input)
59
+ end
60
+
50
61
  # Format a date in short format e.g. "27 Jan 2011".
51
62
  #
52
63
  # date - the Time to format.
@@ -203,7 +214,7 @@ module Jekyll
203
214
  # Filter an array of objects
204
215
  #
205
216
  # input - the object array
206
- # key - key within each object to filter by
217
+ # property - property within each object to filter by
207
218
  # value - desired value
208
219
  #
209
220
  # Returns the filtered array of objects
@@ -248,6 +259,43 @@ module Jekyll
248
259
  end
249
260
  end
250
261
 
262
+ def pop(array, input = 1)
263
+ return array unless array.is_a?(Array)
264
+ new_ary = array.dup
265
+ new_ary.pop(input.to_i || 1)
266
+ new_ary
267
+ end
268
+
269
+ def push(array, input)
270
+ return array unless array.is_a?(Array)
271
+ new_ary = array.dup
272
+ new_ary.push(input)
273
+ new_ary
274
+ end
275
+
276
+ def shift(array, input = 1)
277
+ return array unless array.is_a?(Array)
278
+ new_ary = array.dup
279
+ new_ary.shift(input.to_i || 1)
280
+ new_ary
281
+ end
282
+
283
+ def unshift(array, input)
284
+ return array unless array.is_a?(Array)
285
+ new_ary = array.dup
286
+ new_ary.unshift(input)
287
+ new_ary
288
+ end
289
+
290
+ # Convert an object into its String representation for debugging
291
+ #
292
+ # input - The Object to be converted
293
+ #
294
+ # Returns a String representation of the object.
295
+ def inspect(input)
296
+ CGI.escapeHTML(input.inspect)
297
+ end
298
+
251
299
  private
252
300
  def time(input)
253
301
  case input
@@ -1,4 +1,5 @@
1
1
  # encoding: UTF-8
2
+ require 'csv'
2
3
 
3
4
  module Jekyll
4
5
  class Site
@@ -212,7 +213,7 @@ module Jekyll
212
213
  return unless File.directory?(dir) && (!safe || !File.symlink?(dir))
213
214
 
214
215
  entries = Dir.chdir(dir) do
215
- Dir['*.{yaml,yml,json}'] + Dir['*'].select { |fn| File.directory?(fn) }
216
+ Dir['*.{yaml,yml,json,csv}'] + Dir['*'].select { |fn| File.directory?(fn) }
216
217
  end
217
218
 
218
219
  entries.each do |entry|
@@ -223,7 +224,12 @@ module Jekyll
223
224
  if File.directory?(path)
224
225
  read_data_to(path, data[key] = {})
225
226
  else
226
- data[key] = SafeYAML.load_file(path)
227
+ case File.extname(path).downcase
228
+ when '.csv'
229
+ data[key] = CSV.read(path, :headers => true).map(&:to_hash)
230
+ else
231
+ data[key] = SafeYAML.load_file(path)
232
+ end
227
233
  end
228
234
  end
229
235
  end
@@ -13,13 +13,9 @@ module Jekyll
13
13
 
14
14
  class IncludeTag < Liquid::Tag
15
15
 
16
- SYNTAX_EXAMPLE = "{% include file.ext param='value' param2='value' %}"
17
-
18
16
  VALID_SYNTAX = /([\w-]+)\s*=\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))/
19
17
  VARIABLE_SYNTAX = /(?<variable>[^{]*\{\{\s*(?<name>[\w\-\.]+)\s*(\|.*)?\}\}[^\s}]*)(?<params>.*)/
20
18
 
21
- INCLUDES_DIR = '_includes'
22
-
23
19
  def initialize(tag_name, markup, tokens)
24
20
  super
25
21
  matched = markup.strip.match(VARIABLE_SYNTAX)
@@ -30,6 +26,11 @@ module Jekyll
30
26
  @file, @params = markup.strip.split(' ', 2);
31
27
  end
32
28
  validate_params if @params
29
+ @tag_name = tag_name
30
+ end
31
+
32
+ def syntax_example
33
+ "{% #{@tag_name} file.ext param='value' param2='value' %}"
33
34
  end
34
35
 
35
36
  def parse_params(context)
@@ -61,7 +62,7 @@ Invalid syntax for include tag. File contains invalid characters or sequences:
61
62
 
62
63
  Valid syntax:
63
64
 
64
- #{SYNTAX_EXAMPLE}
65
+ #{syntax_example}
65
66
 
66
67
  eos
67
68
  end
@@ -77,7 +78,7 @@ Invalid syntax for include tag:
77
78
 
78
79
  Valid syntax:
79
80
 
80
- #{SYNTAX_EXAMPLE}
81
+ #{syntax_example}
81
82
 
82
83
  eos
83
84
  end
@@ -96,8 +97,12 @@ eos
96
97
  end
97
98
  end
98
99
 
100
+ def includes_dir
101
+ '_includes'
102
+ end
103
+
99
104
  def render(context)
100
- dir = File.join(File.realpath(context.registers[:site].source), INCLUDES_DIR)
105
+ dir = resolved_includes_dir(context)
101
106
 
102
107
  file = render_variable(context) || @file
103
108
  validate_file_name(file)
@@ -113,10 +118,14 @@ eos
113
118
  partial.render!(context)
114
119
  end
115
120
  rescue => e
116
- raise IncludeTagError.new e.message, File.join(INCLUDES_DIR, @file)
121
+ raise IncludeTagError.new e.message, File.join(includes_dir, @file)
117
122
  end
118
123
  end
119
124
 
125
+ def resolved_includes_dir(context)
126
+ File.join(File.realpath(context.registers[:site].source), includes_dir)
127
+ end
128
+
120
129
  def validate_path(path, dir, safe)
121
130
  if safe && !realpath_prefixed_with?(path, dir)
122
131
  raise IOError.new "The included file '#{path}' should exist and should not be a symlink"
@@ -126,7 +135,7 @@ eos
126
135
  end
127
136
 
128
137
  def path_relative_to_source(dir, path)
129
- File.join(INCLUDES_DIR, path.sub(Regexp.new("^#{dir}"), ""))
138
+ File.join(includes_dir, path.sub(Regexp.new("^#{dir}"), ""))
130
139
  end
131
140
 
132
141
  def realpath_prefixed_with?(path, dir)
@@ -138,7 +147,19 @@ eos
138
147
  File.read(file, file_read_opts(context))
139
148
  end
140
149
  end
150
+
151
+ class IncludeRelativeTag < IncludeTag
152
+ def includes_dir
153
+ '.'
154
+ end
155
+
156
+ def resolved_includes_dir(context)
157
+ page_path = context.registers[:page].nil? ? includes_dir : File.dirname(context.registers[:page]["path"])
158
+ Jekyll.sanitized_path(context.registers[:site].source, page_path)
159
+ end
160
+ end
141
161
  end
142
162
  end
143
163
 
144
164
  Liquid::Template.register_tag('include', Jekyll::Tags::IncludeTag)
165
+ Liquid::Template.register_tag('include_relative', Jekyll::Tags::IncludeRelativeTag)
@@ -102,5 +102,22 @@ module Jekyll
102
102
  !!(File.open(file, 'rb') { |f| f.read(5) } =~ /\A---\r?\n/)
103
103
  end
104
104
 
105
+ # Slugify a filename or title.
106
+ #
107
+ # name - the filename or title to slugify
108
+ #
109
+ # Returns the given filename or title in lowercase, with every
110
+ # sequence of spaces and non-alphanumeric characters replaced with a
111
+ # hyphen.
112
+ def slugify(string)
113
+ unless string.nil?
114
+ # Replace each non-alphanumeric character sequence with a hyphen
115
+ slug = string.gsub(/[^a-z0-9]+/i, '-')
116
+ # Remove leading/trailing hyphen
117
+ slug.gsub!(/^\-|\-$/i, '')
118
+ slug.downcase
119
+ end
120
+ end
121
+
105
122
  end
106
123
  end
@@ -1,3 +1,3 @@
1
1
  module Jekyll
2
- VERSION = '2.3.0'
2
+ VERSION = '2.4.0'
3
3
  end
@@ -1 +1,2 @@
1
- _site
1
+ _site
2
+ .sass-cache
@@ -1,6 +1,6 @@
1
1
  <head>
2
2
  <meta charset="utf-8">
3
- <meta name="viewport" content="width=device-width">
3
+ <meta name="viewport" content="width=device-width initial-scale=1" />
4
4
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
5
5
 
6
6
  <title>{% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %}</title>
@@ -20,12 +20,13 @@ body {
20
20
  font-weight: 300;
21
21
  color: $text-color;
22
22
  background-color: $background-color;
23
+ -webkit-text-size-adjust: 100%;
23
24
  }
24
25
 
25
26
 
26
27
 
27
28
  /**
28
- * Set `margin-bottom` to maintain vertycal rhythm
29
+ * Set `margin-bottom` to maintain vertical rhythm
29
30
  */
30
31
  h1, h2, h3, h4, h5, h6,
31
32
  p, blockquote, pre,
@@ -1,49 +1,49 @@
1
- ---
2
- # Only the main Sass file needs front matter (the dashes are enough)
3
- ---
4
- @charset "utf-8";
5
-
6
-
7
-
8
- // Our variables
9
- $base-font-family: Helvetica, Arial, sans-serif;
10
- $base-font-size: 16px;
11
- $small-font-size: $base-font-size * 0.875;
12
- $base-line-height: 1.5;
13
-
14
- $spacing-unit: 30px;
15
-
16
- $text-color: #111;
17
- $background-color: #fdfdfd;
18
- $brand-color: #2a7ae2;
19
-
20
- $grey-color: #828282;
21
- $grey-color-light: lighten($grey-color, 40%);
22
- $grey-color-dark: darken($grey-color, 25%);
23
-
24
- $on-palm: 600px;
25
- $on-laptop: 800px;
26
-
27
-
28
-
29
- // Using media queries with like this:
30
- // @include media-query($palm) {
31
- // .wrapper {
32
- // padding-right: $spacing-unit / 2;
33
- // padding-left: $spacing-unit / 2;
34
- // }
35
- // }
36
- @mixin media-query($device) {
37
- @media screen and (max-width: $device) {
38
- @content;
39
- }
40
- }
41
-
42
-
43
-
44
- // Import partials from `sass_dir` (defaults to `_sass`)
45
- @import
46
- "base",
47
- "layout",
48
- "syntax-highlighting"
49
- ;
1
+ ---
2
+ # Only the main Sass file needs front matter (the dashes are enough)
3
+ ---
4
+ @charset "utf-8";
5
+
6
+
7
+
8
+ // Our variables
9
+ $base-font-family: Helvetica, Arial, sans-serif;
10
+ $base-font-size: 16px;
11
+ $small-font-size: $base-font-size * 0.875;
12
+ $base-line-height: 1.5;
13
+
14
+ $spacing-unit: 30px;
15
+
16
+ $text-color: #111;
17
+ $background-color: #fdfdfd;
18
+ $brand-color: #2a7ae2;
19
+
20
+ $grey-color: #828282;
21
+ $grey-color-light: lighten($grey-color, 40%);
22
+ $grey-color-dark: darken($grey-color, 25%);
23
+
24
+ $on-palm: 600px;
25
+ $on-laptop: 800px;
26
+
27
+
28
+
29
+ // Using media queries with like this:
30
+ // @include media-query($palm) {
31
+ // .wrapper {
32
+ // padding-right: $spacing-unit / 2;
33
+ // padding-left: $spacing-unit / 2;
34
+ // }
35
+ // }
36
+ @mixin media-query($device) {
37
+ @media screen and (max-width: $device) {
38
+ @content;
39
+ }
40
+ }
41
+
42
+
43
+
44
+ // Import partials from `sass_dir` (defaults to `_sass`)
45
+ @import
46
+ "base",
47
+ "layout",
48
+ "syntax-highlighting"
49
+ ;
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Preston-Werner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-13 00:00:00.000000000 Z
11
+ date: 2014-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: liquid
@@ -352,14 +352,14 @@ dependencies:
352
352
  requirements:
353
353
  - - "~>"
354
354
  - !ruby/object:Gem::Version
355
- version: '0.7'
355
+ version: '0.9'
356
356
  type: :development
357
357
  prerelease: false
358
358
  version_requirements: !ruby/object:Gem::Requirement
359
359
  requirements:
360
360
  - - "~>"
361
361
  - !ruby/object:Gem::Version
362
- version: '0.7'
362
+ version: '0.9'
363
363
  - !ruby/object:Gem::Dependency
364
364
  name: simplecov-gem-adapter
365
365
  requirement: !ruby/object:Gem::Requirement