sixones-jekyll 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.
Files changed (43) hide show
  1. data/History.txt +113 -0
  2. data/README.textile +539 -0
  3. data/VERSION.yml +4 -0
  4. data/bin/jekyll +140 -0
  5. data/lib/jekyll/albino.rb +120 -0
  6. data/lib/jekyll/converters/csv.rb +26 -0
  7. data/lib/jekyll/converters/mephisto.rb +79 -0
  8. data/lib/jekyll/converters/mt.rb +59 -0
  9. data/lib/jekyll/converters/textpattern.rb +50 -0
  10. data/lib/jekyll/converters/typo.rb +49 -0
  11. data/lib/jekyll/converters/wordpress.rb +55 -0
  12. data/lib/jekyll/convertible.rb +71 -0
  13. data/lib/jekyll/core_ext.rb +22 -0
  14. data/lib/jekyll/custom_filters.rb +13 -0
  15. data/lib/jekyll/filters.rb +41 -0
  16. data/lib/jekyll/layout.rb +33 -0
  17. data/lib/jekyll/page.rb +64 -0
  18. data/lib/jekyll/post.rb +201 -0
  19. data/lib/jekyll/site.rb +190 -0
  20. data/lib/jekyll/tags/highlight.rb +53 -0
  21. data/lib/jekyll/tags/include.rb +31 -0
  22. data/lib/jekyll.rb +69 -0
  23. data/test/helper.rb +14 -0
  24. data/test/source/_includes/sig.markdown +3 -0
  25. data/test/source/_layouts/default.html +27 -0
  26. data/test/source/_layouts/simple.html +1 -0
  27. data/test/source/_posts/2008-10-18-foo-bar.textile +8 -0
  28. data/test/source/_posts/2008-11-21-complex.textile +8 -0
  29. data/test/source/_posts/2008-12-03-permalinked-post.textile +9 -0
  30. data/test/source/_posts/2008-12-13-include.markdown +8 -0
  31. data/test/source/category/_posts/2008-9-23-categories.textile +6 -0
  32. data/test/source/css/screen.css +76 -0
  33. data/test/source/foo/_posts/bar/2008-12-12-topical-post.textile +8 -0
  34. data/test/source/index.html +22 -0
  35. data/test/source/z_category/_posts/2008-9-23-categories.textile +6 -0
  36. data/test/suite.rb +9 -0
  37. data/test/test_filters.rb +41 -0
  38. data/test/test_generated_site.rb +32 -0
  39. data/test/test_jekyll.rb +0 -0
  40. data/test/test_post.rb +135 -0
  41. data/test/test_site.rb +45 -0
  42. data/test/test_tags.rb +31 -0
  43. metadata +212 -0
@@ -0,0 +1,41 @@
1
+ module Jekyll
2
+ module Filters
3
+ def textilize(input)
4
+ RedCloth.new(input).to_html
5
+ end
6
+
7
+ def date_to_string(date)
8
+ date.strftime("%d %b %Y")
9
+ end
10
+
11
+ def date_to_long_string(date)
12
+ date.strftime("%d %B %Y")
13
+ end
14
+
15
+ def date_to_xmlschema(date)
16
+ date.xmlschema
17
+ end
18
+
19
+ def xml_escape(input)
20
+ input.gsub("&", "&amp;").gsub("<", "&lt;").gsub(">", "&gt;")
21
+ end
22
+
23
+ def number_of_words(input)
24
+ input.split.length
25
+ end
26
+
27
+ def array_to_sentence_string(array)
28
+ connector = "and"
29
+ case array.length
30
+ when 0
31
+ ""
32
+ when 1
33
+ array[0].to_s
34
+ when 2
35
+ "#{array[0]} #{connector} #{array[1]}"
36
+ else
37
+ "#{array[0...-1].join(', ')}, #{connector} #{array[-1]}"
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,33 @@
1
+ module Jekyll
2
+
3
+ class Layout
4
+ include Convertible
5
+
6
+ attr_accessor :ext
7
+ attr_accessor :data, :content
8
+
9
+ # Initialize a new Layout.
10
+ # +base+ is the String path to the <source>
11
+ # +name+ is the String filename of the post file
12
+ #
13
+ # Returns <Page>
14
+ def initialize(base, name)
15
+ @base = base
16
+ @name = name
17
+
18
+ self.data = {}
19
+
20
+ self.process(name)
21
+ self.read_yaml(base, name)
22
+ end
23
+
24
+ # Extract information from the layout filename
25
+ # +name+ is the String filename of the layout file
26
+ #
27
+ # Returns nothing
28
+ def process(name)
29
+ self.ext = File.extname(name)
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,64 @@
1
+ module Jekyll
2
+
3
+ class Page
4
+ include Convertible
5
+
6
+ attr_accessor :ext
7
+ attr_accessor :data, :content, :output
8
+
9
+ # Initialize a new Page.
10
+ # +base+ is the String path to the <source>
11
+ # +dir+ is the String path between <source> and the file
12
+ # +name+ is the String filename of the file
13
+ #
14
+ # Returns <Page>
15
+ def initialize(base, dir, name)
16
+ @base = base
17
+ @dir = dir
18
+ @name = name
19
+
20
+ self.data = {}
21
+
22
+ self.process(name)
23
+ self.read_yaml(File.join(base, dir), name)
24
+ #self.transform
25
+ end
26
+
27
+ # Extract information from the page filename
28
+ # +name+ is the String filename of the page file
29
+ #
30
+ # Returns nothing
31
+ def process(name)
32
+ self.ext = File.extname(name)
33
+ end
34
+
35
+ # Add any necessary layouts to this post
36
+ # +layouts+ is a Hash of {"name" => "layout"}
37
+ # +site_payload+ is the site payload hash
38
+ #
39
+ # Returns nothing
40
+ def render(layouts, site_payload)
41
+ payload = {"page" => self.data}.deep_merge(site_payload)
42
+ do_layout(payload, layouts)
43
+ end
44
+
45
+ # Write the generated page file to the destination directory.
46
+ # +dest+ is the String path to the destination dir
47
+ #
48
+ # Returns nothing
49
+ def write(dest)
50
+ FileUtils.mkdir_p(File.join(dest, @dir))
51
+
52
+ name = @name
53
+ if self.ext != ""
54
+ name = @name.split(".")[0..-2].join('.') + self.ext
55
+ end
56
+
57
+ path = File.join(dest, @dir, name)
58
+ File.open(path, 'w') do |f|
59
+ f.write(self.output)
60
+ end
61
+ end
62
+ end
63
+
64
+ end
@@ -0,0 +1,201 @@
1
+ module Jekyll
2
+
3
+ class Post
4
+ include Comparable
5
+ include Convertible
6
+
7
+ class << self
8
+ attr_accessor :lsi
9
+ end
10
+
11
+ MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
12
+
13
+ # Post name validator. Post filenames must be like:
14
+ # 2008-11-05-my-awesome-post.textile
15
+ #
16
+ # Returns <Bool>
17
+ def self.valid?(name)
18
+ name =~ MATCHER
19
+ end
20
+
21
+ attr_accessor :date, :slug, :ext, :categories, :topics, :published
22
+ attr_accessor :data, :content, :output
23
+
24
+ # Initialize this Post instance.
25
+ # +base+ is the String path to the dir containing the post file
26
+ # +name+ is the String filename of the post file
27
+ # +categories+ is an Array of Strings for the categories for this post
28
+ #
29
+ # Returns <Post>
30
+ def initialize(source, dir, name)
31
+ @base = File.join(source, dir, '_posts')
32
+ @name = name
33
+
34
+ self.categories = dir.split('/').reject { |x| x.empty? }
35
+
36
+ parts = name.split('/')
37
+ self.topics = parts.size > 1 ? parts[0..-2] : []
38
+
39
+ self.process(name)
40
+ self.read_yaml(@base, name)
41
+
42
+ if self.data.has_key?('published') && self.data['published'] == false
43
+ self.published = false
44
+ else
45
+ self.published = true
46
+ end
47
+
48
+ if self.categories.empty?
49
+ if self.data.has_key?('category')
50
+ self.categories << self.data['category']
51
+ elsif self.data.has_key?('categories')
52
+ # Look for categories in the YAML-header, either specified as
53
+ # an array or a string.
54
+ if self.data['categories'].kind_of? String
55
+ self.categories = self.data['categories'].split
56
+ else
57
+ self.categories = self.data['categories']
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ # Spaceship is based on Post#date
64
+ #
65
+ # Returns -1, 0, 1
66
+ def <=>(other)
67
+ self.date <=> other.date
68
+ end
69
+
70
+ # Extract information from the post filename
71
+ # +name+ is the String filename of the post file
72
+ #
73
+ # Returns nothing
74
+ def process(name)
75
+ m, cats, date, slug, ext = *name.match(MATCHER)
76
+ self.date = Time.parse(date)
77
+ self.slug = slug
78
+ self.ext = ext
79
+ end
80
+
81
+ # The generated directory into which the post will be placed
82
+ # upon generation. This is derived from the permalink or, if
83
+ # permalink is absent, set to the default date
84
+ # e.g. "/2008/11/05/" if the permalink style is :date, otherwise nothing
85
+ #
86
+ # Returns <String>
87
+ def dir
88
+ if permalink
89
+ permalink.to_s.split("/")[0..-2].join("/") + '/'
90
+ else
91
+ prefix = self.categories.empty? ? '' : '/' + self.categories.join('/')
92
+ if [:date, :pretty].include?(Jekyll.permalink_style)
93
+ prefix + date.strftime("/%Y/%m/%d/")
94
+ else
95
+ prefix + '/'
96
+ end
97
+ end
98
+ end
99
+
100
+ # The full path and filename of the post.
101
+ # Defined in the YAML of the post body
102
+ # (Optional)
103
+ #
104
+ # Returns <String>
105
+ def permalink
106
+ self.data && self.data['permalink']
107
+ end
108
+
109
+ # The generated relative url of this post
110
+ # e.g. /2008/11/05/my-awesome-post.html
111
+ #
112
+ # Returns <String>
113
+ def url
114
+ ext = Jekyll.permalink_style == :pretty ? '' : '.html'
115
+ permalink || self.id + ext
116
+ end
117
+
118
+ # The UID for this post (useful in feeds)
119
+ # e.g. /2008/11/05/my-awesome-post
120
+ #
121
+ # Returns <String>
122
+ def id
123
+ self.dir + self.slug
124
+ end
125
+
126
+ # Calculate related posts.
127
+ #
128
+ # Returns [<Post>]
129
+ def related_posts(posts)
130
+ return [] unless posts.size > 1
131
+
132
+ if Jekyll.lsi
133
+ self.class.lsi ||= begin
134
+ puts "Running the classifier... this could take a while."
135
+ lsi = Classifier::LSI.new
136
+ posts.each { |x| $stdout.print(".");$stdout.flush;lsi.add_item(x) }
137
+ puts ""
138
+ lsi
139
+ end
140
+
141
+ related = self.class.lsi.find_related(self.content, 11)
142
+ related - [self]
143
+ else
144
+ (posts - [self])[0..9]
145
+ end
146
+ end
147
+
148
+ # Add any necessary layouts to this post
149
+ # +layouts+ is a Hash of {"name" => "layout"}
150
+ # +site_payload+ is the site payload hash
151
+ #
152
+ # Returns nothing
153
+ def render(layouts, site_payload)
154
+ # construct payload
155
+ payload =
156
+ {
157
+ "site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) },
158
+ "page" => self.to_liquid
159
+ }
160
+ payload = payload.deep_merge(site_payload)
161
+
162
+ do_layout(payload, layouts)
163
+ end
164
+
165
+ # Write the generated post file to the destination directory.
166
+ # +dest+ is the String path to the destination dir
167
+ #
168
+ # Returns nothing
169
+ def write(dest)
170
+ FileUtils.mkdir_p(File.join(dest, dir))
171
+
172
+ path = File.join(dest, self.url)
173
+
174
+ if Jekyll.permalink_style == :pretty
175
+ FileUtils.mkdir_p(path)
176
+ path = File.join(path, "index.html")
177
+ end
178
+
179
+ File.open(path, 'w') do |f|
180
+ f.write(self.output)
181
+ end
182
+ end
183
+
184
+ # Convert this post into a Hash for use in Liquid templates.
185
+ #
186
+ # Returns <Hash>
187
+ def to_liquid
188
+ { "title" => self.data["title"] || self.slug.split('-').select {|w| w.capitalize! || w }.join(' '),
189
+ "url" => self.url,
190
+ "date" => self.date,
191
+ "id" => self.id,
192
+ "topics" => self.topics,
193
+ "content" => self.content }.deep_merge(self.data)
194
+ end
195
+
196
+ def inspect
197
+ "<Post: #{self.id}>"
198
+ end
199
+ end
200
+
201
+ end
@@ -0,0 +1,190 @@
1
+ module Jekyll
2
+
3
+ class Site
4
+ attr_accessor :source, :dest
5
+ attr_accessor :layouts, :posts, :categories
6
+
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
12
+ #
13
+ # 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
+ end
21
+
22
+ # Do the actual work of processing the site and generating the
23
+ # real deal.
24
+ #
25
+ # Returns nothing
26
+ def process
27
+ self.read_filters
28
+ self.read_layouts
29
+ self.transform_pages
30
+ self.write_posts
31
+ end
32
+
33
+ def read_filters
34
+ if Jekyll.custom_filters
35
+ base = File.join(self.source, "_filters")
36
+
37
+ if File.exists?(base)
38
+ entries = [ ]
39
+
40
+ Dir.chdir(base) { entries = filter_entries(Dir['*.rb*']) }
41
+
42
+ entries.each do |f|
43
+ require File.join(base, f)
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ # Read all the files in <source>/_layouts into memory for later use.
50
+ #
51
+ # Returns nothing
52
+ def read_layouts
53
+ base = File.join(self.source, "_layouts")
54
+ entries = []
55
+ Dir.chdir(base) { entries = filter_entries(Dir['*.*']) }
56
+
57
+ entries.each do |f|
58
+ name = f.split(".")[0..-2].join(".")
59
+ self.layouts[name] = Layout.new(base, f)
60
+ end
61
+ rescue Errno::ENOENT => e
62
+ # ignore missing layout dir
63
+ end
64
+
65
+ # Read all the files in <base>/_posts and create a new Post object with each one.
66
+ #
67
+ # Returns nothing
68
+ def read_posts(dir)
69
+ base = File.join(self.source, dir, '_posts')
70
+ entries = []
71
+ Dir.chdir(base) { entries = filter_entries(Dir['**/*']) }
72
+
73
+ # first pass processes, but does not yet render post content
74
+ entries.each do |f|
75
+ if Post.valid?(f)
76
+ post = Post.new(self.source, dir, f)
77
+
78
+ if post.published
79
+ self.posts << post
80
+ post.categories.each { |c| self.categories[c] << post }
81
+ end
82
+ end
83
+ end
84
+
85
+ # second pass renders each post now that full site payload is available
86
+ self.posts.each do |post|
87
+ post.render(self.layouts, site_payload)
88
+ end
89
+
90
+ self.posts.sort!
91
+ self.categories.values.map { |cats| cats.sort! { |a, b| b <=> a} }
92
+ rescue Errno::ENOENT => e
93
+ # ignore missing layout dir
94
+ end
95
+
96
+ # Write each post to <dest>/<year>/<month>/<day>/<slug>
97
+ #
98
+ # Returns nothing
99
+ def write_posts
100
+ self.posts.each do |post|
101
+ post.write(self.dest)
102
+ end
103
+ end
104
+
105
+ # Copy all regular files from <source> to <dest>/ ignoring
106
+ # any files/directories that are hidden or backup files (start
107
+ # with "." or "#" or end with "~") or contain site content (start with "_")
108
+ # unless they are "_posts" directories or web server files such as
109
+ # '.htaccess'
110
+ # The +dir+ String is a relative path used to call this method
111
+ # recursively as it descends through directories
112
+ #
113
+ # Returns nothing
114
+ def transform_pages(dir = '')
115
+ base = File.join(self.source, dir)
116
+ entries = filter_entries(Dir.entries(base))
117
+ directories = entries.select { |e| File.directory?(File.join(base, e)) }
118
+ files = entries.reject { |e| File.directory?(File.join(base, e)) }
119
+
120
+ # we need to make sure to process _posts *first* otherwise they
121
+ # might not be available yet to other templates as {{ site.posts }}
122
+ if directories.include?('_posts')
123
+ directories.delete('_posts')
124
+ read_posts(dir)
125
+ end
126
+ [directories, files].each do |entries|
127
+ entries.each do |f|
128
+ if File.directory?(File.join(base, f))
129
+ next if self.dest.sub(/\/$/, '') == File.join(base, f)
130
+ transform_pages(File.join(dir, f))
131
+ else
132
+ first3 = File.open(File.join(self.source, dir, f)) { |fd| fd.read(3) }
133
+
134
+ if first3 == "---"
135
+ # file appears to have a YAML header so process it as a page
136
+ page = Page.new(self.source, dir, f)
137
+ page.render(self.layouts, site_payload)
138
+ page.write(self.dest)
139
+ else
140
+ # otherwise copy the file without transforming it
141
+ FileUtils.mkdir_p(File.join(self.dest, dir))
142
+ FileUtils.cp(File.join(self.source, dir, f), File.join(self.dest, dir, f))
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ # Constructs a hash map of Posts indexed by the specified Post attribute
150
+ #
151
+ # Returns {post_attr => [<Post>]}
152
+ def post_attr_hash(post_attr)
153
+ # Build a hash map based on the specified post attribute ( post attr => array of posts )
154
+ # then sort each array in reverse order
155
+ hash = Hash.new { |hash, key| hash[key] = Array.new }
156
+ self.posts.each { |p| p.send(post_attr.to_sym).each { |t| hash[t] << p } }
157
+ hash.values.map { |sortme| sortme.sort! { |a, b| b <=> a} }
158
+ return hash
159
+ end
160
+
161
+ # The Hash payload containing site-wide data
162
+ #
163
+ # Returns {"site" => {"time" => <Time>,
164
+ # "posts" => [<Post>],
165
+ # "categories" => [<Post>],
166
+ # "topics" => [<Post>] }}
167
+ def site_payload
168
+ {"site" => {
169
+ "time" => Time.now,
170
+ "posts" => self.posts.sort { |a,b| b <=> a },
171
+ "categories" => post_attr_hash('categories'),
172
+ "topics" => post_attr_hash('topics')
173
+ }}
174
+ end
175
+
176
+ # Filter out any files/directories that are hidden or backup files (start
177
+ # with "." or "#" or end with "~") or contain site content (start with "_")
178
+ # unless they are "_posts" directories or web server files such as
179
+ # '.htaccess'
180
+ def filter_entries(entries)
181
+ entries = entries.reject do |e|
182
+ unless ['_posts', '.htaccess'].include?(e)
183
+ # Reject backup/hidden
184
+ ['.', '_', '#'].include?(e[0..0]) or e[-1..-1] == '~'
185
+ end
186
+ end
187
+ end
188
+
189
+ end
190
+ end
@@ -0,0 +1,53 @@
1
+ module Jekyll
2
+
3
+ class HighlightBlock < Liquid::Block
4
+ include Liquid::StandardFilters
5
+ # we need a language, but the linenos argument is optional.
6
+ SYNTAX = /(\w+)\s?(:?linenos)?\s?/
7
+
8
+ def initialize(tag_name, markup, tokens)
9
+ super
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
21
+ end
22
+
23
+ def render(context)
24
+ if Jekyll.pygments
25
+ render_pygments(context, super.to_s)
26
+ else
27
+ render_codehighlighter(context, super.to_s)
28
+ end
29
+ end
30
+
31
+ def render_pygments(context, code)
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
37
+ end
38
+
39
+ def render_codehighlighter(context, code)
40
+ #The div is required because RDiscount blows ass
41
+ <<-HTML
42
+ <div>
43
+ <pre>
44
+ <code class='#{@lang}'>#{h(code).strip}</code>
45
+ </pre>
46
+ </div>
47
+ HTML
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+ 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(Jekyll.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,69 @@
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
+ begin
17
+ require 'maruku'
18
+ require 'maruku/ext/math'
19
+ # Switch off MathML output
20
+ MaRuKu::Globals[:html_math_output_mathml] = false
21
+ MaRuKu::Globals[:html_math_engine] = 'none'
22
+
23
+ # Turn on math to PNG support with blahtex
24
+ # Resulting PNGs stored in `images/latex`
25
+ MaRuKu::Globals[:html_math_output_png] = true
26
+ MaRuKu::Globals[:html_png_engine] = 'blahtex'
27
+ MaRuKu::Globals[:html_png_dir] = 'images/latex'
28
+ MaRuKu::Globals[:html_png_url] = '/images/latex/'
29
+ rescue LoadError
30
+ puts "The maruku gem is required for markdown support!"
31
+ end
32
+
33
+ # internal requires
34
+ require 'jekyll/core_ext'
35
+ require 'jekyll/site'
36
+ require 'jekyll/convertible'
37
+ require 'jekyll/layout'
38
+ require 'jekyll/page'
39
+ require 'jekyll/post'
40
+ require 'jekyll/filters'
41
+ require 'jekyll/custom_filters'
42
+ require 'jekyll/tags/highlight'
43
+ require 'jekyll/tags/include'
44
+ require 'jekyll/albino'
45
+
46
+ module Jekyll
47
+ class << self
48
+ attr_accessor :source, :dest, :lsi, :pygments, :markdown_proc, :content_type, :permalink_style, :custom_filters
49
+ end
50
+
51
+ Jekyll.lsi = false
52
+ Jekyll.pygments = false
53
+ Jekyll.markdown_proc = Proc.new { |x| Maruku.new(x).to_html }
54
+ Jekyll.permalink_style = :date
55
+ Jekyll.custom_filters = true
56
+
57
+ def self.process(source, dest)
58
+ require 'classifier' if Jekyll.lsi
59
+
60
+ Jekyll.source = source
61
+ Jekyll.dest = dest
62
+ Jekyll::Site.new(source, dest).process
63
+ end
64
+
65
+ def self.version
66
+ yml = YAML.load(File.read(File.join(File.dirname(__FILE__), *%w[.. VERSION.yml])))
67
+ "#{yml[:major]}.#{yml[:minor]}.#{yml[:patch]}"
68
+ end
69
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,14 @@
1
+ require File.join(File.dirname(__FILE__), *%w[.. lib jekyll])
2
+
3
+ require 'test/unit'
4
+ require 'redgreen'
5
+
6
+ include Jekyll
7
+
8
+ def dest_dir
9
+ File.join(File.dirname(__FILE__), *%w[dest])
10
+ end
11
+
12
+ def clear_dest
13
+ FileUtils.rm_rf(dest_dir)
14
+ end
@@ -0,0 +1,3 @@
1
+ --
2
+ Tom Preston-Werner
3
+ github.com/mojombo