matflores-jekyll 0.4.3 → 0.5.0
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.
- data/History.txt +3 -1
- data/README.textile +37 -0
- data/Rakefile +91 -0
- data/VERSION.yml +2 -2
- data/bin/jekyll +60 -56
- data/lib/jekyll.rb +48 -32
- data/lib/jekyll/albino.rb +1 -1
- data/lib/jekyll/converters/mephisto.rb +8 -8
- data/lib/jekyll/converters/mt.rb +8 -8
- data/lib/jekyll/converters/textpattern.rb +4 -4
- data/lib/jekyll/converters/typo.rb +8 -8
- data/lib/jekyll/converters/wordpress.rb +0 -1
- data/lib/jekyll/convertible.rb +33 -22
- data/lib/jekyll/core_ext.rb +5 -5
- data/lib/jekyll/filters.rb +6 -6
- data/lib/jekyll/layout.rb +9 -6
- data/lib/jekyll/page.rb +13 -10
- data/lib/jekyll/post.rb +37 -33
- data/lib/jekyll/site.rb +92 -27
- data/lib/jekyll/tags/highlight.rb +12 -9
- data/lib/jekyll/tags/include.rb +5 -5
- data/test/helper.rb +15 -5
- data/test/source/_posts/2008-02-02-not-published.textile +8 -0
- data/test/source/_posts/2008-02-02-published.textile +8 -0
- data/test/source/_posts/2009-01-27-array-categories.textile +10 -0
- data/test/source/_posts/2009-01-27-categories.textile +7 -0
- data/test/source/_posts/2009-01-27-category.textile +7 -0
- data/test/test_filters.rb +30 -30
- data/test/test_generated_site.rb +58 -55
- data/test/test_post.rb +128 -124
- data/test/test_site.rb +49 -37
- data/test/test_tags.rb +17 -13
- metadata +19 -25
- data/test/test_jekyll.rb +0 -0
data/lib/jekyll/post.rb
CHANGED
@@ -3,13 +3,13 @@ module Jekyll
|
|
3
3
|
class Post
|
4
4
|
include Comparable
|
5
5
|
include Convertible
|
6
|
-
|
6
|
+
|
7
7
|
class << self
|
8
8
|
attr_accessor :lsi
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
|
12
|
-
|
12
|
+
|
13
13
|
# Post name validator. Post filenames must be like:
|
14
14
|
# 2008-11-05-my-awesome-post.textile
|
15
15
|
#
|
@@ -17,34 +17,37 @@ module Jekyll
|
|
17
17
|
def self.valid?(name)
|
18
18
|
name =~ MATCHER
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
|
+
attr_accessor :site
|
21
22
|
attr_accessor :date, :slug, :ext, :categories, :topics, :published
|
22
23
|
attr_accessor :data, :content, :output
|
23
|
-
|
24
|
+
|
24
25
|
# Initialize this Post instance.
|
26
|
+
# +site+ is the Site
|
25
27
|
# +base+ is the String path to the dir containing the post file
|
26
28
|
# +name+ is the String filename of the post file
|
27
29
|
# +categories+ is an Array of Strings for the categories for this post
|
28
30
|
#
|
29
31
|
# Returns <Post>
|
30
|
-
def initialize(source, dir, name)
|
32
|
+
def initialize(site, source, dir, name)
|
33
|
+
@site = site
|
31
34
|
@base = File.join(source, dir, '_posts')
|
32
35
|
@name = name
|
33
|
-
|
36
|
+
|
34
37
|
self.categories = dir.split('/').reject { |x| x.empty? }
|
35
|
-
|
38
|
+
|
36
39
|
parts = name.split('/')
|
37
40
|
self.topics = parts.size > 1 ? parts[0..-2] : []
|
38
|
-
|
41
|
+
|
39
42
|
self.process(name)
|
40
43
|
self.read_yaml(@base, name)
|
41
44
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
if self.data.has_key?('published') && self.data['published'] == false
|
46
|
+
self.published = false
|
47
|
+
else
|
48
|
+
self.published = true
|
49
|
+
end
|
50
|
+
|
48
51
|
if self.categories.empty?
|
49
52
|
if self.data.has_key?('category')
|
50
53
|
self.categories << self.data['category']
|
@@ -59,14 +62,14 @@ module Jekyll
|
|
59
62
|
end
|
60
63
|
end
|
61
64
|
end
|
62
|
-
|
65
|
+
|
63
66
|
# Spaceship is based on Post#date
|
64
67
|
#
|
65
68
|
# Returns -1, 0, 1
|
66
69
|
def <=>(other)
|
67
70
|
self.date <=> other.date
|
68
71
|
end
|
69
|
-
|
72
|
+
|
70
73
|
# Extract information from the post filename
|
71
74
|
# +name+ is the String filename of the post file
|
72
75
|
#
|
@@ -77,7 +80,7 @@ module Jekyll
|
|
77
80
|
self.slug = slug
|
78
81
|
self.ext = ext
|
79
82
|
end
|
80
|
-
|
83
|
+
|
81
84
|
# The generated directory into which the post will be placed
|
82
85
|
# upon generation. This is derived from the permalink or, if
|
83
86
|
# permalink is absent, set to the default date
|
@@ -90,14 +93,14 @@ module Jekyll
|
|
90
93
|
else
|
91
94
|
# I don't want to use categories to define the destination directory
|
92
95
|
# prefix = self.categories.empty? ? '' : '/' + self.categories.join('/')
|
93
|
-
if [:date, :pretty].include?(
|
96
|
+
if [:date, :pretty].include?(self.site.permalink_style)
|
94
97
|
date.strftime("/%Y/%m/%d/")
|
95
98
|
else
|
96
99
|
'/'
|
97
100
|
end
|
98
101
|
end
|
99
102
|
end
|
100
|
-
|
103
|
+
|
101
104
|
# The full path and filename of the post.
|
102
105
|
# Defined in the YAML of the post body
|
103
106
|
# (Optional)
|
@@ -106,16 +109,16 @@ module Jekyll
|
|
106
109
|
def permalink
|
107
110
|
self.data && self.data['permalink']
|
108
111
|
end
|
109
|
-
|
112
|
+
|
110
113
|
# The generated relative url of this post
|
111
114
|
# e.g. /2008/11/05/my-awesome-post.html
|
112
115
|
#
|
113
116
|
# Returns <String>
|
114
117
|
def url
|
115
|
-
ext =
|
118
|
+
ext = self.site.permalink_style == :pretty ? '' : '.html'
|
116
119
|
permalink || self.id + ext
|
117
120
|
end
|
118
|
-
|
121
|
+
|
119
122
|
# The UID for this post (useful in feeds)
|
120
123
|
# e.g. /2008/11/05/my-awesome-post
|
121
124
|
#
|
@@ -123,14 +126,14 @@ module Jekyll
|
|
123
126
|
def id
|
124
127
|
self.dir + self.slug
|
125
128
|
end
|
126
|
-
|
129
|
+
|
127
130
|
# Calculate related posts.
|
128
131
|
#
|
129
132
|
# Returns [<Post>]
|
130
133
|
def related_posts(posts)
|
131
134
|
return [] unless posts.size > 1
|
132
|
-
|
133
|
-
if
|
135
|
+
|
136
|
+
if self.site.lsi
|
134
137
|
self.class.lsi ||= begin
|
135
138
|
puts "Running the classifier... this could take a while."
|
136
139
|
lsi = Classifier::LSI.new
|
@@ -145,7 +148,7 @@ module Jekyll
|
|
145
148
|
(posts - [self])[0..9]
|
146
149
|
end
|
147
150
|
end
|
148
|
-
|
151
|
+
|
149
152
|
# Add any necessary layouts to this post
|
150
153
|
# +layouts+ is a Hash of {"name" => "layout"}
|
151
154
|
# +site_payload+ is the site payload hash
|
@@ -159,20 +162,20 @@ module Jekyll
|
|
159
162
|
"page" => self.to_liquid
|
160
163
|
}
|
161
164
|
payload = payload.deep_merge(site_payload)
|
162
|
-
|
165
|
+
|
163
166
|
do_layout(payload, layouts)
|
164
167
|
end
|
165
|
-
|
168
|
+
|
166
169
|
# Write the generated post file to the destination directory.
|
167
170
|
# +dest+ is the String path to the destination dir
|
168
171
|
#
|
169
172
|
# Returns nothing
|
170
173
|
def write(dest)
|
171
174
|
FileUtils.mkdir_p(File.join(dest, dir))
|
172
|
-
|
175
|
+
|
173
176
|
path = File.join(dest, self.url)
|
174
177
|
|
175
|
-
if
|
178
|
+
if self.site.permalink_style == :pretty
|
176
179
|
FileUtils.mkdir_p(path)
|
177
180
|
path = File.join(path, "index.html")
|
178
181
|
end
|
@@ -181,7 +184,7 @@ module Jekyll
|
|
181
184
|
f.write(self.output)
|
182
185
|
end
|
183
186
|
end
|
184
|
-
|
187
|
+
|
185
188
|
# Convert this post into a Hash for use in Liquid templates.
|
186
189
|
#
|
187
190
|
# Returns <Hash>
|
@@ -191,9 +194,10 @@ module Jekyll
|
|
191
194
|
"date" => self.date,
|
192
195
|
"id" => self.id,
|
193
196
|
"topics" => self.topics,
|
197
|
+
"categories" => self.categories,
|
194
198
|
"content" => self.content }.deep_merge(self.data)
|
195
199
|
end
|
196
|
-
|
200
|
+
|
197
201
|
def inspect
|
198
202
|
"<Post: #{self.id}>"
|
199
203
|
end
|
data/lib/jekyll/site.rb
CHANGED
@@ -1,30 +1,95 @@
|
|
1
1
|
module Jekyll
|
2
|
-
|
2
|
+
|
3
3
|
class Site
|
4
|
-
attr_accessor :
|
5
|
-
attr_accessor :
|
6
|
-
|
4
|
+
attr_accessor :config, :layouts, :posts, :categories, :collated
|
5
|
+
attr_accessor :source, :dest, :lsi, :pygments, :permalink_style
|
6
|
+
|
7
7
|
# Initialize the site
|
8
|
-
# +
|
9
|
-
# the proto-site
|
10
|
-
# +dest+ is the String path to the directory where the generated
|
11
|
-
# site should be written
|
8
|
+
# +config+ is a Hash containing site configurations details
|
12
9
|
#
|
13
10
|
# Returns <Site>
|
14
|
-
def initialize(
|
15
|
-
self.
|
16
|
-
|
17
|
-
self.
|
18
|
-
self.
|
19
|
-
self.
|
20
|
-
self.
|
21
|
-
|
22
|
-
|
11
|
+
def initialize(config)
|
12
|
+
self.config = config.clone
|
13
|
+
|
14
|
+
self.source = config['source']
|
15
|
+
self.dest = config['destination']
|
16
|
+
self.lsi = config['lsi']
|
17
|
+
self.pygments = config['pygments']
|
18
|
+
self.permalink_style = config['permalink'].to_sym
|
19
|
+
|
20
|
+
self.reset
|
21
|
+
self.setup
|
22
|
+
end
|
23
|
+
|
24
|
+
def reset
|
25
|
+
self.layouts = {}
|
26
|
+
self.posts = []
|
27
|
+
self.categories = Hash.new { |hash, key| hash[key] = Array.new }
|
28
|
+
self.collated = {}
|
29
|
+
end
|
30
|
+
|
31
|
+
def setup
|
32
|
+
# Check to see if LSI is enabled.
|
33
|
+
require 'classifier' if self.lsi
|
34
|
+
|
35
|
+
# Set the Markdown interpreter (and Maruku self.config, if necessary)
|
36
|
+
case self.config['markdown']
|
37
|
+
when 'rdiscount'
|
38
|
+
begin
|
39
|
+
require 'rdiscount'
|
40
|
+
|
41
|
+
def markdown(content)
|
42
|
+
RDiscount.new(content).to_html
|
43
|
+
end
|
44
|
+
|
45
|
+
puts 'Using rdiscount for Markdown'
|
46
|
+
rescue LoadError
|
47
|
+
puts 'You must have the rdiscount gem installed first'
|
48
|
+
end
|
49
|
+
when 'maruku'
|
50
|
+
begin
|
51
|
+
require 'maruku'
|
52
|
+
|
53
|
+
def markdown(content)
|
54
|
+
Maruku.new(content).to_html
|
55
|
+
end
|
56
|
+
|
57
|
+
if self.config['maruku']['use_divs']
|
58
|
+
require 'maruku/ext/div'
|
59
|
+
puts 'Maruku: Using extended syntax for div elements.'
|
60
|
+
end
|
61
|
+
|
62
|
+
if self.config['maruku']['use_tex']
|
63
|
+
require 'maruku/ext/math'
|
64
|
+
puts "Maruku: Using LaTeX extension. Images in `#{self.config['maruku']['png_dir']}`."
|
65
|
+
|
66
|
+
# Switch off MathML output
|
67
|
+
MaRuKu::Globals[:html_math_output_mathml] = false
|
68
|
+
MaRuKu::Globals[:html_math_engine] = 'none'
|
69
|
+
|
70
|
+
# Turn on math to PNG support with blahtex
|
71
|
+
# Resulting PNGs stored in `images/latex`
|
72
|
+
MaRuKu::Globals[:html_math_output_png] = true
|
73
|
+
MaRuKu::Globals[:html_png_engine] = self.config['maruku']['png_engine']
|
74
|
+
MaRuKu::Globals[:html_png_dir] = self.config['maruku']['png_dir']
|
75
|
+
MaRuKu::Globals[:html_png_url] = self.config['maruku']['png_url']
|
76
|
+
end
|
77
|
+
rescue LoadError
|
78
|
+
puts "The maruku gem is required for markdown support!"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def textile(content)
|
84
|
+
RedCloth.new(content).to_html
|
85
|
+
end
|
86
|
+
|
23
87
|
# Do the actual work of processing the site and generating the
|
24
88
|
# real deal.
|
25
89
|
#
|
26
90
|
# Returns nothing
|
27
91
|
def process
|
92
|
+
self.reset
|
28
93
|
self.read_layouts
|
29
94
|
self.transform_pages
|
30
95
|
self.write_posts
|
@@ -39,15 +104,15 @@ module Jekyll
|
|
39
104
|
base = File.join(self.source, "_layouts")
|
40
105
|
entries = []
|
41
106
|
Dir.chdir(base) { entries = filter_entries(Dir['*.*']) }
|
42
|
-
|
107
|
+
|
43
108
|
entries.each do |f|
|
44
109
|
name = f.split(".")[0..-2].join(".")
|
45
|
-
self.layouts[name] = Layout.new(base, f)
|
110
|
+
self.layouts[name] = Layout.new(self, base, f)
|
46
111
|
end
|
47
112
|
rescue Errno::ENOENT => e
|
48
113
|
# ignore missing layout dir
|
49
114
|
end
|
50
|
-
|
115
|
+
|
51
116
|
# Read all the files in <base>/_posts and create a new Post object with each one.
|
52
117
|
#
|
53
118
|
# Returns nothing
|
@@ -59,7 +124,7 @@ module Jekyll
|
|
59
124
|
# first pass processes, but does not yet render post content
|
60
125
|
entries.each do |f|
|
61
126
|
if Post.valid?(f)
|
62
|
-
post = Post.new(self.source, dir, f)
|
127
|
+
post = Post.new(self, self.source, dir, f)
|
63
128
|
|
64
129
|
if post.published
|
65
130
|
self.posts << post
|
@@ -67,7 +132,7 @@ module Jekyll
|
|
67
132
|
end
|
68
133
|
end
|
69
134
|
end
|
70
|
-
|
135
|
+
|
71
136
|
# second pass renders each post now that full site payload is available
|
72
137
|
self.posts.each do |post|
|
73
138
|
post.render(self.layouts, site_payload)
|
@@ -93,7 +158,7 @@ module Jekyll
|
|
93
158
|
rescue Errno::ENOENT => e
|
94
159
|
# ignore missing layout dir
|
95
160
|
end
|
96
|
-
|
161
|
+
|
97
162
|
# Write each post to <dest>/<year>/<month>/<day>/<slug>
|
98
163
|
#
|
99
164
|
# Returns nothing
|
@@ -166,7 +231,7 @@ module Jekyll
|
|
166
231
|
directories = entries.select { |e| File.directory?(File.join(base, e)) }
|
167
232
|
files = entries.reject { |e| File.directory?(File.join(base, e)) }
|
168
233
|
|
169
|
-
# we need to make sure to process _posts *first* otherwise they
|
234
|
+
# we need to make sure to process _posts *first* otherwise they
|
170
235
|
# might not be available yet to other templates as {{ site.posts }}
|
171
236
|
if directories.include?('_posts')
|
172
237
|
directories.delete('_posts')
|
@@ -179,10 +244,10 @@ module Jekyll
|
|
179
244
|
transform_pages(File.join(dir, f))
|
180
245
|
else
|
181
246
|
first3 = File.open(File.join(self.source, dir, f)) { |fd| fd.read(3) }
|
182
|
-
|
247
|
+
|
183
248
|
if first3 == "---"
|
184
249
|
# file appears to have a YAML header so process it as a page
|
185
|
-
page = Page.new(self.source, dir, f)
|
250
|
+
page = Page.new(self, self.source, dir, f)
|
186
251
|
page.render(self.layouts, site_payload)
|
187
252
|
page.write(self.dest)
|
188
253
|
else
|
@@ -216,7 +281,7 @@ module Jekyll
|
|
216
281
|
# "topics" => [<Post>] }}
|
217
282
|
def site_payload
|
218
283
|
{"site" => {
|
219
|
-
"time" => Time.now,
|
284
|
+
"time" => Time.now,
|
220
285
|
"posts" => self.posts.sort { |a,b| b <=> a },
|
221
286
|
"collated_posts" => self.collated,
|
222
287
|
"categories" => post_attr_hash('categories'),
|
@@ -1,10 +1,11 @@
|
|
1
1
|
module Jekyll
|
2
|
-
|
2
|
+
|
3
3
|
class HighlightBlock < Liquid::Block
|
4
4
|
include Liquid::StandardFilters
|
5
|
+
|
5
6
|
# we need a language, but the linenos argument is optional.
|
6
7
|
SYNTAX = /(\w+)\s?(:?linenos)?\s?/
|
7
|
-
|
8
|
+
|
8
9
|
def initialize(tag_name, markup, tokens)
|
9
10
|
super
|
10
11
|
if markup =~ SYNTAX
|
@@ -19,23 +20,25 @@ module Jekyll
|
|
19
20
|
raise SyntaxError.new("Syntax Error in 'highlight' - Valid syntax: highlight <lang> [linenos]")
|
20
21
|
end
|
21
22
|
end
|
22
|
-
|
23
|
+
|
23
24
|
def render(context)
|
24
|
-
if
|
25
|
+
if context.registers[:site].pygments
|
25
26
|
render_pygments(context, super.to_s)
|
26
27
|
else
|
27
28
|
render_codehighlighter(context, super.to_s)
|
28
29
|
end
|
29
30
|
end
|
30
|
-
|
31
|
+
|
31
32
|
def render_pygments(context, code)
|
32
|
-
if
|
33
|
+
if context["content_type"] == :markdown
|
33
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>"
|
34
37
|
else
|
35
|
-
|
38
|
+
return Albino.new(code, @lang).to_s(@options)
|
36
39
|
end
|
37
40
|
end
|
38
|
-
|
41
|
+
|
39
42
|
def render_codehighlighter(context, code)
|
40
43
|
#The div is required because RDiscount blows ass
|
41
44
|
<<-HTML
|
@@ -47,7 +50,7 @@ module Jekyll
|
|
47
50
|
HTML
|
48
51
|
end
|
49
52
|
end
|
50
|
-
|
53
|
+
|
51
54
|
end
|
52
55
|
|
53
56
|
Liquid::Template.register_tag('highlight', Jekyll::HighlightBlock)
|
data/lib/jekyll/tags/include.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
module Jekyll
|
2
|
-
|
2
|
+
|
3
3
|
class IncludeTag < Liquid::Tag
|
4
4
|
def initialize(tag_name, file, tokens)
|
5
5
|
super
|
6
6
|
@file = file.strip
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
def render(context)
|
10
10
|
if @file !~ /^[a-zA-Z0-9_\/\.-]+$/ || @file =~ /\.\// || @file =~ /\/\./
|
11
11
|
return "Include file '#{@file}' contains invalid characters or sequences"
|
12
12
|
end
|
13
|
-
|
14
|
-
Dir.chdir(File.join(
|
13
|
+
|
14
|
+
Dir.chdir(File.join(context.registers[:site].source, '_includes')) do
|
15
15
|
choices = Dir['**/*'].reject { |x| File.symlink?(x) }
|
16
16
|
if choices.include?(@file)
|
17
17
|
source = File.read(@file)
|
@@ -25,7 +25,7 @@ module Jekyll
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
end
|
30
30
|
|
31
31
|
Liquid::Template.register_tag('include', Jekyll::IncludeTag)
|