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/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
- if self.data.has_key?('published') && self.data['published'] == false
43
- self.published = false
44
- else
45
- self.published = true
46
- end
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?(Jekyll.permalink_style)
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 = Jekyll.permalink_style == :pretty ? '' : '.html'
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 Jekyll.lsi
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 Jekyll.permalink_style == :pretty
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 :source, :dest
5
- attr_accessor :layouts, :posts, :categories, :collated
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
- # +source+ is String path to the source directory containing
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(source, dest)
15
- self.source = source
16
- self.dest = dest
17
- self.layouts = {}
18
- self.posts = []
19
- self.categories = Hash.new { |hash, key| hash[key] = Array.new }
20
- self.collated = {}
21
- end
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 Jekyll.pygments
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 Jekyll.content_type == :markdown
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
- "<notextile>" + Albino.new(code, @lang).to_s(@options) + "</notextile>"
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)
@@ -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(Jekyll.source, '_includes')) do
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)