mojombo-jekyll 0.2.0 → 0.3.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 +21 -0
- data/Manifest.txt +7 -3
- data/README.textile +88 -5
- data/Rakefile +4 -1
- data/bin/jekyll +39 -1
- data/jekyll.gemspec +7 -7
- data/lib/jekyll.rb +18 -5
- data/lib/jekyll/converters/mt.rb +59 -0
- data/lib/jekyll/converters/wordpress.rb +54 -0
- data/lib/jekyll/convertible.rb +6 -8
- data/lib/jekyll/core_ext.rb +22 -0
- data/lib/jekyll/filters.rb +6 -3
- data/lib/jekyll/layout.rb +0 -15
- data/lib/jekyll/page.rb +3 -3
- data/lib/jekyll/post.rb +36 -19
- data/lib/jekyll/site.rb +52 -20
- data/lib/jekyll/tags/include.rb +12 -1
- data/test/source/_includes/{sig.textile → sig.markdown} +0 -0
- data/test/source/{posts → _posts}/2008-12-03-permalinked-post.textile +0 -0
- data/test/source/_posts/2008-12-13-include.markdown +8 -0
- data/test/source/index.html +11 -1
- data/test/test_generated_site.rb +21 -0
- data/test/test_post.rb +16 -12
- data/test/test_site.rb +4 -4
- metadata +11 -6
- data/test/source/_posts/2008-12-13-include.textile +0 -6
data/History.txt
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
== 0.3.0 / 2008-12-24
|
|
2
|
+
* Major Enhancements
|
|
3
|
+
* Added --server option to start a simple WEBrick server on destination directory [github.com/johnreilly and github.com/mchung]
|
|
4
|
+
* Minor Enhancements
|
|
5
|
+
* Added post categories based on directories containing _posts [github.com/mreid]
|
|
6
|
+
* Added post topics based on directories underneath _posts
|
|
7
|
+
* Added new date filter that shows the full month name [github.com/mreid]
|
|
8
|
+
* Merge Post's YAML front matter into its to_liquid payload [github.com/remi]
|
|
9
|
+
* Restrict includes to regular files underneath _includes
|
|
10
|
+
* Bug Fixes
|
|
11
|
+
* Change YAML delimiter matcher so as to not chew up 2nd level markdown headers [github.com/mreid]
|
|
12
|
+
* Fix bug that meant page data (such as the date) was not available in templates [github.com/mreid]
|
|
13
|
+
* Properly reject directories in _layouts
|
|
14
|
+
|
|
15
|
+
== 0.2.1 / 2008-12-15
|
|
16
|
+
* Major Changes
|
|
17
|
+
* Use Maruku (pure Ruby) for Markdown by default [github.com/mreid]
|
|
18
|
+
* Allow use of RDiscount with --rdiscount flag
|
|
19
|
+
* Minor Enhancements
|
|
20
|
+
* Don't load directory_watcher unless it's needed [github.com/pjhyett]
|
|
21
|
+
|
|
1
22
|
== 0.2.0 / 2008-12-14
|
|
2
23
|
* Major Changes
|
|
3
24
|
* related_posts is now found in site.related_posts
|
data/Manifest.txt
CHANGED
|
@@ -8,7 +8,10 @@ lib/jekyll.rb
|
|
|
8
8
|
lib/jekyll/albino.rb
|
|
9
9
|
lib/jekyll/converters/csv.rb
|
|
10
10
|
lib/jekyll/converters/mephisto.rb
|
|
11
|
+
lib/jekyll/converters/mt.rb
|
|
12
|
+
lib/jekyll/converters/wordpress.rb
|
|
11
13
|
lib/jekyll/convertible.rb
|
|
14
|
+
lib/jekyll/core_ext.rb
|
|
12
15
|
lib/jekyll/filters.rb
|
|
13
16
|
lib/jekyll/layout.rb
|
|
14
17
|
lib/jekyll/page.rb
|
|
@@ -17,16 +20,17 @@ lib/jekyll/site.rb
|
|
|
17
20
|
lib/jekyll/tags/highlight.rb
|
|
18
21
|
lib/jekyll/tags/include.rb
|
|
19
22
|
test/helper.rb
|
|
20
|
-
test/source/_includes/sig.
|
|
23
|
+
test/source/_includes/sig.markdown
|
|
21
24
|
test/source/_layouts/default.html
|
|
22
25
|
test/source/_layouts/simple.html
|
|
23
26
|
test/source/_posts/2008-10-18-foo-bar.textile
|
|
24
27
|
test/source/_posts/2008-11-21-complex.textile
|
|
25
|
-
test/source/_posts/2008-12-
|
|
28
|
+
test/source/_posts/2008-12-03-permalinked-post.textile
|
|
29
|
+
test/source/_posts/2008-12-13-include.markdown
|
|
26
30
|
test/source/css/screen.css
|
|
27
31
|
test/source/index.html
|
|
28
|
-
test/source/posts/2008-12-03-permalinked-post.textile
|
|
29
32
|
test/suite.rb
|
|
33
|
+
test/test_generated_site.rb
|
|
30
34
|
test/test_jekyll.rb
|
|
31
35
|
test/test_post.rb
|
|
32
36
|
test/test_site.rb
|
data/README.textile
CHANGED
|
@@ -31,9 +31,10 @@ various data about my site. A reverse chronological list of all my blog posts
|
|
|
31
31
|
can be found in <code>site.posts</code>. Each post, in turn, contains various
|
|
32
32
|
fields such as <code>title</code> and <code>date</code>.
|
|
33
33
|
|
|
34
|
-
Jekyll gets the list of blog posts by parsing the files in
|
|
35
|
-
"_posts":http://github.com/mojombo/tpw/tree/master/_posts directory
|
|
36
|
-
|
|
34
|
+
Jekyll gets the list of blog posts by parsing the files in any
|
|
35
|
+
"_posts":http://github.com/mojombo/tpw/tree/master/_posts directory found in
|
|
36
|
+
subdirectories below the root.
|
|
37
|
+
Each post's filename contains the publishing date and slug (what shows up in the
|
|
37
38
|
URL) that the final HTML file should have. Open up the file corresponding to a
|
|
38
39
|
blog post:
|
|
39
40
|
"2008-11-17-blogging-like-a-hacker.textile":http://github.com/mojombo/tpw/tree/master/_posts/2008-11-17-blogging-like-a-hacker.textile.
|
|
@@ -52,6 +53,12 @@ filename is used to construct the URL in the generated site. The example post,
|
|
|
52
53
|
for instance, ends up at
|
|
53
54
|
<code>http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html</code>.
|
|
54
55
|
|
|
56
|
+
Categories for posts are derived from the directory structure the posts were
|
|
57
|
+
found within. A post that appears in the directory foo/bar/_posts is placed in
|
|
58
|
+
the categories 'foo' and 'bar'. By selecting posts from particular categories
|
|
59
|
+
in your Liquid templates, you will be able to host multiple blogs within a
|
|
60
|
+
site.
|
|
61
|
+
|
|
55
62
|
Files that do not reside in directories prefixed with an underscore are
|
|
56
63
|
mirrored into a corresponding directory structure in the generated site. If a
|
|
57
64
|
file does not have a YAML preface, it is not run through the Liquid
|
|
@@ -79,6 +86,17 @@ The best way to install Jekyll is via RubyGems:
|
|
|
79
86
|
|
|
80
87
|
$ sudo gem install mojombo-jekyll -s http://gems.github.com/
|
|
81
88
|
|
|
89
|
+
Jekyll requires the gems `directory_watcher`, `liquid`, `open4`,
|
|
90
|
+
and `maruku` (for markdown support). These are automatically
|
|
91
|
+
installed by the gem install command.
|
|
92
|
+
|
|
93
|
+
Maruku comes with optional support for LaTeX to PNG rendering via
|
|
94
|
+
"blahtex":http://gva.noekeon.org/blahtexml/ (Version 0.6) which must be in
|
|
95
|
+
your $PATH along with `dvips`.
|
|
96
|
+
|
|
97
|
+
(NOTE: the version of maruku I am using is `remi-maruku` on GitHub as it
|
|
98
|
+
does not assume a fixed location for `dvips`.)
|
|
99
|
+
|
|
82
100
|
h2. Run
|
|
83
101
|
|
|
84
102
|
$ cd /path/to/proto/site
|
|
@@ -112,6 +130,21 @@ during the conversion:
|
|
|
112
130
|
|
|
113
131
|
$ jekyll --pygments
|
|
114
132
|
|
|
133
|
+
By default, Jekyll uses "Maruku":http://maruku.rubyforge.org (pure Ruby) for
|
|
134
|
+
Markdown support. If you'd like to use RDiscount (faster, but requires
|
|
135
|
+
compilation), you must install it (gem install rdiscount) and then you can
|
|
136
|
+
have it used instead:
|
|
137
|
+
|
|
138
|
+
$ jekyll --rdiscount
|
|
139
|
+
|
|
140
|
+
When previewing complex sites locally, simply opening the site in a web
|
|
141
|
+
browser (using file://) can cause problems with links that are relative to
|
|
142
|
+
the site root (e.g., "/stylesheets/style.css"). To get around this, Jekyll
|
|
143
|
+
can launch a simple WEBrick server (works well in conjunction with --auto).
|
|
144
|
+
Default port is 4000:
|
|
145
|
+
|
|
146
|
+
$ jekyll --server [PORT]
|
|
147
|
+
|
|
115
148
|
h2. Data
|
|
116
149
|
|
|
117
150
|
Jekyll traverses your site looking for files to process. Any files with YAML
|
|
@@ -131,7 +164,7 @@ h3. Global
|
|
|
131
164
|
|
|
132
165
|
content
|
|
133
166
|
In layout files, this contains the content of the subview(s). In Posts or
|
|
134
|
-
|
|
167
|
+
Pages, this is undefined.
|
|
135
168
|
|
|
136
169
|
h3. Site
|
|
137
170
|
|
|
@@ -147,6 +180,9 @@ h3. Site
|
|
|
147
180
|
high quality but slow to compute results, run the jekyll command with the
|
|
148
181
|
--lsi (latent semantic indexing) option.
|
|
149
182
|
|
|
183
|
+
site.categories.CATEGORY
|
|
184
|
+
The list of all Posts in category CATEGORY.
|
|
185
|
+
|
|
150
186
|
h3. Post
|
|
151
187
|
|
|
152
188
|
post.title
|
|
@@ -163,6 +199,18 @@ h3. Post
|
|
|
163
199
|
An identifier unique to the Post (useful in RSS feeds).
|
|
164
200
|
e.g. /2008/12/14/my-post
|
|
165
201
|
|
|
202
|
+
post.categories
|
|
203
|
+
The list of categories to which this post belongs. Categories are
|
|
204
|
+
derived from the directory structure above the _posts directory. For
|
|
205
|
+
example, a post at /work/code/_posts/2008-12-24-closures.textile
|
|
206
|
+
would have this field set to ['work', 'code'].
|
|
207
|
+
|
|
208
|
+
post.topics
|
|
209
|
+
The list of topics for this Post. Topics are derived from the directory
|
|
210
|
+
structure beneath the _posts directory. For example, a post at
|
|
211
|
+
/_posts/music/metal/2008-12-24-metalocalypse.textile would have this field
|
|
212
|
+
set to ['music', 'metal'].
|
|
213
|
+
|
|
166
214
|
post.content
|
|
167
215
|
The content of the Post.
|
|
168
216
|
|
|
@@ -240,7 +288,8 @@ becomes
|
|
|
240
288
|
|
|
241
289
|
h3. Include (Tag)
|
|
242
290
|
|
|
243
|
-
If you have small page fragments that you wish to include in multiple places
|
|
291
|
+
If you have small page fragments that you wish to include in multiple places
|
|
292
|
+
on your site, you can use the <code>include</code> tag.
|
|
244
293
|
|
|
245
294
|
<pre>{% include sig.textile %}</pre>
|
|
246
295
|
|
|
@@ -278,6 +327,22 @@ highlighting stylesheet. For an example stylesheet you can look at
|
|
|
278
327
|
are the same styles as used by GitHub and you are free to use them for your
|
|
279
328
|
own site.
|
|
280
329
|
|
|
330
|
+
h2. Categories
|
|
331
|
+
|
|
332
|
+
Posts are placed into categories based on the directory structure they are found
|
|
333
|
+
within (see above for an example). The categories can be accessed from within
|
|
334
|
+
a Liquid template as follows:
|
|
335
|
+
|
|
336
|
+
<pre>
|
|
337
|
+
{% for post in site.categories.foo %}
|
|
338
|
+
<li><span>{{ post.date | date_to_string }}</span> - {{ post.title }}</li>
|
|
339
|
+
{% endfor %}
|
|
340
|
+
</pre>
|
|
341
|
+
|
|
342
|
+
This would list all the posts in the category 'foo' by date and title.
|
|
343
|
+
|
|
344
|
+
The posts within each category are sorted in reverse chronological order.
|
|
345
|
+
|
|
281
346
|
h2. Contribute
|
|
282
347
|
|
|
283
348
|
If you'd like to hack on Jekyll, grab the source from GitHub. To get
|
|
@@ -296,6 +361,24 @@ The best way to get your changes merged back into core is as follows:
|
|
|
296
361
|
# Push the branch up to GitHub
|
|
297
362
|
# Send me (mojombo) a pull request for your branch
|
|
298
363
|
|
|
364
|
+
h2. Blog migrations
|
|
365
|
+
|
|
366
|
+
h3. Movable Type
|
|
367
|
+
|
|
368
|
+
To migrate your MT blog into Jekyll, you'll need read access to the database.
|
|
369
|
+
The lib/jekyll/converters/mt.rb module provides a simple convert to create
|
|
370
|
+
.markdown files in a _posts directory based on the entries contained therein.
|
|
371
|
+
|
|
372
|
+
$ export DB=my_mtdb
|
|
373
|
+
$ export USER=dbuser
|
|
374
|
+
$ export PASS=dbpass
|
|
375
|
+
$ ruby -r './lib/jekyll/converters/mt' -e 'Jekyll::MT.process( \
|
|
376
|
+
"#{ENV["DB"]}", "#{ENV["USER"]}", "#{ENV["PASS"]}")'
|
|
377
|
+
|
|
378
|
+
You may need to adjust the SQL query used to retrieve MT entries. Left alone,
|
|
379
|
+
it will attempt to pull all entries across all blogs regardless of status.
|
|
380
|
+
Please check the results and verify the posts before publishing.
|
|
381
|
+
|
|
299
382
|
h2. License
|
|
300
383
|
|
|
301
384
|
(The MIT License)
|
data/Rakefile
CHANGED
|
@@ -5,7 +5,7 @@ require 'lib/jekyll'
|
|
|
5
5
|
Hoe.new('jekyll', Jekyll::VERSION) do |p|
|
|
6
6
|
p.developer('Tom Preston-Werner', 'tom@mojombo.com')
|
|
7
7
|
p.summary = "Jekyll is a simple, blog aware, static site generator."
|
|
8
|
-
p.extra_deps = ['RedCloth', 'liquid', 'classifier', '
|
|
8
|
+
p.extra_deps = ['RedCloth', 'liquid', 'classifier', 'maruku', 'directory_watcher', 'open4']
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
desc "Open an irb session preloaded with this library"
|
|
@@ -18,4 +18,7 @@ namespace :convert do
|
|
|
18
18
|
task :mephisto do
|
|
19
19
|
sh %q(ruby -r './lib/jekyll/converters/mephisto' -e 'Jekyll::Mephisto.postgres(:database => "#{ENV["DB"]}")')
|
|
20
20
|
end
|
|
21
|
+
task :mt do
|
|
22
|
+
sh %q(ruby -r './lib/jekyll/converters/mt' -e 'Jekyll::MT.process("#{ENV["DB"]}", "#{ENV["USER"]}", "#{ENV["PASS"]}")')
|
|
23
|
+
end
|
|
21
24
|
end
|
data/bin/jekyll
CHANGED
|
@@ -25,6 +25,11 @@ opts = OptionParser.new do |opts|
|
|
|
25
25
|
options[:auto] = true
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
opts.on("--server [PORT]", "Start web server (default port 4000)") do |port|
|
|
29
|
+
options[:server] = true
|
|
30
|
+
options[:server_port] = port || 4000
|
|
31
|
+
end
|
|
32
|
+
|
|
28
33
|
opts.on("--lsi", "Use LSI for better related posts") do
|
|
29
34
|
Jekyll.lsi = true
|
|
30
35
|
end
|
|
@@ -32,6 +37,16 @@ opts = OptionParser.new do |opts|
|
|
|
32
37
|
opts.on("--pygments", "Use pygments to highlight code") do
|
|
33
38
|
Jekyll.pygments = true
|
|
34
39
|
end
|
|
40
|
+
|
|
41
|
+
opts.on("--rdiscount", "Use rdiscount gem for Markdown") do
|
|
42
|
+
begin
|
|
43
|
+
require 'rdiscount'
|
|
44
|
+
Jekyll.markdown_proc = Proc.new { |x| RDiscount.new(x).to_html }
|
|
45
|
+
puts 'Using rdiscount for Markdown'
|
|
46
|
+
rescue LoadError
|
|
47
|
+
puts 'You must have the rdiscount gem installed first'
|
|
48
|
+
end
|
|
49
|
+
end
|
|
35
50
|
end
|
|
36
51
|
|
|
37
52
|
opts.parse!
|
|
@@ -69,6 +84,8 @@ case ARGV.size
|
|
|
69
84
|
end
|
|
70
85
|
|
|
71
86
|
if options[:auto]
|
|
87
|
+
require 'directory_watcher'
|
|
88
|
+
|
|
72
89
|
puts "Auto-regenerating enabled: #{source} -> #{destination}"
|
|
73
90
|
|
|
74
91
|
dw = DirectoryWatcher.new(source)
|
|
@@ -83,7 +100,28 @@ if options[:auto]
|
|
|
83
100
|
|
|
84
101
|
dw.start
|
|
85
102
|
|
|
86
|
-
|
|
103
|
+
unless options[:server]
|
|
104
|
+
loop { sleep 1000 }
|
|
105
|
+
end
|
|
87
106
|
else
|
|
88
107
|
Jekyll.process(source, destination)
|
|
108
|
+
puts "Successfully generated site in #{destination}"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
if options[:server]
|
|
112
|
+
require 'webrick'
|
|
113
|
+
include WEBrick
|
|
114
|
+
|
|
115
|
+
FileUtils.mkdir_p(destination)
|
|
116
|
+
|
|
117
|
+
s = HTTPServer.new(
|
|
118
|
+
:Port => options[:server_port],
|
|
119
|
+
:DocumentRoot => destination
|
|
120
|
+
)
|
|
121
|
+
t = Thread.new {
|
|
122
|
+
s.start
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
trap("INT") { s.shutdown }
|
|
126
|
+
t.join()
|
|
89
127
|
end
|
data/jekyll.gemspec
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = %q{jekyll}
|
|
3
|
-
s.version = "0.
|
|
3
|
+
s.version = "0.3.0"
|
|
4
4
|
|
|
5
5
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
6
6
|
s.authors = ["Tom Preston-Werner"]
|
|
7
|
-
s.date = %q{2008-12-
|
|
7
|
+
s.date = %q{2008-12-24}
|
|
8
8
|
s.default_executable = %q{jekyll}
|
|
9
9
|
s.email = ["tom@mojombo.com"]
|
|
10
10
|
s.executables = ["jekyll"]
|
|
11
11
|
s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
|
|
12
|
-
s.files = ["History.txt", "Manifest.txt", "README.textile", "Rakefile", "bin/jekyll", "jekyll.gemspec", "lib/jekyll.rb", "lib/jekyll/albino.rb", "lib/jekyll/converters/csv.rb", "lib/jekyll/converters/mephisto.rb", "lib/jekyll/convertible.rb", "lib/jekyll/filters.rb", "lib/jekyll/layout.rb", "lib/jekyll/page.rb", "lib/jekyll/post.rb", "lib/jekyll/site.rb", "lib/jekyll/tags/highlight.rb", "lib/jekyll/tags/include.rb", "test/helper.rb", "test/source/_includes/sig.
|
|
12
|
+
s.files = ["History.txt", "Manifest.txt", "README.textile", "Rakefile", "bin/jekyll", "jekyll.gemspec", "lib/jekyll.rb", "lib/jekyll/albino.rb", "lib/jekyll/converters/csv.rb", "lib/jekyll/converters/mephisto.rb", "lib/jekyll/converters/mt.rb", "lib/jekyll/converters/wordpress.rb", "lib/jekyll/convertible.rb", "lib/jekyll/core_ext.rb", "lib/jekyll/filters.rb", "lib/jekyll/layout.rb", "lib/jekyll/page.rb", "lib/jekyll/post.rb", "lib/jekyll/site.rb", "lib/jekyll/tags/highlight.rb", "lib/jekyll/tags/include.rb", "test/helper.rb", "test/source/_includes/sig.markdown", "test/source/_layouts/default.html", "test/source/_layouts/simple.html", "test/source/_posts/2008-10-18-foo-bar.textile", "test/source/_posts/2008-11-21-complex.textile", "test/source/_posts/2008-12-03-permalinked-post.textile", "test/source/_posts/2008-12-13-include.markdown", "test/source/css/screen.css", "test/source/index.html", "test/suite.rb", "test/test_generated_site.rb", "test/test_jekyll.rb", "test/test_post.rb", "test/test_site.rb"]
|
|
13
13
|
s.has_rdoc = true
|
|
14
14
|
s.rdoc_options = ["--main", "README.txt"]
|
|
15
15
|
s.require_paths = ["lib"]
|
|
16
16
|
s.rubyforge_project = %q{jekyll}
|
|
17
17
|
s.rubygems_version = %q{1.3.0}
|
|
18
18
|
s.summary = %q{Jekyll is a simple, blog aware, static site generator.}
|
|
19
|
-
s.test_files = ["test/test_jekyll.rb", "test/test_post.rb", "test/test_site.rb"]
|
|
19
|
+
s.test_files = ["test/test_generated_site.rb", "test/test_jekyll.rb", "test/test_post.rb", "test/test_site.rb"]
|
|
20
20
|
|
|
21
21
|
if s.respond_to? :specification_version then
|
|
22
22
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
|
|
|
26
26
|
s.add_runtime_dependency(%q<RedCloth>, [">= 0"])
|
|
27
27
|
s.add_runtime_dependency(%q<liquid>, [">= 0"])
|
|
28
28
|
s.add_runtime_dependency(%q<classifier>, [">= 0"])
|
|
29
|
-
s.add_runtime_dependency(%q<
|
|
29
|
+
s.add_runtime_dependency(%q<maruku>, [">= 0"])
|
|
30
30
|
s.add_runtime_dependency(%q<directory_watcher>, [">= 0"])
|
|
31
31
|
s.add_runtime_dependency(%q<open4>, [">= 0"])
|
|
32
32
|
s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
|
|
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
|
|
|
34
34
|
s.add_dependency(%q<RedCloth>, [">= 0"])
|
|
35
35
|
s.add_dependency(%q<liquid>, [">= 0"])
|
|
36
36
|
s.add_dependency(%q<classifier>, [">= 0"])
|
|
37
|
-
s.add_dependency(%q<
|
|
37
|
+
s.add_dependency(%q<maruku>, [">= 0"])
|
|
38
38
|
s.add_dependency(%q<directory_watcher>, [">= 0"])
|
|
39
39
|
s.add_dependency(%q<open4>, [">= 0"])
|
|
40
40
|
s.add_dependency(%q<hoe>, [">= 1.8.0"])
|
|
@@ -43,7 +43,7 @@ Gem::Specification.new do |s|
|
|
|
43
43
|
s.add_dependency(%q<RedCloth>, [">= 0"])
|
|
44
44
|
s.add_dependency(%q<liquid>, [">= 0"])
|
|
45
45
|
s.add_dependency(%q<classifier>, [">= 0"])
|
|
46
|
-
s.add_dependency(%q<
|
|
46
|
+
s.add_dependency(%q<maruku>, [">= 0"])
|
|
47
47
|
s.add_dependency(%q<directory_watcher>, [">= 0"])
|
|
48
48
|
s.add_dependency(%q<open4>, [">= 0"])
|
|
49
49
|
s.add_dependency(%q<hoe>, [">= 1.8.0"])
|
data/lib/jekyll.rb
CHANGED
|
@@ -6,6 +6,7 @@ require 'rubygems'
|
|
|
6
6
|
# core
|
|
7
7
|
require 'fileutils'
|
|
8
8
|
require 'time'
|
|
9
|
+
require 'yaml'
|
|
9
10
|
|
|
10
11
|
# stdlib
|
|
11
12
|
|
|
@@ -13,13 +14,24 @@ require 'time'
|
|
|
13
14
|
require 'liquid'
|
|
14
15
|
require 'redcloth'
|
|
15
16
|
begin
|
|
16
|
-
require '
|
|
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/'
|
|
17
29
|
rescue LoadError
|
|
18
|
-
puts "The
|
|
30
|
+
puts "The maruku gem is required for markdown support!"
|
|
19
31
|
end
|
|
20
|
-
require 'directory_watcher'
|
|
21
32
|
|
|
22
33
|
# internal requires
|
|
34
|
+
require 'jekyll/core_ext'
|
|
23
35
|
require 'jekyll/site'
|
|
24
36
|
require 'jekyll/convertible'
|
|
25
37
|
require 'jekyll/layout'
|
|
@@ -31,14 +43,15 @@ require 'jekyll/tags/include'
|
|
|
31
43
|
require 'jekyll/albino'
|
|
32
44
|
|
|
33
45
|
module Jekyll
|
|
34
|
-
VERSION = '0.
|
|
46
|
+
VERSION = '0.3.0'
|
|
35
47
|
|
|
36
48
|
class << self
|
|
37
|
-
attr_accessor :source, :dest, :lsi, :pygments
|
|
49
|
+
attr_accessor :source, :dest, :lsi, :pygments, :markdown_proc
|
|
38
50
|
end
|
|
39
51
|
|
|
40
52
|
Jekyll.lsi = false
|
|
41
53
|
Jekyll.pygments = false
|
|
54
|
+
Jekyll.markdown_proc = Proc.new { |x| Maruku.new(x).to_html }
|
|
42
55
|
|
|
43
56
|
def self.process(source, dest)
|
|
44
57
|
require 'classifier' if Jekyll.lsi
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Created by Nick Gerakines, open source and publically available under the
|
|
2
|
+
# MIT license. Use this module at your own risk.
|
|
3
|
+
# I'm an Erlang/Perl/C++ guy so please forgive my dirty ruby.
|
|
4
|
+
|
|
5
|
+
require 'rubygems'
|
|
6
|
+
require 'sequel'
|
|
7
|
+
require 'fileutils'
|
|
8
|
+
|
|
9
|
+
# NOTE: This converter requires Sequel and the MySQL gems.
|
|
10
|
+
# The MySQL gem can be difficult to install on OS X. Once you have MySQL
|
|
11
|
+
# installed, running the following commands should work:
|
|
12
|
+
# $ sudo gem install sequel
|
|
13
|
+
# $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
|
|
14
|
+
|
|
15
|
+
module Jekyll
|
|
16
|
+
module MT
|
|
17
|
+
# This query will pull blog posts from all entries across all blogs. If
|
|
18
|
+
# you've got unpublished, deleted or otherwise hidden posts please sift
|
|
19
|
+
# through the created posts to make sure nothing is accidently published.
|
|
20
|
+
QUERY = "SELECT entry_id, entry_basename, entry_text, entry_text_more, entry_created_on, entry_title FROM mt_entry"
|
|
21
|
+
|
|
22
|
+
def self.process(dbname, user, pass, host = 'localhost')
|
|
23
|
+
db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host)
|
|
24
|
+
|
|
25
|
+
FileUtils.mkdir_p "_posts"
|
|
26
|
+
|
|
27
|
+
db[QUERY].each do |post|
|
|
28
|
+
title = post[:entry_title]
|
|
29
|
+
slug = post[:entry_basename]
|
|
30
|
+
date = post[:entry_created_on]
|
|
31
|
+
content = post[:entry_text]
|
|
32
|
+
more_content = post[:entry_text_more]
|
|
33
|
+
|
|
34
|
+
# Be sure to include the body and extended body.
|
|
35
|
+
if more_content != nil
|
|
36
|
+
conent = content + " \n" + more_content
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Ideally, this script would determine the post format (markdown, html
|
|
40
|
+
# , etc) and create files with proper extensions. At this point it
|
|
41
|
+
# just assumes that markdown will be acceptable.
|
|
42
|
+
name = [date.year, date.month, date.day, slug].join('-') + ".markdown"
|
|
43
|
+
|
|
44
|
+
data = {
|
|
45
|
+
'layout' => 'post',
|
|
46
|
+
'title' => title.to_s,
|
|
47
|
+
'mt_id' => post[:entry_id],
|
|
48
|
+
}.delete_if { |k,v| v.nil? || v == ''}.to_yaml
|
|
49
|
+
|
|
50
|
+
File.open("_posts/#{name}", "w") do |f|
|
|
51
|
+
f.puts data
|
|
52
|
+
f.puts "---"
|
|
53
|
+
f.puts content
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'sequel'
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
|
|
5
|
+
# NOTE: This converter requires Sequel and the MySQL gems.
|
|
6
|
+
# The MySQL gem can be difficult to install on OS X. Once you have MySQL
|
|
7
|
+
# installed, running the following commands should work:
|
|
8
|
+
# $ sudo gem install sequel
|
|
9
|
+
# $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
|
|
10
|
+
|
|
11
|
+
module Jekyll
|
|
12
|
+
module WordPress
|
|
13
|
+
|
|
14
|
+
# Reads a MySQL database via Sequel and creates a post file for each
|
|
15
|
+
# post in wp_posts that has post_status = 'publish'.
|
|
16
|
+
# This restriction is made because 'draft' posts are not guaranteed to
|
|
17
|
+
# have valid dates.
|
|
18
|
+
QUERY = "select * from wp_posts where post_status = 'publish' and post_type = 'post'"
|
|
19
|
+
|
|
20
|
+
def self.process(dbname, user, pass, host = 'localhost')
|
|
21
|
+
db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host)
|
|
22
|
+
|
|
23
|
+
FileUtils.mkdir_p "_posts"
|
|
24
|
+
|
|
25
|
+
db[QUERY].each do |post|
|
|
26
|
+
# Get required fields and construct Jekyll compatible name
|
|
27
|
+
title = post[:post_title]
|
|
28
|
+
slug = post[:post_name]
|
|
29
|
+
date = post[:post_date]
|
|
30
|
+
content = post[:post_content]
|
|
31
|
+
|
|
32
|
+
name = [date.year, date.month, date.day, slug].join('-') + ".markdown"
|
|
33
|
+
|
|
34
|
+
# Get the relevant fields as a hash, delete empty fields and convert
|
|
35
|
+
# to YAML for the header
|
|
36
|
+
data = {
|
|
37
|
+
'layout' => 'post',
|
|
38
|
+
'title' => title.to_s,
|
|
39
|
+
'excerpt' => post[:post_excerpt].to_s,
|
|
40
|
+
'wordpress_id' => post[:ID],
|
|
41
|
+
'wordpress_url' => post[:guid]
|
|
42
|
+
}.delete_if { |k,v| v.nil? || v == ''}.to_yaml
|
|
43
|
+
|
|
44
|
+
# Write out the data and content to file
|
|
45
|
+
File.open("_posts/#{name}", "w") do |f|
|
|
46
|
+
f.puts data
|
|
47
|
+
f.puts "---"
|
|
48
|
+
f.puts content
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
data/lib/jekyll/convertible.rb
CHANGED
|
@@ -13,13 +13,13 @@ module Jekyll
|
|
|
13
13
|
def read_yaml(base, name)
|
|
14
14
|
self.content = File.read(File.join(base, name))
|
|
15
15
|
|
|
16
|
-
if self.content =~ /^(
|
|
16
|
+
if self.content =~ /^(---\s*\n.*?)\n---\s*\n/m
|
|
17
17
|
self.content = self.content[($1.size + 5)..-1]
|
|
18
18
|
|
|
19
19
|
self.data = YAML.load($1)
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
# Transform the contents based on the file extension.
|
|
24
24
|
#
|
|
25
25
|
# Returns nothing
|
|
@@ -30,7 +30,7 @@ module Jekyll
|
|
|
30
30
|
self.content = RedCloth.new(self.content).to_html
|
|
31
31
|
when ".markdown":
|
|
32
32
|
self.ext = ".html"
|
|
33
|
-
self.content =
|
|
33
|
+
self.content = Jekyll.markdown_proc.call(self.content)
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
@@ -39,10 +39,8 @@ module Jekyll
|
|
|
39
39
|
# +site_payload+ is the site payload hash
|
|
40
40
|
#
|
|
41
41
|
# Returns nothing
|
|
42
|
-
def do_layout(payload, layouts
|
|
43
|
-
#
|
|
44
|
-
payload = payload.merge(site_payload)
|
|
45
|
-
# render content
|
|
42
|
+
def do_layout(payload, layouts)
|
|
43
|
+
# render and transform content (this becomes the final content of the object)
|
|
46
44
|
self.content = Liquid::Template.parse(self.content).render(payload, [Jekyll::Filters])
|
|
47
45
|
self.transform
|
|
48
46
|
|
|
@@ -52,7 +50,7 @@ module Jekyll
|
|
|
52
50
|
# recursively render layouts
|
|
53
51
|
layout = layouts[self.data["layout"]]
|
|
54
52
|
while layout
|
|
55
|
-
payload = payload.
|
|
53
|
+
payload = payload.deep_merge({"content" => self.output, "page" => layout.data})
|
|
56
54
|
self.output = Liquid::Template.parse(layout.content).render(payload, [Jekyll::Filters])
|
|
57
55
|
|
|
58
56
|
layout = layouts[layout.data["layout"]]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class Hash
|
|
2
|
+
# Merges self with another hash, recursively.
|
|
3
|
+
#
|
|
4
|
+
# This code was lovingly stolen from some random gem:
|
|
5
|
+
# http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
|
|
6
|
+
#
|
|
7
|
+
# Thanks to whoever made it.
|
|
8
|
+
def deep_merge(hash)
|
|
9
|
+
target = dup
|
|
10
|
+
|
|
11
|
+
hash.keys.each do |key|
|
|
12
|
+
if hash[key].is_a? Hash and self[key].is_a? Hash
|
|
13
|
+
target[key] = target[key].deep_merge(hash[key])
|
|
14
|
+
next
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
target[key] = hash[key]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
target
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/jekyll/filters.rb
CHANGED
|
@@ -4,6 +4,10 @@ module Jekyll
|
|
|
4
4
|
def date_to_string(date)
|
|
5
5
|
date.strftime("%d %b %Y")
|
|
6
6
|
end
|
|
7
|
+
|
|
8
|
+
def date_to_long_string(date)
|
|
9
|
+
date.strftime("%d %B %Y")
|
|
10
|
+
end
|
|
7
11
|
|
|
8
12
|
def date_to_xmlschema(date)
|
|
9
13
|
date.xmlschema
|
|
@@ -15,7 +19,6 @@ module Jekyll
|
|
|
15
19
|
|
|
16
20
|
def number_of_words(input)
|
|
17
21
|
input.split.length
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
22
|
+
end
|
|
23
|
+
end
|
|
21
24
|
end
|
data/lib/jekyll/layout.rb
CHANGED
|
@@ -28,21 +28,6 @@ module Jekyll
|
|
|
28
28
|
def process(name)
|
|
29
29
|
self.ext = File.extname(name)
|
|
30
30
|
end
|
|
31
|
-
|
|
32
|
-
# Add any necessary layouts to this post
|
|
33
|
-
# +layouts+ is a Hash of {"name" => "layout"}
|
|
34
|
-
# +site_payload+ is the site payload hash
|
|
35
|
-
#
|
|
36
|
-
# Returns nothing
|
|
37
|
-
def add_layout(layouts, site_payload)
|
|
38
|
-
payload = {"page" => self.data}.merge(site_payload)
|
|
39
|
-
self.content = Liquid::Template.parse(self.content).render(payload, [Jekyll::Filters])
|
|
40
|
-
|
|
41
|
-
layout = layouts[self.data["layout"]] || self.content
|
|
42
|
-
payload = {"content" => self.content, "page" => self.data}
|
|
43
|
-
|
|
44
|
-
self.content = Liquid::Template.parse(layout).render(payload, [Jekyll::Filters])
|
|
45
|
-
end
|
|
46
31
|
end
|
|
47
32
|
|
|
48
33
|
end
|
data/lib/jekyll/page.rb
CHANGED
|
@@ -37,9 +37,9 @@ module Jekyll
|
|
|
37
37
|
# +site_payload+ is the site payload hash
|
|
38
38
|
#
|
|
39
39
|
# Returns nothing
|
|
40
|
-
def
|
|
41
|
-
payload = {"page" => self.data}
|
|
42
|
-
do_layout(payload, layouts
|
|
40
|
+
def render(layouts, site_payload)
|
|
41
|
+
payload = {"page" => self.data}.deep_merge(site_payload)
|
|
42
|
+
do_layout(payload, layouts)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
# Write the generated page file to the destination directory.
|
data/lib/jekyll/post.rb
CHANGED
|
@@ -3,12 +3,12 @@ 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
|
-
MATCHER = /^(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
|
|
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
|
|
@@ -18,22 +18,26 @@ module Jekyll
|
|
|
18
18
|
name =~ MATCHER
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
attr_accessor :date, :slug, :ext
|
|
21
|
+
attr_accessor :date, :slug, :ext, :categories, :topics
|
|
22
22
|
attr_accessor :data, :content, :output
|
|
23
23
|
|
|
24
24
|
# Initialize this Post instance.
|
|
25
25
|
# +base+ is the String path to the dir containing the post file
|
|
26
26
|
# +name+ is the String filename of the post file
|
|
27
|
+
# +categories+ is an Array of Strings for the categories for this post
|
|
27
28
|
#
|
|
28
29
|
# Returns <Post>
|
|
29
|
-
def initialize(
|
|
30
|
-
@base =
|
|
30
|
+
def initialize(source, dir, name)
|
|
31
|
+
@base = File.join(source, dir, '_posts')
|
|
31
32
|
@name = name
|
|
32
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
|
+
|
|
33
39
|
self.process(name)
|
|
34
|
-
self.read_yaml(base, name)
|
|
35
|
-
#Removed to avoid munging of liquid tags, replaced in convertible.rb#48
|
|
36
|
-
#self.transform
|
|
40
|
+
self.read_yaml(@base, name)
|
|
37
41
|
end
|
|
38
42
|
|
|
39
43
|
# Spaceship is based on Post#date
|
|
@@ -48,7 +52,7 @@ module Jekyll
|
|
|
48
52
|
#
|
|
49
53
|
# Returns nothing
|
|
50
54
|
def process(name)
|
|
51
|
-
m, date, slug, ext = *name.match(MATCHER)
|
|
55
|
+
m, cats, date, slug, ext = *name.match(MATCHER)
|
|
52
56
|
self.date = Time.parse(date)
|
|
53
57
|
self.slug = slug
|
|
54
58
|
self.ext = ext
|
|
@@ -61,9 +65,12 @@ module Jekyll
|
|
|
61
65
|
#
|
|
62
66
|
# Returns <String>
|
|
63
67
|
def dir
|
|
64
|
-
permalink
|
|
65
|
-
permalink.to_s.split("/")[0..-2].join("/")
|
|
66
|
-
|
|
68
|
+
if permalink
|
|
69
|
+
permalink.to_s.split("/")[0..-2].join("/")
|
|
70
|
+
else
|
|
71
|
+
prefix = self.categories.empty? ? '' : '/' + self.categories.join('/')
|
|
72
|
+
prefix + date.strftime("/%Y/%m/%d/")
|
|
73
|
+
end
|
|
67
74
|
end
|
|
68
75
|
|
|
69
76
|
# The full path and filename of the post.
|
|
@@ -90,7 +97,7 @@ module Jekyll
|
|
|
90
97
|
def id
|
|
91
98
|
self.dir + self.slug
|
|
92
99
|
end
|
|
93
|
-
|
|
100
|
+
|
|
94
101
|
# Calculate related posts.
|
|
95
102
|
#
|
|
96
103
|
# Returns [<Post>]
|
|
@@ -118,11 +125,16 @@ module Jekyll
|
|
|
118
125
|
# +site_payload+ is the site payload hash
|
|
119
126
|
#
|
|
120
127
|
# Returns nothing
|
|
121
|
-
def
|
|
122
|
-
# construct
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
128
|
+
def render(layouts, site_payload)
|
|
129
|
+
# construct payload
|
|
130
|
+
payload =
|
|
131
|
+
{
|
|
132
|
+
"site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) },
|
|
133
|
+
"page" => self.to_liquid
|
|
134
|
+
}
|
|
135
|
+
payload = payload.deep_merge(site_payload)
|
|
136
|
+
|
|
137
|
+
do_layout(payload, layouts)
|
|
126
138
|
end
|
|
127
139
|
|
|
128
140
|
# Write the generated post file to the destination directory.
|
|
@@ -146,7 +158,12 @@ module Jekyll
|
|
|
146
158
|
"url" => self.url,
|
|
147
159
|
"date" => self.date,
|
|
148
160
|
"id" => self.id,
|
|
149
|
-
"
|
|
161
|
+
"topics" => self.topics,
|
|
162
|
+
"content" => self.content }.deep_merge(self.data)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def inspect
|
|
166
|
+
"<Post: #{self.id}>"
|
|
150
167
|
end
|
|
151
168
|
end
|
|
152
169
|
|
data/lib/jekyll/site.rb
CHANGED
|
@@ -24,19 +24,19 @@ module Jekyll
|
|
|
24
24
|
# Returns nothing
|
|
25
25
|
def process
|
|
26
26
|
self.read_layouts
|
|
27
|
-
self.read_posts
|
|
28
|
-
self.write_posts
|
|
29
27
|
self.transform_pages
|
|
28
|
+
self.write_posts
|
|
30
29
|
end
|
|
31
30
|
|
|
32
|
-
# Read all the files in <source>/_layouts
|
|
33
|
-
# later use.
|
|
31
|
+
# Read all the files in <source>/_layouts except backup files
|
|
32
|
+
# (end with "~") into memory for later use.
|
|
34
33
|
#
|
|
35
34
|
# Returns nothing
|
|
36
35
|
def read_layouts
|
|
37
36
|
base = File.join(self.source, "_layouts")
|
|
38
37
|
entries = Dir.entries(base)
|
|
39
|
-
entries = entries.reject { |e|
|
|
38
|
+
entries = entries.reject { |e| e[-1..-1] == '~' }
|
|
39
|
+
entries = entries.reject { |e| File.directory?(File.join(base, e)) }
|
|
40
40
|
|
|
41
41
|
entries.each do |f|
|
|
42
42
|
name = f.split(".")[0..-2].join(".")
|
|
@@ -46,17 +46,29 @@ module Jekyll
|
|
|
46
46
|
# ignore missing layout dir
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
# Read all the files in <
|
|
50
|
-
# object with each one.
|
|
49
|
+
# Read all the files in <base>/_posts except backup files (end with "~")
|
|
50
|
+
# and create a new Post object with each one.
|
|
51
51
|
#
|
|
52
52
|
# Returns nothing
|
|
53
|
-
def read_posts
|
|
54
|
-
base = File.join(self.source,
|
|
55
|
-
|
|
56
|
-
entries =
|
|
53
|
+
def read_posts(dir)
|
|
54
|
+
base = File.join(self.source, dir, '_posts')
|
|
55
|
+
|
|
56
|
+
entries = []
|
|
57
|
+
Dir.chdir(base) { entries = Dir['**/*'] }
|
|
58
|
+
entries = entries.reject { |e| e[-1..-1] == '~' }
|
|
59
|
+
entries = entries.reject { |e| File.directory?(File.join(base, e)) }
|
|
57
60
|
|
|
61
|
+
# first pass processes, but does not yet render post content
|
|
58
62
|
entries.each do |f|
|
|
59
|
-
|
|
63
|
+
if Post.valid?(f)
|
|
64
|
+
post = Post.new(self.source, dir, f)
|
|
65
|
+
self.posts << post
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# second pass renders each post now that full site payload is available
|
|
70
|
+
self.posts.each do |post|
|
|
71
|
+
post.render(self.layouts, site_payload)
|
|
60
72
|
end
|
|
61
73
|
|
|
62
74
|
self.posts.sort!
|
|
@@ -69,14 +81,14 @@ module Jekyll
|
|
|
69
81
|
# Returns nothing
|
|
70
82
|
def write_posts
|
|
71
83
|
self.posts.each do |post|
|
|
72
|
-
post.add_layout(self.layouts, site_payload)
|
|
73
84
|
post.write(self.dest)
|
|
74
85
|
end
|
|
75
86
|
end
|
|
76
87
|
|
|
77
88
|
# Copy all regular files from <source> to <dest>/ ignoring
|
|
78
|
-
# any files/directories that are hidden
|
|
79
|
-
# site content (start with "_")
|
|
89
|
+
# any files/directories that are hidden or backup files (start
|
|
90
|
+
# with "." or end with "~") or contain site content (start with "_")
|
|
91
|
+
# unless they are "_posts" directories
|
|
80
92
|
# The +dir+ String is a relative path used to call this method
|
|
81
93
|
# recursively as it descends through directories
|
|
82
94
|
#
|
|
@@ -84,7 +96,17 @@ module Jekyll
|
|
|
84
96
|
def transform_pages(dir = '')
|
|
85
97
|
base = File.join(self.source, dir)
|
|
86
98
|
entries = Dir.entries(base)
|
|
87
|
-
entries = entries.reject { |e| [
|
|
99
|
+
entries = entries.reject { |e| e[-1..-1] == '~' }
|
|
100
|
+
entries = entries.reject do |e|
|
|
101
|
+
(e != '_posts') and ['.', '_'].include?(e[0..0])
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# we need to make sure to process _posts *first* otherwise they
|
|
105
|
+
# might not be available yet to other templates as {{ site.posts }}
|
|
106
|
+
if entries.include?('_posts')
|
|
107
|
+
entries.delete('_posts')
|
|
108
|
+
read_posts(dir)
|
|
109
|
+
end
|
|
88
110
|
|
|
89
111
|
entries.each do |f|
|
|
90
112
|
if File.directory?(File.join(base, f))
|
|
@@ -93,13 +115,13 @@ module Jekyll
|
|
|
93
115
|
else
|
|
94
116
|
first3 = File.open(File.join(self.source, dir, f)) { |fd| fd.read(3) }
|
|
95
117
|
|
|
96
|
-
# if the file appears to have a YAML header then process it as a page
|
|
97
118
|
if first3 == "---"
|
|
119
|
+
# file appears to have a YAML header so process it as a page
|
|
98
120
|
page = Page.new(self.source, dir, f)
|
|
99
|
-
page.
|
|
121
|
+
page.render(self.layouts, site_payload)
|
|
100
122
|
page.write(self.dest)
|
|
101
|
-
# otherwise copy the file without transforming it
|
|
102
123
|
else
|
|
124
|
+
# otherwise copy the file without transforming it
|
|
103
125
|
FileUtils.mkdir_p(File.join(self.dest, dir))
|
|
104
126
|
FileUtils.cp(File.join(self.source, dir, f), File.join(self.dest, dir, f))
|
|
105
127
|
end
|
|
@@ -111,7 +133,17 @@ module Jekyll
|
|
|
111
133
|
#
|
|
112
134
|
# Returns {"site" => {"time" => <Time>, "posts" => [<Post>]}}
|
|
113
135
|
def site_payload
|
|
114
|
-
|
|
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
|
+
{"site" => {
|
|
143
|
+
"time" => Time.now,
|
|
144
|
+
"posts" => self.posts.sort { |a,b| b <=> a },
|
|
145
|
+
"categories" => categories
|
|
146
|
+
}}
|
|
115
147
|
end
|
|
116
148
|
end
|
|
117
149
|
|
data/lib/jekyll/tags/include.rb
CHANGED
|
@@ -7,7 +7,18 @@ module Jekyll
|
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def render(context)
|
|
10
|
-
|
|
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
|
+
File.read(@file)
|
|
18
|
+
else
|
|
19
|
+
"Included file '#{@file}' not found in _includes directory"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
11
22
|
end
|
|
12
23
|
end
|
|
13
24
|
|
|
File without changes
|
|
File without changes
|
data/test/source/index.html
CHANGED
|
@@ -5,8 +5,18 @@ title: Tom Preston-Werner
|
|
|
5
5
|
|
|
6
6
|
h1. Welcome to my site
|
|
7
7
|
|
|
8
|
+
h2. Please read our {{ site.posts | size }} Posts
|
|
9
|
+
|
|
8
10
|
<ul>
|
|
9
11
|
{% for post in site.posts %}
|
|
10
12
|
<li>{{ post.date }} <a href="{{ post.url }}">{{ post.title }}</a></li>
|
|
11
13
|
{% endfor %}
|
|
12
|
-
</ul>
|
|
14
|
+
</ul>
|
|
15
|
+
|
|
16
|
+
{% assign first_post = site.posts.first %}
|
|
17
|
+
<div id="first_post">
|
|
18
|
+
<h1>{{ first_post.title }}</h1>
|
|
19
|
+
<div>
|
|
20
|
+
{{ first_post.content }}
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
|
2
|
+
|
|
3
|
+
class TestGeneratedSite < Test::Unit::TestCase
|
|
4
|
+
def setup
|
|
5
|
+
clear_dest
|
|
6
|
+
source = File.join(File.dirname(__FILE__), *%w[source])
|
|
7
|
+
@s = Site.new(source, dest_dir)
|
|
8
|
+
@s.process
|
|
9
|
+
@index = File.read(File.join(dest_dir, 'index.html'))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_site_posts_in_index
|
|
13
|
+
# confirm that {{ site.posts }} is working
|
|
14
|
+
assert @index.include?("#{@s.posts.size} Posts")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_post_content_in_index
|
|
18
|
+
# confirm that the {{ post.content }} is rendered OK
|
|
19
|
+
assert @index.include?('<p>This <em>is</em> cool</p>')
|
|
20
|
+
end
|
|
21
|
+
end
|
data/test/test_post.rb
CHANGED
|
@@ -7,6 +7,9 @@ class TestPost < Test::Unit::TestCase
|
|
|
7
7
|
|
|
8
8
|
def test_valid
|
|
9
9
|
assert Post.valid?("2008-10-19-foo-bar.textile")
|
|
10
|
+
assert Post.valid?("foo/bar/2008-10-19-foo-bar.textile")
|
|
11
|
+
|
|
12
|
+
assert !Post.valid?("lol2008-10-19-foo-bar.textile")
|
|
10
13
|
assert !Post.valid?("blah")
|
|
11
14
|
end
|
|
12
15
|
|
|
@@ -21,6 +24,7 @@ class TestPost < Test::Unit::TestCase
|
|
|
21
24
|
|
|
22
25
|
def test_url
|
|
23
26
|
p = Post.allocate
|
|
27
|
+
p.categories = []
|
|
24
28
|
p.process("2008-10-19-foo-bar.textile")
|
|
25
29
|
|
|
26
30
|
assert_equal "/2008/10/19/foo-bar.html", p.url
|
|
@@ -29,7 +33,7 @@ class TestPost < Test::Unit::TestCase
|
|
|
29
33
|
def test_permalink
|
|
30
34
|
p = Post.allocate
|
|
31
35
|
p.process("2008-12-03-permalinked-post.textile")
|
|
32
|
-
p.read_yaml(File.join(File.dirname(__FILE__), *%w[source
|
|
36
|
+
p.read_yaml(File.join(File.dirname(__FILE__), *%w[source _posts]), "2008-12-03-permalinked-post.textile")
|
|
33
37
|
|
|
34
38
|
assert_equal "my_category/permalinked-post", p.permalink
|
|
35
39
|
end
|
|
@@ -37,7 +41,7 @@ class TestPost < Test::Unit::TestCase
|
|
|
37
41
|
def test_dir_respects_permalink
|
|
38
42
|
p = Post.allocate
|
|
39
43
|
p.process("2008-12-03-permalinked-post.textile")
|
|
40
|
-
p.read_yaml(File.join(File.dirname(__FILE__), *%w[source
|
|
44
|
+
p.read_yaml(File.join(File.dirname(__FILE__), *%w[source _posts]), "2008-12-03-permalinked-post.textile")
|
|
41
45
|
|
|
42
46
|
assert_equal "my_category", p.dir
|
|
43
47
|
end
|
|
@@ -59,10 +63,10 @@ class TestPost < Test::Unit::TestCase
|
|
|
59
63
|
assert_equal "<h1>{{ page.title }}</h1>\n<p>Best <strong>post</strong> ever</p>", p.content
|
|
60
64
|
end
|
|
61
65
|
|
|
62
|
-
def
|
|
63
|
-
p = Post.new(File.join(File.dirname(__FILE__), *%w[source
|
|
66
|
+
def test_render
|
|
67
|
+
p = Post.new(File.join(File.dirname(__FILE__), *%w[source]), '', "2008-10-18-foo-bar.textile")
|
|
64
68
|
layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")}
|
|
65
|
-
p.
|
|
69
|
+
p.render(layouts, {"site" => {"posts" => []}})
|
|
66
70
|
|
|
67
71
|
assert_equal "<<< <h1>Foo Bar</h1>\n<p>Best <strong>post</strong> ever</p> >>>", p.output
|
|
68
72
|
end
|
|
@@ -70,26 +74,26 @@ class TestPost < Test::Unit::TestCase
|
|
|
70
74
|
def test_write
|
|
71
75
|
clear_dest
|
|
72
76
|
|
|
73
|
-
p = Post.new(File.join(File.dirname(__FILE__), *%w[source
|
|
77
|
+
p = Post.new(File.join(File.dirname(__FILE__), *%w[source]), '', "2008-10-18-foo-bar.textile")
|
|
74
78
|
layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")}
|
|
75
|
-
p.
|
|
79
|
+
p.render(layouts, {"site" => {"posts" => []}})
|
|
76
80
|
p.write(dest_dir)
|
|
77
81
|
end
|
|
78
82
|
|
|
79
83
|
def test_data
|
|
80
|
-
p = Post.new(File.join(File.dirname(__FILE__), *%w[source
|
|
84
|
+
p = Post.new(File.join(File.dirname(__FILE__), *%w[source]), '', "2008-11-21-complex.textile")
|
|
81
85
|
layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")}
|
|
82
|
-
p.
|
|
86
|
+
p.render(layouts, {"site" => {"posts" => []}})
|
|
83
87
|
|
|
84
88
|
assert_equal "<<< <p>url: /2008/11/21/complex.html<br />\ndate: #{Time.parse("2008-11-21")}<br />\nid: /2008/11/21/complex</p> >>>", p.output
|
|
85
89
|
end
|
|
86
90
|
|
|
87
91
|
def test_include
|
|
88
92
|
Jekyll.source = File.join(File.dirname(__FILE__), *%w[source])
|
|
89
|
-
p = Post.new(File.join(File.dirname(__FILE__), *%w[source
|
|
93
|
+
p = Post.new(File.join(File.dirname(__FILE__), *%w[source]), '', "2008-12-13-include.markdown")
|
|
90
94
|
layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")}
|
|
91
|
-
p.
|
|
95
|
+
p.render(layouts, {"site" => {"posts" => []}})
|
|
92
96
|
|
|
93
|
-
assert_equal "<<< <
|
|
97
|
+
assert_equal "<<< <hr />\n<p>Tom Preston-Werner github.com/mojombo</p>\n\n<p>This <em>is</em> cool</p> >>>", p.output
|
|
94
98
|
end
|
|
95
99
|
end
|
data/test/test_site.rb
CHANGED
|
@@ -15,11 +15,11 @@ class TestSite < Test::Unit::TestCase
|
|
|
15
15
|
|
|
16
16
|
assert_equal ["default", "simple"].sort, @s.layouts.keys.sort
|
|
17
17
|
end
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
def test_read_posts
|
|
20
|
-
@s.read_posts
|
|
20
|
+
@s.read_posts('')
|
|
21
21
|
|
|
22
|
-
assert_equal
|
|
22
|
+
assert_equal 4, @s.posts.size
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def test_write_posts
|
|
@@ -27,4 +27,4 @@ class TestSite < Test::Unit::TestCase
|
|
|
27
27
|
|
|
28
28
|
@s.process
|
|
29
29
|
end
|
|
30
|
-
end
|
|
30
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mojombo-jekyll
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tom Preston-Werner
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2008-12-
|
|
12
|
+
date: 2008-12-24 00:00:00 -08:00
|
|
13
13
|
default_executable: jekyll
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
@@ -40,7 +40,7 @@ dependencies:
|
|
|
40
40
|
version: "0"
|
|
41
41
|
version:
|
|
42
42
|
- !ruby/object:Gem::Dependency
|
|
43
|
-
name:
|
|
43
|
+
name: maruku
|
|
44
44
|
version_requirement:
|
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
|
46
46
|
requirements:
|
|
@@ -96,7 +96,10 @@ files:
|
|
|
96
96
|
- lib/jekyll/albino.rb
|
|
97
97
|
- lib/jekyll/converters/csv.rb
|
|
98
98
|
- lib/jekyll/converters/mephisto.rb
|
|
99
|
+
- lib/jekyll/converters/mt.rb
|
|
100
|
+
- lib/jekyll/converters/wordpress.rb
|
|
99
101
|
- lib/jekyll/convertible.rb
|
|
102
|
+
- lib/jekyll/core_ext.rb
|
|
100
103
|
- lib/jekyll/filters.rb
|
|
101
104
|
- lib/jekyll/layout.rb
|
|
102
105
|
- lib/jekyll/page.rb
|
|
@@ -105,16 +108,17 @@ files:
|
|
|
105
108
|
- lib/jekyll/tags/highlight.rb
|
|
106
109
|
- lib/jekyll/tags/include.rb
|
|
107
110
|
- test/helper.rb
|
|
108
|
-
- test/source/_includes/sig.
|
|
111
|
+
- test/source/_includes/sig.markdown
|
|
109
112
|
- test/source/_layouts/default.html
|
|
110
113
|
- test/source/_layouts/simple.html
|
|
111
114
|
- test/source/_posts/2008-10-18-foo-bar.textile
|
|
112
115
|
- test/source/_posts/2008-11-21-complex.textile
|
|
113
|
-
- test/source/_posts/2008-12-
|
|
116
|
+
- test/source/_posts/2008-12-03-permalinked-post.textile
|
|
117
|
+
- test/source/_posts/2008-12-13-include.markdown
|
|
114
118
|
- test/source/css/screen.css
|
|
115
119
|
- test/source/index.html
|
|
116
|
-
- test/source/posts/2008-12-03-permalinked-post.textile
|
|
117
120
|
- test/suite.rb
|
|
121
|
+
- test/test_generated_site.rb
|
|
118
122
|
- test/test_jekyll.rb
|
|
119
123
|
- test/test_post.rb
|
|
120
124
|
- test/test_site.rb
|
|
@@ -146,6 +150,7 @@ signing_key:
|
|
|
146
150
|
specification_version: 2
|
|
147
151
|
summary: Jekyll is a simple, blog aware, static site generator.
|
|
148
152
|
test_files:
|
|
153
|
+
- test/test_generated_site.rb
|
|
149
154
|
- test/test_jekyll.rb
|
|
150
155
|
- test/test_post.rb
|
|
151
156
|
- test/test_site.rb
|