jekyll 1.0.0.beta4 → 1.0.0.rc1

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.

@@ -0,0 +1,26 @@
1
+ module Jekyll
2
+ module Converters
3
+ class Markdown
4
+ class RDiscountParser
5
+ def initialize(config)
6
+ require 'rdiscount'
7
+ @config = config
8
+ @rdiscount_extensions = @config['rdiscount']['extensions'].map { |e| e.to_sym }
9
+ rescue LoadError
10
+ STDERR.puts 'You are missing a library required for Markdown. Please run:'
11
+ STDERR.puts ' $ [sudo] gem install rdiscount'
12
+ raise FatalException.new("Missing dependency: rdiscount")
13
+ end
14
+
15
+ def convert(content)
16
+ rd = RDiscount.new(content, *@rdiscount_extensions)
17
+ html = rd.to_html
18
+ if rd.generate_toc and html.include?(@config['rdiscount']['toc_token'])
19
+ html.gsub!(@config['rdiscount']['toc_token'], rd.toc_content.force_encoding('utf-8'))
20
+ end
21
+ html
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,40 @@
1
+ module Jekyll
2
+ module Converters
3
+ class Markdown
4
+ class RedcarpetParser
5
+ def initialize(config)
6
+ require 'redcarpet'
7
+ @config = config
8
+ @redcarpet_extensions = {}
9
+ @config['redcarpet']['extensions'].each { |e| @redcarpet_extensions[e.to_sym] = true }
10
+
11
+ @renderer ||= Class.new(Redcarpet::Render::HTML) do
12
+ def block_code(code, lang)
13
+ lang = lang && lang.split.first || "text"
14
+ output = add_code_tags(
15
+ Pygments.highlight(code, :lexer => lang, :options => { :encoding => 'utf-8' }),
16
+ lang
17
+ )
18
+ end
19
+
20
+ def add_code_tags(code, lang)
21
+ code = code.sub(/<pre>/,'<pre><code class="' + lang + '">')
22
+ code = code.sub(/<\/pre>/,"</code></pre>")
23
+ end
24
+ end
25
+ rescue LoadError
26
+ STDERR.puts 'You are missing a library required for Markdown. Please run:'
27
+ STDERR.puts ' $ [sudo] gem install redcarpet'
28
+ raise FatalException.new("Missing dependency: redcarpet")
29
+ end
30
+
31
+ def convert(content)
32
+ @redcarpet_extensions[:fenced_code_blocks] = !@redcarpet_extensions[:no_fenced_code_blocks]
33
+ @renderer.send :include, Redcarpet::Render::SmartyPants if @redcarpet_extensions[:smart]
34
+ markdown = Redcarpet::Markdown.new(@renderer.new(@redcarpet_extensions), @redcarpet_extensions)
35
+ markdown.render(content)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -71,7 +71,7 @@ module Jekyll
71
71
  #
72
72
  # Returns nothing.
73
73
  def do_layout(payload, layouts)
74
- info = { :filters => [Jekyll::Filters], :registers => { :site => self.site } }
74
+ info = { :filters => [Jekyll::Filters], :registers => { :site => self.site, :page => payload['page'] } }
75
75
 
76
76
  # render and transform content (this becomes the final content of the object)
77
77
  payload["pygments_prefix"] = converter.pygments_prefix
@@ -0,0 +1,25 @@
1
+ module Jekyll
2
+ class Deprecator
3
+ def self.process(args)
4
+ deprecation_message args, "--server", "The --server command has been replaced by the \
5
+ 'serve' subcommand."
6
+ deprecation_message args, "--no-server", "To build Jekyll without launching a server, \
7
+ use the 'build' subcommand."
8
+ deprecation_message args, "--auto", "The switch '--auto' has been replaced with '--watch'."
9
+ deprecation_message args, "--no-auto", "To disable auto-replication, simply leave off \
10
+ the '--watch' switch."
11
+ deprecation_message args, "--pygments", "The 'pygments' setting can only be set in \
12
+ your config files."
13
+ deprecation_message args, "--paginate", "The 'paginate' setting can only be set in your \
14
+ config files."
15
+ deprecation_message args, "--url", "The 'url' setting can only be set in your config files."
16
+ end
17
+
18
+ def self.deprecation_message(args, deprecated_argument, message)
19
+ if args.include?(deprecated_argument)
20
+ Jekyll::Logger.error "Deprecation:", message
21
+ exit(1)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,52 @@
1
+ module Jekyll
2
+ module Logger
3
+ # Public: Print a jekyll message to stdout
4
+ #
5
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
6
+ # message - the message detail
7
+ #
8
+ # Returns nothing
9
+ def self.info(topic, message)
10
+ $stdout.puts message(topic, message)
11
+ end
12
+
13
+ # Public: Print a jekyll message to stderr
14
+ #
15
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
16
+ # message - the message detail
17
+ #
18
+ # Returns nothing
19
+ def self.warn(topic, message)
20
+ $stderr.puts message(topic, message).yellow
21
+ end
22
+
23
+ # Public: Print a jekyll error message to stderr
24
+ #
25
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
26
+ # message - the message detail
27
+ #
28
+ # Returns nothing
29
+ def self.error(topic, message)
30
+ $stderr.puts message(topic, message).red
31
+ end
32
+
33
+ # Public: Build a Jekyll topic method
34
+ #
35
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
36
+ # message - the message detail
37
+ #
38
+ # Returns the formatted message
39
+ def self.message(topic, message)
40
+ formatted_topic(topic) + message.gsub(/\s+/, ' ')
41
+ end
42
+
43
+ # Public: Format the topic
44
+ #
45
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
46
+ #
47
+ # Returns the formatted topic statement
48
+ def self.formatted_topic(topic)
49
+ "#{topic} ".rjust(20)
50
+ end
51
+ end
52
+ end
@@ -35,6 +35,7 @@ application/postscript ps eps ai
35
35
  application/rdf+xml rdf
36
36
  application/rtf rtf
37
37
  text/vcard vcf vcard
38
+ application/vnd.apple.pkpass pkpass
38
39
  application/vnd.ms-excel xls
39
40
  application/vnd.ms-powerpoint ppt
40
41
  application/vnd.wap.wmlc wmlc
@@ -23,18 +23,6 @@ module Jekyll
23
23
  self.read_yaml(File.join(base, dir), name)
24
24
  end
25
25
 
26
- # Read the YAML frontmatter.
27
- #
28
- # base - The String path to the dir containing the file.
29
- # name - The String filename of the file.
30
- #
31
- # Returns nothing.
32
- def read_yaml(base, name)
33
- super(base, name)
34
- self.data['layout'] = 'page' unless self.data.has_key?('layout')
35
- self.data
36
- end
37
-
38
26
  # The generated directory into which the page will be placed
39
27
  # upon generation. This is derived from the permalink or, if
40
28
  # permalink is absent, we be '/'
@@ -124,7 +112,8 @@ module Jekyll
124
112
  def to_liquid
125
113
  self.data.deep_merge({
126
114
  "url" => self.url,
127
- "content" => self.content })
115
+ "content" => self.content,
116
+ "path" => self.data['path'] || File.join(@dir, @name).sub(/\A\//, '') })
128
117
  end
129
118
 
130
119
  # Obtain destination path.
@@ -19,7 +19,7 @@ module Jekyll
19
19
  end
20
20
 
21
21
  attr_accessor :site
22
- attr_accessor :data, :excerpt, :content, :output, :ext
22
+ attr_accessor :data, :extracted_excerpt, :content, :output, :ext
23
23
  attr_accessor :date, :slug, :published, :tags, :categories
24
24
 
25
25
  attr_reader :name
@@ -33,12 +33,13 @@ module Jekyll
33
33
  # Returns the new Post.
34
34
  def initialize(site, source, dir, name)
35
35
  @site = site
36
+ @dir = dir
36
37
  @base = self.containing_dir(source, dir)
37
38
  @name = name
38
39
 
39
40
  self.categories = dir.downcase.split('/').reject { |x| x.empty? }
40
41
  self.process(name)
41
- begin
42
+ begin
42
43
  self.read_yaml(@base, name)
43
44
  rescue Exception => msg
44
45
  raise FatalException.new("#{msg} in #{@base}/#{name}")
@@ -80,8 +81,19 @@ module Jekyll
80
81
  # Returns nothing.
81
82
  def read_yaml(base, name)
82
83
  super(base, name)
83
- self.excerpt = self.extract_excerpt
84
- self.data['layout'] = 'post' unless self.data.has_key?('layout')
84
+ self.extracted_excerpt = self.extract_excerpt
85
+ end
86
+
87
+ # The post excerpt. This is either a custom excerpt
88
+ # set in YAML front matter or the result of extract_excerpt.
89
+ #
90
+ # Returns excerpt string.
91
+ def excerpt
92
+ if self.data.has_key? 'excerpt'
93
+ self.data['excerpt']
94
+ else
95
+ self.extracted_excerpt
96
+ end
85
97
  end
86
98
 
87
99
  # Compares Post objects. First compares the Post date. If the dates are
@@ -117,7 +129,7 @@ module Jekyll
117
129
  # Returns nothing.
118
130
  def transform
119
131
  super
120
- self.excerpt = converter.convert(self.excerpt)
132
+ self.extracted_excerpt = converter.convert(self.extracted_excerpt)
121
133
  end
122
134
 
123
135
  # The generated directory into which the post will be placed
@@ -233,7 +245,7 @@ module Jekyll
233
245
 
234
246
  do_layout(payload, layouts)
235
247
  end
236
-
248
+
237
249
  # Obtain destination path.
238
250
  #
239
251
  # dest - The String path to the destination dir.
@@ -273,7 +285,8 @@ module Jekyll
273
285
  "previous" => self.previous,
274
286
  "tags" => self.tags,
275
287
  "content" => self.content,
276
- "excerpt" => self.excerpt })
288
+ "excerpt" => self.excerpt,
289
+ "path" => self.data['path'] || File.join(@dir, '_posts', @name).sub(/\A\//, '') })
277
290
  end
278
291
 
279
292
  # Returns the shorthand String identifier of this Post.
@@ -23,12 +23,12 @@ module Jekyll
23
23
  self.pygments = config['pygments']
24
24
  self.baseurl = config['baseurl']
25
25
  self.permalink_style = config['permalink'].to_sym
26
- self.exclude = config['exclude'] || []
27
- self.include = config['include'] || []
26
+ self.exclude = config['exclude']
27
+ self.include = config['include']
28
28
  self.future = config['future']
29
- self.show_drafts = config['show_drafts'] || nil
30
- self.limit_posts = config['limit_posts'] || nil
31
- self.keep_files = config['keep_files'] || []
29
+ self.show_drafts = config['show_drafts']
30
+ self.limit_posts = config['limit_posts']
31
+ self.keep_files = config['keep_files']
32
32
 
33
33
  self.reset
34
34
  self.setup
@@ -97,7 +97,7 @@ module Jekyll
97
97
  #
98
98
  # Returns an Array of plugin search paths
99
99
  def plugins_path
100
- if (config['plugins'] == Jekyll::DEFAULTS['plugins'])
100
+ if (config['plugins'] == Jekyll::Configuration::DEFAULTS['plugins'])
101
101
  [File.join(self.source, config['plugins'])]
102
102
  else
103
103
  Array(config['plugins']).map { |d| File.expand_path(d) }
@@ -1,2 +1 @@
1
- markdown: rdiscount
2
1
  pygments: true
@@ -1,5 +1,3 @@
1
- auto: false
2
- server: true
3
1
  permalink: /docs/:categories/:title
4
2
  pygments: true
5
3
  gauges_id: 503c5af6613f5d0f19000027
@@ -81,6 +81,22 @@ class="flag">flags</code> (specified on the command-line) that control them.
81
81
  <p><code class="option">include: [DIR, FILE, ...]</code></p>
82
82
  </td>
83
83
  </tr>
84
+ <tr class='setting'>
85
+ <td>
86
+ <p class='name'><strong>Time Zone</strong></p>
87
+ <p class="description">
88
+ Set the time zone for site generation. This sets the <code>TZ</code>
89
+ environment variable, which Ruby uses to handle time and date
90
+ creation and manipulation. Any entry from the
91
+ <a href="http://en.wikipedia.org/wiki/Tz_database">IANA Time Zone
92
+ Database</a> is valid, e.g. <code>America/New_York</code>. The default
93
+ is the local time zone, as set by your operating system.
94
+ </p>
95
+ </td>
96
+ <td class='align-center'>
97
+ <p><code class="option">timezone: TIMEZONE</code></p>
98
+ </td>
99
+ </tr>
84
100
  </tbody>
85
101
  </table>
86
102
 
@@ -159,6 +159,14 @@ following is a reference of the available data.
159
159
 
160
160
  </p></td>
161
161
  </tr>
162
+ <tr>
163
+ <td><p><code>page.excerpt</code></p></td>
164
+ <td><p>
165
+
166
+ The un-rendered excerpt of the Page.
167
+
168
+ </p></td>
169
+ </tr>
162
170
  <tr>
163
171
  <td><p><code>page.url</code></p></td>
164
172
  <td><p>
@@ -205,7 +213,17 @@ following is a reference of the available data.
205
213
  <td><p>
206
214
 
207
215
  The list of tags to which this post belongs. These can be specified in
208
- the <a href="../frontmatter">YAML Front Matter</a>
216
+ the <a href="../frontmatter">YAML Front Matter</a>.
217
+
218
+ </p></td>
219
+ </tr>
220
+ <tr>
221
+ <td><p><code>page.path</code></p></td>
222
+ <td><p>
223
+
224
+ The path to the raw post or page. Example usage: Linking back to the
225
+ page or post's source on GitHub. This can be overridden in the
226
+ <a href="../frontmatter">YAML Front Matter</a>.
209
227
 
210
228
  </p></td>
211
229
  </tr>
@@ -258,10 +276,18 @@ following is a reference of the available data.
258
276
  <td><p><code>paginator.previous_page</code></p></td>
259
277
  <td><p>The number of the previous page.</p></td>
260
278
  </tr>
279
+ <tr>
280
+ <td><p><code>paginator.previous_page_path</code></p></td>
281
+ <td><p>The path to the previous page.</p></td>
282
+ </tr>
261
283
  <tr>
262
284
  <td><p><code>paginator.next_page</code></p></td>
263
285
  <td><p>The number of the next page.</p></td>
264
286
  </tr>
287
+ <tr>
288
+ <td><p><code>paginator.next_page_path</code></p></td>
289
+ <td><p>The path to the next page.</p></td>
290
+ </tr>
265
291
  </tbody>
266
292
  </table>
267
293
 
@@ -49,10 +49,15 @@ overview: true
49
49
  <p class="line">
50
50
  <span class="path">~</span>
51
51
  <span class="prompt">$</span>
52
- <span class="command">cd my/awesome/site</span>
52
+ <span class="command">jekyll new my-awesome-site</span>
53
53
  </p>
54
54
  <p class="line">
55
- <span class="path">~/my/awesome/site</span>
55
+ <span class="path">~</span>
56
+ <span class="prompt">$</span>
57
+ <span class="command">cd my-awesome-site</span>
58
+ </p>
59
+ <p class="line">
60
+ <span class="path">~/my-awesome-site</span>
56
61
  <span class="prompt">$</span>
57
62
  <span class="command">jekyll serve</span>
58
63
  </p>
@@ -0,0 +1,10 @@
1
+ ---
2
+ layout: ~
3
+ excerpt: 'I can set a custom excerpt'
4
+ ---
5
+
6
+ This is not my excerpt.
7
+
8
+ Neither is this.
9
+
10
+ I can use the excerpt: <quote>{{page.excerpt}}</quote>
@@ -1,6 +1,72 @@
1
1
  require 'helper'
2
2
 
3
3
  class TestConfiguration < Test::Unit::TestCase
4
+ context "#stringify_keys" do
5
+ setup do
6
+ @mixed_keys = Configuration[{
7
+ 'markdown' => 'maruku',
8
+ :permalink => 'date',
9
+ 'baseurl' => '/',
10
+ :include => ['.htaccess'],
11
+ :source => './'
12
+ }]
13
+ @string_keys = Configuration[{
14
+ 'markdown' => 'maruku',
15
+ 'permalink' => 'date',
16
+ 'baseurl' => '/',
17
+ 'include' => ['.htaccess'],
18
+ 'source' => './'
19
+ }]
20
+ end
21
+ should "stringify symbol keys" do
22
+ assert_equal @string_keys, @mixed_keys.stringify_keys
23
+ end
24
+ should "not mess with keys already strings" do
25
+ assert_equal @string_keys, @string_keys.stringify_keys
26
+ end
27
+ end
28
+ context "#config_files" do
29
+ setup do
30
+ @config = Configuration[{"source" => source_dir}]
31
+ @no_override = {}
32
+ @one_config_file = {"config" => "config.yml"}
33
+ @multiple_files = {"config" => %w[config/site.yml config/deploy.yml configuration.yml]}
34
+ end
35
+
36
+ should "always return an array" do
37
+ assert @config.config_files(@no_override).is_a?(Array)
38
+ assert @config.config_files(@one_config_file).is_a?(Array)
39
+ assert @config.config_files(@multiple_files).is_a?(Array)
40
+ end
41
+ should "return the default config path if no config files are specified" do
42
+ assert_equal [File.join(source_dir, "_config.yml")], @config.config_files(@no_override)
43
+ end
44
+ should "return the config if given one config file" do
45
+ assert_equal %w[config.yml], @config.config_files(@one_config_file)
46
+ end
47
+ should "return an array of the config files if given many config files" do
48
+ assert_equal %w[config/site.yml config/deploy.yml configuration.yml], @config.config_files(@multiple_files)
49
+ end
50
+ end
51
+ context "#backwards_compatibilize" do
52
+ setup do
53
+ @config = Configuration[{
54
+ "auto" => true,
55
+ "watch" => true,
56
+ "server" => true
57
+ }]
58
+ end
59
+ should "unset 'auto' and 'watch'" do
60
+ assert @config.has_key?("auto")
61
+ assert @config.has_key?("watch")
62
+ assert !@config.backwards_compatibilize.has_key?("auto")
63
+ assert !@config.backwards_compatibilize.has_key?("watch")
64
+ end
65
+ should "unset 'server'" do
66
+ assert @config.has_key?("server")
67
+ assert !@config.backwards_compatibilize.has_key?("server")
68
+ end
69
+ end
4
70
  context "loading configuration" do
5
71
  setup do
6
72
  @path = File.join(Dir.pwd, '_config.yml')
@@ -8,21 +74,21 @@ class TestConfiguration < Test::Unit::TestCase
8
74
 
9
75
  should "fire warning with no _config.yml" do
10
76
  mock(YAML).safe_load_file(@path) { raise SystemCallError, "No such file or directory - #{@path}" }
11
- mock($stderr).puts("Configuration file: none")
12
- assert_equal Jekyll::DEFAULTS, Jekyll.configuration({})
77
+ mock($stderr).puts("Configuration file: none".yellow)
78
+ assert_equal Jekyll::Configuration::DEFAULTS, Jekyll.configuration({})
13
79
  end
14
80
 
15
81
  should "load configuration as hash" do
16
82
  mock(YAML).safe_load_file(@path) { Hash.new }
17
83
  mock($stdout).puts("Configuration file: #{@path}")
18
- assert_equal Jekyll::DEFAULTS, Jekyll.configuration({})
84
+ assert_equal Jekyll::Configuration::DEFAULTS, Jekyll.configuration({})
19
85
  end
20
86
 
21
87
  should "fire warning with bad config" do
22
88
  mock(YAML).safe_load_file(@path) { Array.new }
23
- mock($stderr).puts(" WARNING: Error reading configuration. Using defaults (and options).")
24
- mock($stderr).puts("Configuration file: (INVALID) #{@path}")
25
- assert_equal Jekyll::DEFAULTS, Jekyll.configuration({})
89
+ mock($stderr).puts(("WARNING: ".rjust(20) + "Error reading configuration. Using defaults (and options).").yellow)
90
+ mock($stderr).puts("Configuration file: (INVALID) #{@path}".yellow)
91
+ assert_equal Jekyll::Configuration::DEFAULTS, Jekyll.configuration({})
26
92
  end
27
93
  end
28
94
  context "loading config from external file" do
@@ -37,19 +103,35 @@ class TestConfiguration < Test::Unit::TestCase
37
103
  should "load default config if no config_file is set" do
38
104
  mock(YAML).safe_load_file(@paths[:default]) { Hash.new }
39
105
  mock($stdout).puts("Configuration file: #{@paths[:default]}")
40
- assert_equal Jekyll::DEFAULTS, Jekyll.configuration({})
106
+ assert_equal Jekyll::Configuration::DEFAULTS, Jekyll.configuration({})
41
107
  end
42
108
 
43
109
  should "load different config if specified" do
44
110
  mock(YAML).safe_load_file(@paths[:other]) { {"baseurl" => "http://wahoo.dev"} }
45
111
  mock($stdout).puts("Configuration file: #{@paths[:other]}")
46
- assert_equal Jekyll::DEFAULTS.deep_merge({ "baseurl" => "http://wahoo.dev" }), Jekyll.configuration({ "config" => @paths[:other] })
112
+ assert_equal Jekyll::Configuration::DEFAULTS.deep_merge({ "baseurl" => "http://wahoo.dev" }), Jekyll.configuration({ "config" => @paths[:other] })
47
113
  end
48
114
 
49
115
  should "load default config if path passed is empty" do
50
116
  mock(YAML).safe_load_file(@paths[:default]) { Hash.new }
51
117
  mock($stdout).puts("Configuration file: #{@paths[:default]}")
52
- assert_equal Jekyll::DEFAULTS, Jekyll.configuration({ "config" => @paths[:empty] })
118
+ assert_equal Jekyll::Configuration::DEFAULTS, Jekyll.configuration({ "config" => @paths[:empty] })
119
+ end
120
+
121
+ should "load multiple config files" do
122
+ mock(YAML).safe_load_file(@paths[:default]) { Hash.new }
123
+ mock(YAML).safe_load_file(@paths[:other]) { Hash.new }
124
+ mock($stdout).puts("Configuration file: #{@paths[:default]}")
125
+ mock($stdout).puts("Configuration file: #{@paths[:other]}")
126
+ assert_equal Jekyll::Configuration::DEFAULTS, Jekyll.configuration({ "config" => [@paths[:default], @paths[:other]] })
127
+ end
128
+
129
+ should "load multiple config files and last config should win" do
130
+ mock(YAML).safe_load_file(@paths[:default]) { {"baseurl" => "http://example.dev"} }
131
+ mock(YAML).safe_load_file(@paths[:other]) { {"baseurl" => "http://wahoo.dev"} }
132
+ mock($stdout).puts("Configuration file: #{@paths[:default]}")
133
+ mock($stdout).puts("Configuration file: #{@paths[:other]}")
134
+ assert_equal Jekyll::Configuration::DEFAULTS.deep_merge({ "baseurl" => "http://wahoo.dev" }), Jekyll.configuration({ "config" => [@paths[:default], @paths[:other]] })
53
135
  end
54
136
  end
55
137
  end