jberkel-jekyll 0.5.4

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 (73) hide show
  1. data/.gitignore +6 -0
  2. data/History.txt +151 -0
  3. data/README.textile +42 -0
  4. data/Rakefile +90 -0
  5. data/VERSION.yml +4 -0
  6. data/bin/jekyll +168 -0
  7. data/features/create_sites.feature +46 -0
  8. data/features/embed_filters.feature +60 -0
  9. data/features/pagination.feature +40 -0
  10. data/features/permalinks.feature +65 -0
  11. data/features/post_data.feature +153 -0
  12. data/features/site_configuration.feature +63 -0
  13. data/features/site_data.feature +82 -0
  14. data/features/step_definitions/jekyll_steps.rb +136 -0
  15. data/features/support/env.rb +16 -0
  16. data/jekyll.gemspec +141 -0
  17. data/lib/jekyll/albino.rb +122 -0
  18. data/lib/jekyll/converters/csv.rb +26 -0
  19. data/lib/jekyll/converters/marley.rb +53 -0
  20. data/lib/jekyll/converters/mephisto.rb +79 -0
  21. data/lib/jekyll/converters/mt.rb +59 -0
  22. data/lib/jekyll/converters/textpattern.rb +50 -0
  23. data/lib/jekyll/converters/typo.rb +49 -0
  24. data/lib/jekyll/converters/wordpress.rb +54 -0
  25. data/lib/jekyll/convertible.rb +117 -0
  26. data/lib/jekyll/core_ext.rb +38 -0
  27. data/lib/jekyll/filters.rb +51 -0
  28. data/lib/jekyll/haml_helpers.rb +15 -0
  29. data/lib/jekyll/layout.rb +37 -0
  30. data/lib/jekyll/page.rb +112 -0
  31. data/lib/jekyll/pager.rb +45 -0
  32. data/lib/jekyll/post.rb +310 -0
  33. data/lib/jekyll/site.rb +316 -0
  34. data/lib/jekyll/tags/highlight.rb +56 -0
  35. data/lib/jekyll/tags/include.rb +31 -0
  36. data/lib/jekyll.rb +86 -0
  37. data/test/helper.rb +27 -0
  38. data/test/source/_includes/sig.markdown +3 -0
  39. data/test/source/_layouts/default.html +27 -0
  40. data/test/source/_layouts/simple.html +1 -0
  41. data/test/source/_posts/2008-02-02-not-published.textile +8 -0
  42. data/test/source/_posts/2008-02-02-published.textile +8 -0
  43. data/test/source/_posts/2008-10-18-foo-bar.textile +8 -0
  44. data/test/source/_posts/2008-11-21-complex.textile +8 -0
  45. data/test/source/_posts/2008-12-03-permalinked-post.textile +9 -0
  46. data/test/source/_posts/2008-12-13-include.markdown +8 -0
  47. data/test/source/_posts/2009-01-27-array-categories.textile +10 -0
  48. data/test/source/_posts/2009-01-27-categories.textile +7 -0
  49. data/test/source/_posts/2009-01-27-category.textile +7 -0
  50. data/test/source/_posts/2009-03-12-hash-#1.markdown +6 -0
  51. data/test/source/_posts/2009-05-18-tag.textile +6 -0
  52. data/test/source/_posts/2009-05-18-tags.textile +9 -0
  53. data/test/source/_posts/2009-06-22-empty-yaml.textile +3 -0
  54. data/test/source/_posts/2009-06-22-no-yaml.textile +1 -0
  55. data/test/source/about.html +6 -0
  56. data/test/source/category/_posts/2008-9-23-categories.textile +6 -0
  57. data/test/source/contacts.html +5 -0
  58. data/test/source/css/screen.css +76 -0
  59. data/test/source/foo/_posts/bar/2008-12-12-topical-post.textile +8 -0
  60. data/test/source/index.html +22 -0
  61. data/test/source/sitemap.xml +23 -0
  62. data/test/source/win/_posts/2009-05-24-yaml-linebreak.markdown +7 -0
  63. data/test/source/z_category/_posts/2008-9-23-categories.textile +6 -0
  64. data/test/suite.rb +9 -0
  65. data/test/test_configuration.rb +29 -0
  66. data/test/test_filters.rb +49 -0
  67. data/test/test_generated_site.rb +40 -0
  68. data/test/test_page.rb +98 -0
  69. data/test/test_pager.rb +47 -0
  70. data/test/test_post.rb +302 -0
  71. data/test/test_site.rb +85 -0
  72. data/test/test_tags.rb +116 -0
  73. metadata +194 -0
@@ -0,0 +1,316 @@
1
+ module Jekyll
2
+
3
+ class Site
4
+ attr_accessor :config, :layouts, :posts, :categories, :exclude,
5
+ :source, :dest, :lsi, :pygments, :permalink_style, :tags
6
+
7
+ attr_accessor :sass, :post_defaults, :collated_posts
8
+
9
+
10
+ # Initialize the site
11
+ # +config+ is a Hash containing site configurations details
12
+ #
13
+ # Returns <Site>
14
+ def initialize(config)
15
+ self.config = config.clone
16
+
17
+ self.source = config['source']
18
+ self.dest = config['destination']
19
+ self.lsi = config['lsi']
20
+ self.pygments = config['pygments']
21
+ self.permalink_style = config['permalink'].to_sym
22
+ self.post_defaults = config['post_defaults'] || {}
23
+ self.exclude = config['exclude'] || []
24
+
25
+ self.reset
26
+ self.setup
27
+ end
28
+
29
+ def reset
30
+ self.layouts = {}
31
+ self.posts = []
32
+ self.collated_posts = Hash.new {|h,k| h[k] = Hash.new {|h,k| h[k] = Hash.new {|h,k| h[k] = [] } } }
33
+ self.categories = Hash.new { |hash, key| hash[key] = [] }
34
+ self.tags = Hash.new { |hash, key| hash[key] = [] }
35
+ end
36
+
37
+ def setup
38
+ # Check to see if LSI is enabled.
39
+ require 'classifier' if self.lsi
40
+
41
+ if self.config['sass']
42
+ begin
43
+ require 'sass'
44
+ self.sass = true
45
+ puts 'Using Sass for CSS generation'
46
+ rescue LoadError
47
+ puts 'You must have the haml gem installed first'
48
+ end
49
+ end
50
+
51
+ if self.config['haml']
52
+ begin
53
+ require 'haml'
54
+ require 'jekyll/haml_helpers'
55
+ helpers = File.join(source, '_helpers.rb')
56
+ require helpers if File.exist?(helpers)
57
+ puts 'Enabled Haml'
58
+ rescue LoadError => e
59
+ raise "You must have the haml gem installed first: #{e}"
60
+ end
61
+ end
62
+
63
+ # Set the Markdown interpreter (and Maruku self.config, if necessary)
64
+ case self.config['markdown']
65
+ when 'rdiscount'
66
+ begin
67
+ require 'rdiscount'
68
+
69
+ def markdown(content)
70
+ RDiscount.new(content).to_html
71
+ end
72
+
73
+ rescue LoadError
74
+ puts 'You must have the rdiscount gem installed first'
75
+ end
76
+ when 'maruku'
77
+ begin
78
+ require 'maruku'
79
+
80
+ def markdown(content)
81
+ Maruku.new(content).to_html
82
+ end
83
+
84
+ if self.config['maruku']['use_divs']
85
+ require 'maruku/ext/div'
86
+ puts 'Maruku: Using extended syntax for div elements.'
87
+ end
88
+
89
+ if self.config['maruku']['use_tex']
90
+ require 'maruku/ext/math'
91
+ puts "Maruku: Using LaTeX extension. Images in `#{self.config['maruku']['png_dir']}`."
92
+
93
+ # Switch off MathML output
94
+ MaRuKu::Globals[:html_math_output_mathml] = false
95
+ MaRuKu::Globals[:html_math_engine] = 'none'
96
+
97
+ # Turn on math to PNG support with blahtex
98
+ # Resulting PNGs stored in `images/latex`
99
+ MaRuKu::Globals[:html_math_output_png] = true
100
+ MaRuKu::Globals[:html_png_engine] = self.config['maruku']['png_engine']
101
+ MaRuKu::Globals[:html_png_dir] = self.config['maruku']['png_dir']
102
+ MaRuKu::Globals[:html_png_url] = self.config['maruku']['png_url']
103
+ end
104
+ rescue LoadError
105
+ puts "The maruku gem is required for markdown support!"
106
+ end
107
+ else
108
+ raise "Invalid Markdown processor: '#{self.config['markdown']}' -- did you mean 'maruku' or 'rdiscount'?"
109
+ end
110
+ end
111
+
112
+ def textile(content)
113
+ RedCloth.new(content).to_html
114
+ end
115
+
116
+ # Do the actual work of processing the site and generating the
117
+ # real deal.
118
+ #
119
+ # Returns nothing
120
+ def process
121
+ self.reset
122
+ self.read_layouts
123
+ self.transform_pages
124
+ self.transform_sass if self.sass
125
+ self.write_posts
126
+ end
127
+
128
+ # Read all the files in <source>/_layouts into memory for later use.
129
+ #
130
+ # Returns nothing
131
+ def read_layouts
132
+ base = File.join(self.source, "_layouts")
133
+ entries = []
134
+ Dir.chdir(base) { entries = filter_entries(Dir['*.*']) }
135
+
136
+ entries.each do |f|
137
+ name = f.split(".")[0..-2].join(".")
138
+ self.layouts[name] = Layout.new(self, base, f)
139
+ end
140
+ rescue Errno::ENOENT => e
141
+ # ignore missing layout dir
142
+ end
143
+
144
+ # Read all the files in <base>/_posts and create a new Post object with each one.
145
+ #
146
+ # Returns nothing
147
+ def read_posts(dir)
148
+ base = File.join(self.source, dir, '_posts')
149
+ entries = []
150
+ Dir.chdir(base) { entries = filter_entries(Dir['**/*']) }
151
+
152
+ # first pass processes, but does not yet render post content
153
+ entries.each do |f|
154
+ if Post.valid?(f)
155
+ post = Post.new(self, self.source, dir, f)
156
+
157
+ if post.published
158
+ self.posts << post
159
+ post.categories.each { |c| self.categories[c] << post }
160
+ post.tags.each { |c| self.tags[c] << post }
161
+ end
162
+ end
163
+ end
164
+
165
+ self.posts.sort!
166
+
167
+ # second pass renders each post now that full site payload is available
168
+ self.posts.each do |post|
169
+ post.render(self.layouts, site_payload)
170
+ self.collated_posts[post.date.year][post.date.month][post.date.day].unshift(post)
171
+ end
172
+
173
+ self.categories.values.map { |ps| ps.sort! { |a, b| b <=> a} }
174
+ self.tags.values.map { |ps| ps.sort! { |a, b| b <=> a} }
175
+ rescue Errno::ENOENT => e
176
+ # ignore missing layout dir
177
+ end
178
+
179
+ # Write each post to <dest>/<year>/<month>/<day>/<slug>
180
+ #
181
+ # Returns nothing
182
+ def write_posts
183
+ self.posts.each do |post|
184
+ post.write(self.dest)
185
+ end
186
+ end
187
+
188
+ # Copy all regular files from <source> to <dest>/ ignoring
189
+ # any files/directories that are hidden or backup files (start
190
+ # with "." or "#" or end with "~") or contain site content (start with "_")
191
+ # unless they are "_posts" directories or web server files such as
192
+ # '.htaccess'
193
+ # The +dir+ String is a relative path used to call this method
194
+ # recursively as it descends through directories
195
+ #
196
+ # Returns nothing
197
+ def transform_pages(dir = '')
198
+ base = File.join(self.source, dir)
199
+ entries = filter_entries(Dir.entries(base))
200
+ directories = entries.select { |e| File.directory?(File.join(base, e)) }
201
+ files = entries.reject { |e| File.directory?(File.join(base, e)) || File.symlink?(File.join(base, e)) }
202
+
203
+ # we need to make sure to process _posts *first* otherwise they
204
+ # might not be available yet to other templates as {{ site.posts }}
205
+ if directories.include?('_posts')
206
+ directories.delete('_posts')
207
+ read_posts(dir)
208
+ end
209
+
210
+ [directories, files].each do |entries|
211
+ entries.each do |f|
212
+ if File.directory?(File.join(base, f))
213
+ next if self.dest.sub(/\/$/, '') == File.join(base, f)
214
+ transform_pages(File.join(dir, f))
215
+ elsif Pager.pagination_enabled?(self.config, f)
216
+ paginate_posts(f, dir)
217
+ else
218
+ first3 = File.open(File.join(self.source, dir, f)) { |fd| fd.read(3) }
219
+ if first3 == "---"
220
+ # file appears to have a YAML header so process it as a page
221
+ page = Page.new(self, self.source, dir, f)
222
+ page.render(self.layouts, site_payload)
223
+ page.write(self.dest)
224
+ else
225
+ # otherwise copy the file without transforming it
226
+ FileUtils.mkdir_p(File.join(self.dest, dir))
227
+ FileUtils.cp(File.join(self.source, dir, f), File.join(self.dest, dir, f))
228
+ end
229
+ end
230
+ end
231
+ end
232
+ end
233
+
234
+ # Transform all *.sass files from <dest> to css with the same name
235
+ # and delete source sass files.
236
+ # Returns nothing
237
+ def transform_sass(dir = '')
238
+ base = File.join(self.source, dir)
239
+ entries = Dir.entries(base)
240
+ entries = entries.reject { |e| ['.', '_'].include?(e[0..0]) }
241
+ directories = entries.select { |e| File.directory?(File.join(base, e)) }
242
+ directories.each { |d| transform_sass(File.join(dir, d)) }
243
+ files = entries.reject { |e| File.directory?(File.join(base, e)) }
244
+ files = files.select { |f| File.extname(File.join(base, f)) == ".sass" }
245
+ files.each do |f|
246
+ input = File.open(File.join(base, f), "r")
247
+ result = Sass::Engine.new(input.read, :style => :compact, :load_paths => base).render
248
+ FileUtils.mkdir_p(File.join(self.dest, dir))
249
+ output = File.open(File.join(self.dest, dir, f).gsub(/.sass\Z/, ".css"), "w") do |o|
250
+ o.write(result)
251
+ end
252
+ FileUtils.rm(File.join(self.dest, dir, f))
253
+ end
254
+ end
255
+
256
+ # Constructs a hash map of Posts indexed by the specified Post attribute
257
+ #
258
+ # Returns {post_attr => [<Post>]}
259
+ def post_attr_hash(post_attr)
260
+ # Build a hash map based on the specified post attribute ( post attr => array of posts )
261
+ # then sort each array in reverse order
262
+ hash = Hash.new { |hash, key| hash[key] = Array.new }
263
+ self.posts.each { |p| p.send(post_attr.to_sym).each { |t| hash[t] << p } }
264
+ hash.values.map { |sortme| sortme.sort! { |a, b| b <=> a} }
265
+ return hash
266
+ end
267
+
268
+ # The Hash payload containing site-wide data
269
+ #
270
+ # Returns {"site" => {"time" => <Time>,
271
+ # "posts" => [<Post>],
272
+ # "categories" => [<Post>]}
273
+ def site_payload
274
+ {"site" => self.config.merge({
275
+ "time" => Time.now,
276
+ "posts" => self.posts.sort { |a,b| b <=> a },
277
+ "categories" => post_attr_hash('categories'),
278
+ "tags" => post_attr_hash('tags')})}
279
+ end
280
+
281
+ # Filter out any files/directories that are hidden or backup files (start
282
+ # with "." or "#" or end with "~") or contain site content (start with "_")
283
+ # unless they are "_posts" directories or web server files such as
284
+ # '.htaccess'
285
+ def filter_entries(entries)
286
+ entries = entries.reject do |e|
287
+ unless ['_posts', '.htaccess'].include?(e)
288
+ ['.', '_', '#'].include?(e[0..0]) || e[-1..-1] == '~' || self.exclude.include?(e)
289
+ end
290
+ end
291
+ end
292
+
293
+ # Paginates the blog's posts. Renders the index.html file into paginated directories, ie: page2, page3...
294
+ # and adds more wite-wide data
295
+ #
296
+ # {"paginator" => { "page" => <Number>,
297
+ # "per_page" => <Number>,
298
+ # "posts" => [<Post>],
299
+ # "total_posts" => <Number>,
300
+ # "total_pages" => <Number>,
301
+ # "previous_page" => <Number>,
302
+ # "next_page" => <Number> }}
303
+ def paginate_posts(file, dir)
304
+ all_posts = self.posts.sort { |a,b| b <=> a }
305
+ pages = Pager.calculate_pages(all_posts, self.config['paginate'].to_i)
306
+ pages += 1
307
+ (1..pages).each do |num_page|
308
+ pager = Pager.new(self.config, num_page, all_posts, pages)
309
+ page = Page.new(self, self.source, dir, file)
310
+ page.render(self.layouts, site_payload.merge({'paginator' => pager.to_hash}))
311
+ suffix = "page#{num_page}" if num_page > 1
312
+ page.write(self.dest, suffix)
313
+ end
314
+ end
315
+ end
316
+ end
@@ -0,0 +1,56 @@
1
+ module Jekyll
2
+
3
+ class HighlightBlock < Liquid::Block
4
+ include Liquid::StandardFilters
5
+
6
+ # we need a language, but the linenos argument is optional.
7
+ SYNTAX = /(\w+)\s?(:?linenos)?\s?/
8
+
9
+ def initialize(tag_name, markup, tokens)
10
+ super
11
+ if markup =~ SYNTAX
12
+ @lang = $1
13
+ if defined? $2
14
+ # additional options to pass to Albino.
15
+ @options = { 'O' => 'linenos=inline' }
16
+ else
17
+ @options = {}
18
+ end
19
+ else
20
+ raise SyntaxError.new("Syntax Error in 'highlight' - Valid syntax: highlight <lang> [linenos]")
21
+ end
22
+ end
23
+
24
+ def render(context)
25
+ if context.registers[:site].pygments
26
+ render_pygments(context, super.to_s)
27
+ else
28
+ render_codehighlighter(context, super.to_s)
29
+ end
30
+ end
31
+
32
+ def render_pygments(context, code)
33
+ if context["content_type"] == "markdown"
34
+ return "\n" + Albino.new(code, @lang).to_s(@options) + "\n"
35
+ elsif context["content_type"] == "textile"
36
+ return "<notextile>" + Albino.new(code, @lang).to_s(@options) + "</notextile>"
37
+ else
38
+ return highlighted_code
39
+ end
40
+ end
41
+
42
+ def render_codehighlighter(context, code)
43
+ #The div is required because RDiscount blows ass
44
+ <<-HTML
45
+ <div>
46
+ <pre>
47
+ <code class='#{@lang}'>#{h(code).strip}</code>
48
+ </pre>
49
+ </div>
50
+ HTML
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ Liquid::Template.register_tag('highlight', Jekyll::HighlightBlock)
@@ -0,0 +1,31 @@
1
+ module Jekyll
2
+
3
+ class IncludeTag < Liquid::Tag
4
+ def initialize(tag_name, file, tokens)
5
+ super
6
+ @file = file.strip
7
+ end
8
+
9
+ def render(context)
10
+ if @file !~ /^[a-zA-Z0-9_\/\.-]+$/ || @file =~ /\.\// || @file =~ /\/\./
11
+ return "Include file '#{@file}' contains invalid characters or sequences"
12
+ end
13
+
14
+ Dir.chdir(File.join(context.registers[:site].source, '_includes')) do
15
+ choices = Dir['**/*'].reject { |x| File.symlink?(x) }
16
+ if choices.include?(@file)
17
+ source = File.read(@file)
18
+ partial = Liquid::Template.parse(source)
19
+ context.stack do
20
+ partial.render(context)
21
+ end
22
+ else
23
+ "Included file '#{@file}' not found in _includes directory"
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ Liquid::Template.register_tag('include', Jekyll::IncludeTag)
data/lib/jekyll.rb ADDED
@@ -0,0 +1,86 @@
1
+ $:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
2
+
3
+ # rubygems
4
+ require 'rubygems'
5
+
6
+ # core
7
+ require 'fileutils'
8
+ require 'time'
9
+ require 'yaml'
10
+
11
+ # stdlib
12
+
13
+ # 3rd party
14
+ require 'liquid'
15
+ require 'redcloth'
16
+
17
+ # internal requires
18
+ require 'jekyll/core_ext'
19
+ require 'jekyll/pager'
20
+ require 'jekyll/site'
21
+ require 'jekyll/convertible'
22
+ require 'jekyll/layout'
23
+ require 'jekyll/page'
24
+ require 'jekyll/post'
25
+ require 'jekyll/filters'
26
+ require 'jekyll/tags/highlight'
27
+ require 'jekyll/tags/include'
28
+ require 'jekyll/albino'
29
+
30
+ module Jekyll
31
+ # Default options. Overriden by values in _config.yml or command-line opts.
32
+ # Strings are used instead of symbols for YAML compatibility.
33
+ DEFAULTS = {
34
+ 'auto' => false,
35
+ 'server' => false,
36
+ 'server_port' => 4000,
37
+
38
+ 'source' => '.',
39
+ 'destination' => File.join('.', '_site'),
40
+
41
+ 'lsi' => false,
42
+ 'pygments' => false,
43
+ 'sass' => false,
44
+ 'markdown' => 'maruku',
45
+ 'permalink' => 'date',
46
+
47
+ 'maruku' => {
48
+ 'use_tex' => false,
49
+ 'use_divs' => false,
50
+ 'png_engine' => 'blahtex',
51
+ 'png_dir' => 'images/latex',
52
+ 'png_url' => '/images/latex'
53
+ }
54
+ }
55
+
56
+ # Generate a Jekyll configuration Hash by merging the default options
57
+ # with anything in _config.yml, and adding the given options on top
58
+ # +override+ is a Hash of config directives
59
+ #
60
+ # Returns Hash
61
+ def self.configuration(override)
62
+ # _config.yml may override default source location, but until
63
+ # then, we need to know where to look for _config.yml
64
+ source = override['source'] || Jekyll::DEFAULTS['source']
65
+
66
+ # Get configuration from <source>/_config.yml
67
+ config_file = File.join(source, '_config.yml')
68
+ begin
69
+ config = YAML.load_file(config_file)
70
+ raise "Invalid configuration - #{config_file}" if !config.is_a?(Hash)
71
+ STDOUT.puts "Configuration from #{config_file}"
72
+ rescue => err
73
+ STDERR.puts "WARNING: Could not read configuration. Using defaults (and options)."
74
+ STDERR.puts "\t" + err.to_s
75
+ config = {}
76
+ end
77
+
78
+ # Merge DEFAULTS < _config.yml < override
79
+ Jekyll::DEFAULTS.deep_merge(config).deep_merge(override)
80
+ end
81
+
82
+ def self.version
83
+ yml = YAML.load(File.read(File.join(File.dirname(__FILE__), *%w[.. VERSION.yml])))
84
+ "#{yml[:major]}.#{yml[:minor]}.#{yml[:patch]}"
85
+ end
86
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ gem 'RedCloth', '>= 4.1.1'
3
+
4
+ require File.join(File.dirname(__FILE__), *%w[.. lib jekyll])
5
+
6
+ require 'test/unit'
7
+ require 'redgreen'
8
+ require 'shoulda'
9
+ require 'rr'
10
+
11
+ include Jekyll
12
+
13
+ class Test::Unit::TestCase
14
+ include RR::Adapters::TestUnit
15
+
16
+ def dest_dir(*subdirs)
17
+ File.join(File.dirname(__FILE__), 'dest', *subdirs)
18
+ end
19
+
20
+ def source_dir(*subdirs)
21
+ File.join(File.dirname(__FILE__), 'source', *subdirs)
22
+ end
23
+
24
+ def clear_dest
25
+ FileUtils.rm_rf(dest_dir)
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ --
2
+ Tom Preston-Werner
3
+ github.com/mojombo
@@ -0,0 +1,27 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en-us">
5
+ <head>
6
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
7
+ <title>{{ page.title }}</title>
8
+ <meta name="author" content="<%= @page.author %>" />
9
+
10
+ <!-- CodeRay syntax highlighting CSS -->
11
+ <link rel="stylesheet" href="/css/coderay.css" type="text/css" />
12
+
13
+ <!-- Homepage CSS -->
14
+ <link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen, projection" />
15
+ </head>
16
+ <body>
17
+
18
+ <div class="site">
19
+ <div class="title">
20
+ Tom Preston-Werner
21
+ </div>
22
+
23
+ {{ content }}
24
+ </div>
25
+
26
+ </body>
27
+ </html>
@@ -0,0 +1 @@
1
+ <<< {{ content }} >>>
@@ -0,0 +1,8 @@
1
+ ---
2
+ layout: default
3
+ title: Not published!
4
+ published: false
5
+ category: publish_test
6
+ ---
7
+
8
+ This should *not* be published!
@@ -0,0 +1,8 @@
1
+ ---
2
+ layout: default
3
+ title: Publish
4
+ category: publish_test
5
+ ---
6
+
7
+ This should be published.
8
+
@@ -0,0 +1,8 @@
1
+ ---
2
+ layout: default
3
+ title: Foo Bar
4
+ ---
5
+
6
+ h1. {{ page.title }}
7
+
8
+ Best *post* ever
@@ -0,0 +1,8 @@
1
+ ---
2
+ layout: default
3
+ title: Complex
4
+ ---
5
+
6
+ url: {{ page.url }}
7
+ date: {{ page.date }}
8
+ id: {{ page.id }}
@@ -0,0 +1,9 @@
1
+ ---
2
+ title: Post with Permalink
3
+ permalink: my_category/permalinked-post
4
+ ---
5
+
6
+ h1. {{ page.title }}
7
+
8
+
9
+ <p>Best <strong>post</strong> ever</p>
@@ -0,0 +1,8 @@
1
+ ---
2
+ layout: default
3
+ title: Include
4
+ ---
5
+
6
+ {% include sig.markdown %}
7
+
8
+ This _is_ cool
@@ -0,0 +1,10 @@
1
+ ---
2
+ layout: default
3
+ title: Array categories in YAML
4
+ categories:
5
+ - foo
6
+ - bar
7
+ - baz
8
+ ---
9
+
10
+ Best *post* ever
@@ -0,0 +1,7 @@
1
+ ---
2
+ layout: default
3
+ title: Categories in YAML
4
+ categories: foo bar baz
5
+ ---
6
+
7
+ Best *post* ever
@@ -0,0 +1,7 @@
1
+ ---
2
+ layout: default
3
+ title: Category in YAML
4
+ category: foo
5
+ ---
6
+
7
+ Best *post* ever
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default
3
+ title: Hash #1
4
+ ---
5
+
6
+ Hashes are nice
@@ -0,0 +1,6 @@
1
+ ---
2
+ title: A Tag
3
+ tag: code
4
+ ---
5
+
6
+ Whoa.
@@ -0,0 +1,9 @@
1
+ ---
2
+ title: Some Tags
3
+ tags:
4
+ - food
5
+ - cooking
6
+ - pizza
7
+ ---
8
+
9
+ Awesome!
@@ -0,0 +1,3 @@
1
+ ---
2
+ ---
3
+ Empty YAML.
@@ -0,0 +1 @@
1
+ No YAML.
@@ -0,0 +1,6 @@
1
+ ---
2
+ title: About
3
+ permalink: /about/
4
+ ---
5
+
6
+ About the site