PerfectlyNormal-jekyll 0.5.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.
- data/History.txt +127 -0
- data/README.textile +41 -0
- data/Rakefile +91 -0
- data/VERSION.yml +4 -0
- data/bin/jekyll +150 -0
- data/lib/jekyll.rb +84 -0
- data/lib/jekyll/albino.rb +122 -0
- data/lib/jekyll/converters/csv.rb +26 -0
- data/lib/jekyll/converters/mephisto.rb +79 -0
- data/lib/jekyll/converters/mt.rb +59 -0
- data/lib/jekyll/converters/textpattern.rb +50 -0
- data/lib/jekyll/converters/typo.rb +49 -0
- data/lib/jekyll/converters/wordpress.rb +54 -0
- data/lib/jekyll/convertible.rb +82 -0
- data/lib/jekyll/core_ext.rb +22 -0
- data/lib/jekyll/filters.rb +47 -0
- data/lib/jekyll/layout.rb +36 -0
- data/lib/jekyll/page.rb +70 -0
- data/lib/jekyll/post.rb +243 -0
- data/lib/jekyll/site.rb +265 -0
- data/lib/jekyll/tags/highlight.rb +56 -0
- data/lib/jekyll/tags/include.rb +31 -0
- data/test/helper.rb +27 -0
- data/test/source/_includes/sig.markdown +3 -0
- data/test/source/_layouts/default.html +27 -0
- data/test/source/_layouts/simple.html +1 -0
- 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/2008-10-18-foo-bar.textile +8 -0
- data/test/source/_posts/2008-11-21-complex.textile +8 -0
- data/test/source/_posts/2008-12-03-permalinked-post.textile +9 -0
- data/test/source/_posts/2008-12-13-include.markdown +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/source/_posts/2009-03-12-hash-#1.markdown +6 -0
- data/test/source/category/_posts/2008-9-23-categories.textile +6 -0
- data/test/source/css/screen.css +76 -0
- data/test/source/foo/_posts/bar/2008-12-12-topical-post.textile +8 -0
- data/test/source/index.html +22 -0
- data/test/source/z_category/_posts/2008-9-23-categories.textile +6 -0
- data/test/suite.rb +9 -0
- data/test/test_filters.rb +49 -0
- data/test/test_generated_site.rb +38 -0
- data/test/test_post.rb +269 -0
- data/test/test_site.rb +65 -0
- data/test/test_tags.rb +116 -0
- metadata +164 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
module Jekyll
|
2
|
+
|
3
|
+
class HighlightBlock < Liquid::Block
|
4
|
+
include Liquid::StandardFilters
|
5
|
+
|
6
|
+
# we need a language, but the linenos argument is optional.
|
7
|
+
SYNTAX = /(\w+)\s?(:?linenos)?\s?/
|
8
|
+
|
9
|
+
def initialize(tag_name, markup, tokens)
|
10
|
+
super
|
11
|
+
if markup =~ SYNTAX
|
12
|
+
@lang = $1
|
13
|
+
if defined? $2
|
14
|
+
# additional options to pass to Albino.
|
15
|
+
@options = { 'O' => 'linenos=inline' }
|
16
|
+
else
|
17
|
+
@options = {}
|
18
|
+
end
|
19
|
+
else
|
20
|
+
raise SyntaxError.new("Syntax Error in 'highlight' - Valid syntax: highlight <lang> [linenos]")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def render(context)
|
25
|
+
if context.registers[:site].pygments
|
26
|
+
render_pygments(context, super.to_s)
|
27
|
+
else
|
28
|
+
render_codehighlighter(context, super.to_s)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def render_pygments(context, code)
|
33
|
+
if context["content_type"] == "markdown"
|
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>"
|
37
|
+
else
|
38
|
+
return Albino.new(code, @lang).to_s(@options)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def render_codehighlighter(context, code)
|
43
|
+
#The div is required because RDiscount blows ass
|
44
|
+
<<-HTML
|
45
|
+
<div>
|
46
|
+
<pre>
|
47
|
+
<code class='#{@lang}'>#{h(code).strip}</code>
|
48
|
+
</pre>
|
49
|
+
</div>
|
50
|
+
HTML
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
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(context.registers[:site].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/test/helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'RedCloth', '= 4.1.0'
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), *%w[.. lib jekyll])
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
require 'redgreen'
|
8
|
+
require 'shoulda'
|
9
|
+
require 'rr'
|
10
|
+
|
11
|
+
include Jekyll
|
12
|
+
|
13
|
+
class Test::Unit::TestCase
|
14
|
+
include RR::Adapters::TestUnit
|
15
|
+
|
16
|
+
def dest_dir(*subdirs)
|
17
|
+
File.join(File.dirname(__FILE__), 'dest', *subdirs)
|
18
|
+
end
|
19
|
+
|
20
|
+
def source_dir(*subdirs)
|
21
|
+
File.join(File.dirname(__FILE__), 'source', *subdirs)
|
22
|
+
end
|
23
|
+
|
24
|
+
def clear_dest
|
25
|
+
FileUtils.rm_rf(dest_dir)
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en-us">
|
5
|
+
<head>
|
6
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
7
|
+
<title>{{ page.title }}</title>
|
8
|
+
<meta name="author" content="<%= @page.author %>" />
|
9
|
+
|
10
|
+
<!-- CodeRay syntax highlighting CSS -->
|
11
|
+
<link rel="stylesheet" href="/css/coderay.css" type="text/css" />
|
12
|
+
|
13
|
+
<!-- Homepage CSS -->
|
14
|
+
<link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen, projection" />
|
15
|
+
</head>
|
16
|
+
<body>
|
17
|
+
|
18
|
+
<div class="site">
|
19
|
+
<div class="title">
|
20
|
+
Tom Preston-Werner
|
21
|
+
</div>
|
22
|
+
|
23
|
+
{{ content }}
|
24
|
+
</div>
|
25
|
+
|
26
|
+
</body>
|
27
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
<<< {{ content }} >>>
|
@@ -0,0 +1,76 @@
|
|
1
|
+
/*****************************************************************************/
|
2
|
+
/*
|
3
|
+
/* Common
|
4
|
+
/*
|
5
|
+
/*****************************************************************************/
|
6
|
+
|
7
|
+
/* Global Reset */
|
8
|
+
|
9
|
+
* {
|
10
|
+
margin: 0;
|
11
|
+
padding: 0;
|
12
|
+
}
|
13
|
+
|
14
|
+
html, body {
|
15
|
+
height: 100%;
|
16
|
+
}
|
17
|
+
|
18
|
+
body {
|
19
|
+
background-color: white;
|
20
|
+
font: 13.34px helvetica, arial, clean, sans-serif;
|
21
|
+
*font-size: small;
|
22
|
+
text-align: center;
|
23
|
+
}
|
24
|
+
|
25
|
+
h1, h2, h3, h4, h5, h6 {
|
26
|
+
font-size: 100%;
|
27
|
+
}
|
28
|
+
|
29
|
+
h1 {
|
30
|
+
margin-bottom: 1em;
|
31
|
+
}
|
32
|
+
|
33
|
+
p {
|
34
|
+
margin: 1em 0;
|
35
|
+
}
|
36
|
+
|
37
|
+
a {
|
38
|
+
color: #00a;
|
39
|
+
}
|
40
|
+
|
41
|
+
a:hover {
|
42
|
+
color: black;
|
43
|
+
}
|
44
|
+
|
45
|
+
a:visited {
|
46
|
+
color: #a0a;
|
47
|
+
}
|
48
|
+
|
49
|
+
table {
|
50
|
+
font-size: inherit;
|
51
|
+
font: 100%;
|
52
|
+
}
|
53
|
+
|
54
|
+
/*****************************************************************************/
|
55
|
+
/*
|
56
|
+
/* Site
|
57
|
+
/*
|
58
|
+
/*****************************************************************************/
|
59
|
+
|
60
|
+
.site {
|
61
|
+
font-size: 110%;
|
62
|
+
text-align: justify;
|
63
|
+
width: 40em;
|
64
|
+
margin: 3em auto 2em auto;
|
65
|
+
line-height: 1.5em;
|
66
|
+
}
|
67
|
+
|
68
|
+
.title {
|
69
|
+
color: #a00;
|
70
|
+
font-weight: bold;
|
71
|
+
margin-bottom: 2em;
|
72
|
+
}
|
73
|
+
|
74
|
+
.site .meta {
|
75
|
+
color: #aaa;
|
76
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Tom Preston-Werner
|
4
|
+
---
|
5
|
+
|
6
|
+
h1. Welcome to my site
|
7
|
+
|
8
|
+
h2. Please read our {{ site.posts | size }} Posts
|
9
|
+
|
10
|
+
<ul>
|
11
|
+
{% for post in site.posts %}
|
12
|
+
<li>{{ post.date }} <a href="{{ post.url }}">{{ post.title }}</a></li>
|
13
|
+
{% endfor %}
|
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>
|
data/test/suite.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TestFilters < Test::Unit::TestCase
|
4
|
+
class JekyllFilter
|
5
|
+
include Jekyll::Filters
|
6
|
+
end
|
7
|
+
|
8
|
+
context "filters" do
|
9
|
+
setup do
|
10
|
+
@filter = JekyllFilter.new
|
11
|
+
end
|
12
|
+
|
13
|
+
should "textilize with simple string" do
|
14
|
+
assert_equal "<p>something <strong>really</strong> simple</p>", @filter.textilize("something *really* simple")
|
15
|
+
end
|
16
|
+
|
17
|
+
should "convert array to sentence string with no args" do
|
18
|
+
assert_equal "", @filter.array_to_sentence_string([])
|
19
|
+
end
|
20
|
+
|
21
|
+
should "convert array to sentence string with one arg" do
|
22
|
+
assert_equal "1", @filter.array_to_sentence_string([1])
|
23
|
+
assert_equal "chunky", @filter.array_to_sentence_string(["chunky"])
|
24
|
+
end
|
25
|
+
|
26
|
+
should "convert array to sentence string with two args" do
|
27
|
+
assert_equal "1 and 2", @filter.array_to_sentence_string([1, 2])
|
28
|
+
assert_equal "chunky and bacon", @filter.array_to_sentence_string(["chunky", "bacon"])
|
29
|
+
end
|
30
|
+
|
31
|
+
should "convert array to sentence string with multiple args" do
|
32
|
+
assert_equal "1, 2, 3, and 4", @filter.array_to_sentence_string([1, 2, 3, 4])
|
33
|
+
assert_equal "chunky, bacon, bits, and pieces", @filter.array_to_sentence_string(["chunky", "bacon", "bits", "pieces"])
|
34
|
+
end
|
35
|
+
|
36
|
+
should "escape xml with ampersands" do
|
37
|
+
assert_equal "AT&T", @filter.xml_escape("AT&T")
|
38
|
+
assert_equal "<code>command &lt;filename&gt;</code>", @filter.xml_escape("<code>command <filename></code>")
|
39
|
+
end
|
40
|
+
|
41
|
+
should "escape space as plus" do
|
42
|
+
assert_equal "my+things", @filter.cgi_escape("my things")
|
43
|
+
end
|
44
|
+
|
45
|
+
should "escape special characters" do
|
46
|
+
assert_equal "hey%21", @filter.cgi_escape("hey!")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TestGeneratedSite < Test::Unit::TestCase
|
4
|
+
context "generated sites" do
|
5
|
+
setup do
|
6
|
+
clear_dest
|
7
|
+
stub(Jekyll).configuration do
|
8
|
+
Jekyll::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir})
|
9
|
+
end
|
10
|
+
|
11
|
+
@site = Site.new(Jekyll.configuration)
|
12
|
+
@site.process
|
13
|
+
@index = File.read(dest_dir('index.html'))
|
14
|
+
end
|
15
|
+
|
16
|
+
should "insert site.posts into the index" do
|
17
|
+
assert @index.include?("#{@site.posts.size} Posts")
|
18
|
+
end
|
19
|
+
|
20
|
+
should "render post.content" do
|
21
|
+
latest_post = Dir[source_dir('_posts', '*')].sort.last
|
22
|
+
post = Post.new(@site, source_dir, '', File.basename(latest_post))
|
23
|
+
post.transform
|
24
|
+
assert @index.include?(post.content)
|
25
|
+
end
|
26
|
+
|
27
|
+
should "hide unpublished posts" do
|
28
|
+
published = Dir[dest_dir('publish_test/2008/02/02/*.html')].map {|f| File.basename(f)}
|
29
|
+
|
30
|
+
assert_equal 1, published.size
|
31
|
+
assert_equal "published.html", published.first
|
32
|
+
end
|
33
|
+
|
34
|
+
should "not copy _posts directory" do
|
35
|
+
assert !File.exist?(dest_dir('_posts'))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|