jekyll 0.3.0 → 0.4.1

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.

Potentially problematic release.


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

Files changed (44) hide show
  1. data/History.txt +25 -0
  2. data/README.textile +93 -23
  3. data/VERSION.yml +4 -0
  4. data/bin/jekyll +9 -0
  5. data/lib/jekyll.rb +7 -3
  6. data/lib/jekyll/converters/mephisto.rb +56 -1
  7. data/lib/jekyll/converters/mt.rb +1 -1
  8. data/lib/jekyll/converters/textpattern.rb +50 -0
  9. data/lib/jekyll/converters/typo.rb +49 -0
  10. data/lib/jekyll/converters/wordpress.rb +9 -8
  11. data/lib/jekyll/convertible.rb +14 -3
  12. data/lib/jekyll/filters.rb +18 -3
  13. data/lib/jekyll/post.rb +9 -5
  14. data/lib/jekyll/site.rb +45 -28
  15. data/lib/jekyll/tags/highlight.rb +20 -4
  16. data/lib/jekyll/tags/include.rb +6 -2
  17. data/test/dest/2008/10/18/foo-bar.html +28 -0
  18. data/test/dest/2008/11/21/complex.html +29 -0
  19. data/test/dest/2008/12/13/include.html +30 -0
  20. data/test/dest/_posts/2008-10-18-foo-bar.html +28 -0
  21. data/test/dest/_posts/2008-11-21-complex.html +29 -0
  22. data/test/dest/_posts/2008-12-03-permalinked-post.html +2 -0
  23. data/test/dest/_posts/2008-12-13-include.html +30 -0
  24. data/test/dest/category/2008/09/23/categories.html +27 -0
  25. data/test/dest/category/_posts/2008-9-23-categories.html +27 -0
  26. data/test/dest/css/screen.css +76 -0
  27. data/test/dest/foo/2008/12/12/topical-post.html +28 -0
  28. data/test/dest/foo/_posts/bar/2008-12-12-topical-post.html +28 -0
  29. data/test/dest/index.html +60 -0
  30. data/test/dest/my_category/permalinked-post +2 -0
  31. data/test/dest/z_category/2008/09/23/categories.html +27 -0
  32. data/test/dest/z_category/_posts/2008-9-23-categories.html +27 -0
  33. data/test/source/category/_posts/2008-9-23-categories.textile +6 -0
  34. data/test/source/foo/_posts/bar/2008-12-12-topical-post.textile +8 -0
  35. data/test/source/z_category/_posts/2008-9-23-categories.textile +6 -0
  36. data/test/test_filters.rb +37 -0
  37. data/test/test_generated_site.rb +1 -0
  38. data/test/test_post.rb +15 -1
  39. data/test/test_site.rb +5 -2
  40. data/test/test_tags.rb +31 -0
  41. metadata +85 -37
  42. data/Manifest.txt +0 -36
  43. data/Rakefile +0 -24
  44. data/jekyll.gemspec +0 -51
@@ -24,16 +24,26 @@ module Jekyll
24
24
  #
25
25
  # Returns nothing
26
26
  def transform
27
- case self.ext
28
- when ".textile":
27
+ case Jekyll.content_type
28
+ when :textile
29
29
  self.ext = ".html"
30
30
  self.content = RedCloth.new(self.content).to_html
31
- when ".markdown":
31
+ when :markdown
32
32
  self.ext = ".html"
33
33
  self.content = Jekyll.markdown_proc.call(self.content)
34
34
  end
35
35
  end
36
36
 
37
+ def determine_content_type
38
+ case self.ext[1..-1]
39
+ when /textile/i
40
+ return :textile
41
+ when /markdown/i, /mkdn/i, /md/i
42
+ return :markdown
43
+ end
44
+ return :unknown
45
+ end
46
+
37
47
  # Add any necessary layouts to this convertible document
38
48
  # +layouts+ is a Hash of {"name" => "layout"}
39
49
  # +site_payload+ is the site payload hash
@@ -41,6 +51,7 @@ module Jekyll
41
51
  # Returns nothing
42
52
  def do_layout(payload, layouts)
43
53
  # render and transform content (this becomes the final content of the object)
54
+ Jekyll.content_type = self.determine_content_type
44
55
  self.content = Liquid::Template.parse(self.content).render(payload, [Jekyll::Filters])
45
56
  self.transform
46
57
 
@@ -14,11 +14,26 @@ module Jekyll
14
14
  end
15
15
 
16
16
  def xml_escape(input)
17
- input.gsub("<", "&lt;").gsub(">", "&gt;")
17
+ input.gsub("&", "&amp;").gsub("<", "&lt;").gsub(">", "&gt;")
18
18
  end
19
19
 
20
20
  def number_of_words(input)
21
21
  input.split.length
22
- end
22
+ end
23
+
24
+ def array_to_sentence_string(array)
25
+ connector = "and"
26
+ case array.length
27
+ when 0
28
+ ""
29
+ when 1
30
+ array[0].to_s
31
+ when 2
32
+ "#{array[0]} #{connector} #{array[1]}"
33
+ else
34
+ "#{array[0...-1].join(', ')}, #{connector} #{array[-1]}"
35
+ end
36
+ end
37
+
23
38
  end
24
- end
39
+ end
data/lib/jekyll/post.rb CHANGED
@@ -61,15 +61,19 @@ module Jekyll
61
61
  # The generated directory into which the post will be placed
62
62
  # upon generation. This is derived from the permalink or, if
63
63
  # permalink is absent, set to the default date
64
- # e.g. "/2008/11/05/"
64
+ # e.g. "/2008/11/05/" if the permalink style is :date, otherwise nothing
65
65
  #
66
66
  # Returns <String>
67
67
  def dir
68
68
  if permalink
69
- permalink.to_s.split("/")[0..-2].join("/")
69
+ permalink.to_s.split("/")[0..-2].join("/") + '/'
70
70
  else
71
71
  prefix = self.categories.empty? ? '' : '/' + self.categories.join('/')
72
- prefix + date.strftime("/%Y/%m/%d/")
72
+ if Jekyll.permalink_style == :date
73
+ prefix + date.strftime("/%Y/%m/%d/")
74
+ else
75
+ prefix + '/'
76
+ end
73
77
  end
74
78
  end
75
79
 
@@ -87,7 +91,7 @@ module Jekyll
87
91
  #
88
92
  # Returns <String>
89
93
  def url
90
- self.dir + self.slug + ".html"
94
+ permalink || self.dir + self.slug + ".html"
91
95
  end
92
96
 
93
97
  # The UID for this post (useful in feeds)
@@ -154,7 +158,7 @@ module Jekyll
154
158
  #
155
159
  # Returns <Hash>
156
160
  def to_liquid
157
- { "title" => self.data["title"] || "",
161
+ { "title" => self.data["title"] || self.slug.split('-').select {|w| w.capitalize! || w }.join(' '),
158
162
  "url" => self.url,
159
163
  "date" => self.date,
160
164
  "id" => self.id,
data/lib/jekyll/site.rb CHANGED
@@ -2,7 +2,7 @@ module Jekyll
2
2
 
3
3
  class Site
4
4
  attr_accessor :source, :dest
5
- attr_accessor :layouts, :posts
5
+ attr_accessor :layouts, :posts, :categories
6
6
 
7
7
  # Initialize the site
8
8
  # +source+ is String path to the source directory containing
@@ -16,6 +16,7 @@ module Jekyll
16
16
  self.dest = dest
17
17
  self.layouts = {}
18
18
  self.posts = []
19
+ self.categories = Hash.new { |hash, key| hash[key] = Array.new }
19
20
  end
20
21
 
21
22
  # Do the actual work of processing the site and generating the
@@ -63,6 +64,7 @@ module Jekyll
63
64
  if Post.valid?(f)
64
65
  post = Post.new(self.source, dir, f)
65
66
  self.posts << post
67
+ post.categories.each { |c| self.categories[c] << post }
66
68
  end
67
69
  end
68
70
 
@@ -72,6 +74,7 @@ module Jekyll
72
74
  end
73
75
 
74
76
  self.posts.sort!
77
+ self.categories.values.map { |cats| cats.sort! { |a, b| b <=> a} }
75
78
  rescue Errno::ENOENT => e
76
79
  # ignore missing layout dir
77
80
  end
@@ -88,7 +91,8 @@ module Jekyll
88
91
  # Copy all regular files from <source> to <dest>/ ignoring
89
92
  # any files/directories that are hidden or backup files (start
90
93
  # with "." or end with "~") or contain site content (start with "_")
91
- # unless they are "_posts" directories
94
+ # unless they are "_posts" directories or web server files such as
95
+ # '.htaccess'
92
96
  # The +dir+ String is a relative path used to call this method
93
97
  # recursively as it descends through directories
94
98
  #
@@ -98,8 +102,10 @@ module Jekyll
98
102
  entries = Dir.entries(base)
99
103
  entries = entries.reject { |e| e[-1..-1] == '~' }
100
104
  entries = entries.reject do |e|
101
- (e != '_posts') and ['.', '_'].include?(e[0..0])
105
+ (e != '_posts') and ['.', '_'].include?(e[0..0]) unless ['.htaccess'].include?(e)
102
106
  end
107
+ directories = entries.select { |e| File.directory?(File.join(base, e)) }
108
+ files = entries.reject { |e| File.directory?(File.join(base, e)) }
103
109
 
104
110
  # we need to make sure to process _posts *first* otherwise they
105
111
  # might not be available yet to other templates as {{ site.posts }}
@@ -107,42 +113,53 @@ module Jekyll
107
113
  entries.delete('_posts')
108
114
  read_posts(dir)
109
115
  end
110
-
111
- entries.each do |f|
112
- if File.directory?(File.join(base, f))
113
- next if self.dest.sub(/\/$/, '') == File.join(base, f)
114
- transform_pages(File.join(dir, f))
115
- else
116
- first3 = File.open(File.join(self.source, dir, f)) { |fd| fd.read(3) }
117
-
118
- if first3 == "---"
119
- # file appears to have a YAML header so process it as a page
120
- page = Page.new(self.source, dir, f)
121
- page.render(self.layouts, site_payload)
122
- page.write(self.dest)
116
+ [directories, files].each do |entries|
117
+ entries.each do |f|
118
+ if File.directory?(File.join(base, f))
119
+ next if self.dest.sub(/\/$/, '') == File.join(base, f)
120
+ transform_pages(File.join(dir, f))
123
121
  else
124
- # otherwise copy the file without transforming it
125
- FileUtils.mkdir_p(File.join(self.dest, dir))
126
- FileUtils.cp(File.join(self.source, dir, f), File.join(self.dest, dir, f))
122
+ first3 = File.open(File.join(self.source, dir, f)) { |fd| fd.read(3) }
123
+
124
+ if first3 == "---"
125
+ # file appears to have a YAML header so process it as a page
126
+ page = Page.new(self.source, dir, f)
127
+ page.render(self.layouts, site_payload)
128
+ page.write(self.dest)
129
+ else
130
+ # otherwise copy the file without transforming it
131
+ FileUtils.mkdir_p(File.join(self.dest, dir))
132
+ FileUtils.cp(File.join(self.source, dir, f), File.join(self.dest, dir, f))
133
+ end
127
134
  end
128
135
  end
129
136
  end
130
137
  end
131
-
138
+
139
+ # Constructs a hash map of Posts indexed by the specified Post attribute
140
+ #
141
+ # Returns {post_attr => [<Post>]}
142
+ def post_attr_hash(post_attr)
143
+ # Build a hash map based on the specified post attribute ( post attr => array of posts )
144
+ # then sort each array in reverse order
145
+ hash = Hash.new { |hash, key| hash[key] = Array.new }
146
+ self.posts.each { |p| p.send(post_attr.to_sym).each { |t| hash[t] << p } }
147
+ hash.values.map { |sortme| sortme.sort! { |a, b| b <=> a} }
148
+ return hash
149
+ end
150
+
132
151
  # The Hash payload containing site-wide data
133
152
  #
134
- # Returns {"site" => {"time" => <Time>, "posts" => [<Post>]}}
153
+ # Returns {"site" => {"time" => <Time>,
154
+ # "posts" => [<Post>],
155
+ # "categories" => [<Post>],
156
+ # "topics" => [<Post>] }}
135
157
  def site_payload
136
- # Build the category hash map of category ( names => arrays of posts )
137
- # then sort each array in reverse order
138
- categories = Hash.new { |hash, key| hash[key] = Array.new }
139
- self.posts.each { |p| p.categories.each { |c| categories[c] << p } }
140
- categories.values.map { |cats| cats.sort! { |a, b| b <=> a} }
141
-
142
158
  {"site" => {
143
159
  "time" => Time.now,
144
160
  "posts" => self.posts.sort { |a,b| b <=> a },
145
- "categories" => categories
161
+ "categories" => post_attr_hash('categories'),
162
+ "topics" => post_attr_hash('topics')
146
163
  }}
147
164
  end
148
165
  end
@@ -2,10 +2,22 @@ module Jekyll
2
2
 
3
3
  class HighlightBlock < Liquid::Block
4
4
  include Liquid::StandardFilters
5
+ # we need a language, but the linenos argument is optional.
6
+ SYNTAX = /(\w+)\s?(:?linenos)?\s?/
5
7
 
6
- def initialize(tag_name, lang, tokens)
8
+ def initialize(tag_name, markup, tokens)
7
9
  super
8
- @lang = lang.strip
10
+ if markup =~ SYNTAX
11
+ @lang = $1
12
+ if defined? $2
13
+ # additional options to pass to Albino.
14
+ @options = { 'O' => 'linenos=inline' }
15
+ else
16
+ @options = {}
17
+ end
18
+ else
19
+ raise SyntaxError.new("Syntax Error in 'highlight' - Valid syntax: highlight <lang> [linenos]")
20
+ end
9
21
  end
10
22
 
11
23
  def render(context)
@@ -17,7 +29,11 @@ module Jekyll
17
29
  end
18
30
 
19
31
  def render_pygments(context, code)
20
- "<notextile>" + Albino.new(code, @lang).to_s + "</notextile>"
32
+ if Jekyll.content_type == :markdown
33
+ return "\n" + Albino.new(code, @lang).to_s(@options) + "\n"
34
+ else
35
+ "<notextile>" + Albino.new(code, @lang).to_s(@options) + "</notextile>"
36
+ end
21
37
  end
22
38
 
23
39
  def render_codehighlighter(context, code)
@@ -34,4 +50,4 @@ module Jekyll
34
50
 
35
51
  end
36
52
 
37
- Liquid::Template.register_tag('highlight', Jekyll::HighlightBlock)
53
+ Liquid::Template.register_tag('highlight', Jekyll::HighlightBlock)
@@ -14,7 +14,11 @@ module Jekyll
14
14
  Dir.chdir(File.join(Jekyll.source, '_includes')) do
15
15
  choices = Dir['**/*'].reject { |x| File.symlink?(x) }
16
16
  if choices.include?(@file)
17
- File.read(@file)
17
+ source = File.read(@file)
18
+ partial = Liquid::Template.parse(source)
19
+ context.stack do
20
+ partial.render(context)
21
+ end
18
22
  else
19
23
  "Included file '#{@file}' not found in _includes directory"
20
24
  end
@@ -24,4 +28,4 @@ module Jekyll
24
28
 
25
29
  end
26
30
 
27
- Liquid::Template.register_tag('include', Jekyll::IncludeTag)
31
+ Liquid::Template.register_tag('include', Jekyll::IncludeTag)
@@ -0,0 +1,28 @@
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>Foo Bar</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
+ <h1>Foo Bar</h1>
24
+ <p>Best <strong>post</strong> ever</p>
25
+ </div>
26
+
27
+ </body>
28
+ </html>
@@ -0,0 +1,29 @@
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>Complex</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
+ <p>url: /2008/11/21/complex.html<br />
24
+ date: Fri Nov 21 00:00:00 -0800 2008<br />
25
+ id: /2008/11/21/complex</p>
26
+ </div>
27
+
28
+ </body>
29
+ </html>
@@ -0,0 +1,30 @@
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>Include</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
+ <hr />
24
+ <p>Tom Preston-Werner github.com/mojombo</p>
25
+
26
+ <p>This <em>is</em> cool</p>
27
+ </div>
28
+
29
+ </body>
30
+ </html>
@@ -0,0 +1,28 @@
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>Foo Bar</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
+ <h1>Foo Bar</h1>
24
+ <p>Best <strong>post</strong> ever</p>
25
+ </div>
26
+
27
+ </body>
28
+ </html>
@@ -0,0 +1,29 @@
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>Complex</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
+ <p>url: <br />
24
+ date: <br />
25
+ id:</p>
26
+ </div>
27
+
28
+ </body>
29
+ </html>