zzot-semi-static 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +63 -0
- data/VERSION.yml +2 -2
- data/lib/semi-static.rb +68 -1
- data/lib/semi-static/base.rb +3 -4
- data/lib/semi-static/convertable.rb +19 -6
- data/lib/semi-static/index.rb +19 -1
- data/lib/semi-static/layout.rb +9 -0
- data/lib/semi-static/post.rb +0 -21
- data/lib/semi-static/posts.rb +51 -3
- data/lib/semi-static/pygmentize.rb +11 -4
- data/lib/semi-static/site.rb +72 -7
- data/lib/semi-static/snippet.rb +7 -0
- data/lib/semi-static/statistics.rb +13 -0
- data/lib/semi-static/tags.rb +121 -0
- data/test/ref/test_layout/default_layout.html +43 -1
- data/test/ref/test_layout/post_layout.html +42 -0
- data/test/ref/test_page/about.html +42 -0
- data/test/ref/test_page/colophon.html +42 -0
- data/test/ref/test_post/impressions.html +48 -0
- data/test/ref/test_post/lighting-up.html +48 -0
- data/test/ref/test_post/the-working-mans-typeface.html +92 -45
- data/test/source/layouts/default.haml +4 -1
- data/test/source/layouts/post.erb +7 -3
- data/test/source/posts/2005-03-27-a-bash-script-to-mess-with-the-containing-terminalapp-window.markdown +2 -1
- data/test/source/posts/2008-11-24-lighting-up.markdown +0 -1
- data/test/source/posts/2008-11-26-impressions.md +0 -1
- data/test/source/posts/2008-12-04-the-working-mans-typeface.html +1 -1
- data/test/source/snippets/tags-widget.haml +6 -0
- data/test/test_layout.rb +2 -1
- data/test/test_post.rb +17 -14
- metadata +5 -4
- data/README.markdown +0 -84
- data/lib/semi-static/categories.rb +0 -74
data/README.rdoc
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
= Semi Static
|
2
|
+
|
3
|
+
Semi Static is yet another static site generator. I've been playing around
|
4
|
+
with similar systems off and on for years, but it's
|
5
|
+
Jekyll[http://github.com/mojombo/jekyll] that finally convinced me to build
|
6
|
+
(and finish) one for myself. The main idea that I take from Jekyll is using
|
7
|
+
Git[http://git-scm.com/] as the database. The idea from Jekyll that I'm not
|
8
|
+
adopting is avoiding Ruby[http://ruby-lang.org/] code evaluation at all
|
9
|
+
costs -- I'm not letting other people feed documents into it (as
|
10
|
+
GitHub[http://github.com/] Pages[http://pages.github.com] does), so I don't
|
11
|
+
need to protect myself from them.
|
12
|
+
|
13
|
+
At some point Semi Static had a sister project, Semi Live, that would generate
|
14
|
+
the site dynamically (probably via Rails[http://rubyonrails.org/]). I stopped
|
15
|
+
working on it not long after I first started, so don't expect to see it on my
|
16
|
+
projects[http://github.com/zzot] page.
|
17
|
+
|
18
|
+
== Features
|
19
|
+
|
20
|
+
* Layouts can be Haml[http://haml.hamptoncatlin.com/] or
|
21
|
+
ERB[http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/] -- but not
|
22
|
+
Liquid[http://www.liquidmarkup.org/].
|
23
|
+
* Stylesheets can be Sass[http://haml.hamptoncatlin.com/] or raw CSS.
|
24
|
+
* Pages and posts can be Maruku[http://maruku.rubyforge.org/] or raw HTML.
|
25
|
+
* Code highlighting by Pygments[http://pygments.org/].
|
26
|
+
|
27
|
+
== Installation
|
28
|
+
|
29
|
+
The easiest way to install Semi-Static is via RubyGems[http://www.rubygems.org/]:
|
30
|
+
|
31
|
+
$ sudo gem install zzot-semi-static -s http://gems.github.com/
|
32
|
+
|
33
|
+
Semi-Static requires the `Haml` and `Maruku` gems and the `Pygments`
|
34
|
+
library to be installed.
|
35
|
+
|
36
|
+
== Usage
|
37
|
+
|
38
|
+
$ semi source-path [output-path]
|
39
|
+
|
40
|
+
== License
|
41
|
+
|
42
|
+
(The MIT License)
|
43
|
+
|
44
|
+
Copyright (c) 2009 Josh Dady
|
45
|
+
|
46
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
47
|
+
a copy of this software and associated documentation files (the
|
48
|
+
'Software'), to deal in the Software without restriction, including
|
49
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
50
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
51
|
+
permit persons to whom the Software is furnished to do so, subject to
|
52
|
+
the following conditions:
|
53
|
+
|
54
|
+
The above copyright notice and this permission notice shall be
|
55
|
+
included in all copies or substantial portions of the Software.
|
56
|
+
|
57
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
58
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
59
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
60
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
61
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
62
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
63
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/VERSION.yml
CHANGED
data/lib/semi-static.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Core requirements
|
2
2
|
require 'erb'
|
3
3
|
require 'tempfile'
|
4
|
+
require 'time'
|
4
5
|
require 'yaml'
|
5
6
|
|
6
7
|
# Gem requirements
|
@@ -25,6 +26,72 @@ require 'semi-static/post'
|
|
25
26
|
require 'semi-static/snippet'
|
26
27
|
require 'semi-static/posts'
|
27
28
|
require 'semi-static/index'
|
28
|
-
require 'semi-static/
|
29
|
+
require 'semi-static/tags'
|
29
30
|
require 'semi-static/statistics'
|
30
31
|
require 'semi-static/site'
|
32
|
+
|
33
|
+
##
|
34
|
+
# Semi Static is yet another static site generator. I've been playing around
|
35
|
+
# with similar systems off and on for years, but it's
|
36
|
+
# Jekyll[http://github.com/mojombo/jekyll] that finally convinced me to build
|
37
|
+
# (and finish) one for myself. The main idea that I take from Jekyll is using
|
38
|
+
# Git[http://git-scm.com/] as the database. The idea from Jekyll that I'm not
|
39
|
+
# adopting is avoiding Ruby[http://ruby-lang.org/] code evaluation at all
|
40
|
+
# costs -- I'm not letting other people feed documents into it (as
|
41
|
+
# GitHub[http://github.com/] Pages[http://pages.github.com] does), so I don't
|
42
|
+
# need to protect myself from them.
|
43
|
+
#
|
44
|
+
# At some point Semi Static had a sister project, Semi Live, that would generate
|
45
|
+
# the site dynamically (probably via Rails[http://rubyonrails.org/]). I stopped
|
46
|
+
# working on it not long after I first started, so don't expect to see it on my
|
47
|
+
# projects[http://github.com/zzot] page.
|
48
|
+
#
|
49
|
+
# == Features
|
50
|
+
#
|
51
|
+
# * Layouts can be Haml[http://haml.hamptoncatlin.com/] or
|
52
|
+
# ERB[http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/] -- but not
|
53
|
+
# Liquid[http://www.liquidmarkup.org/].
|
54
|
+
# * Stylesheets can be Sass[http://haml.hamptoncatlin.com/] or raw CSS.
|
55
|
+
# * Pages and posts can be Maruku[http://maruku.rubyforge.org/] or raw HTML.
|
56
|
+
# * Code highlighting by Pygments[http://pygments.org/].
|
57
|
+
#
|
58
|
+
# == Installation
|
59
|
+
#
|
60
|
+
# The easiest way to install Semi-Static is via RubyGems[http://www.rubygems.org/]:
|
61
|
+
#
|
62
|
+
# $ sudo gem install zzot-semi-static -s http://gems.github.com/
|
63
|
+
#
|
64
|
+
# Semi-Static requires the `Haml` and `Maruku` gems and the `Pygments`
|
65
|
+
# library to be installed.
|
66
|
+
#
|
67
|
+
# == Usage
|
68
|
+
#
|
69
|
+
# $ semi source-path [output-path]
|
70
|
+
#
|
71
|
+
# == License
|
72
|
+
#
|
73
|
+
# (The MIT License)
|
74
|
+
#
|
75
|
+
# Copyright (c) 2009 Josh Dady
|
76
|
+
#
|
77
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
78
|
+
# a copy of this software and associated documentation files (the
|
79
|
+
# 'Software'), to deal in the Software without restriction, including
|
80
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
81
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
82
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
83
|
+
# the following conditions:
|
84
|
+
#
|
85
|
+
# The above copyright notice and this permission notice shall be
|
86
|
+
# included in all copies or substantial portions of the Software.
|
87
|
+
#
|
88
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
89
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
90
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
91
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
92
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
93
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
94
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
95
|
+
|
96
|
+
module SemiStatic
|
97
|
+
end
|
data/lib/semi-static/base.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
module SemiStatic
|
2
|
-
# Base
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# can refer to it later.
|
2
|
+
# Base is a single source file and its associated metadata. Base loads
|
3
|
+
# itself from the source file and strips off and parses the metadata in
|
4
|
+
# the file's header.
|
6
5
|
class Base
|
7
6
|
##
|
8
7
|
# The associated Site object
|
@@ -1,8 +1,10 @@
|
|
1
1
|
module SemiStatic
|
2
|
+
##
|
3
|
+
# Support conversion of the source file into another format.
|
2
4
|
module Convertable
|
3
5
|
include ERB::Util
|
4
6
|
|
5
|
-
def load
|
7
|
+
def load #:nodoc:
|
6
8
|
@content = nil
|
7
9
|
if layout
|
8
10
|
layout.load
|
@@ -10,6 +12,8 @@ module SemiStatic
|
|
10
12
|
super
|
11
13
|
end
|
12
14
|
|
15
|
+
##
|
16
|
+
# Format the source file.
|
13
17
|
def content(options={})
|
14
18
|
return @content unless @content.nil?
|
15
19
|
|
@@ -25,7 +29,9 @@ module SemiStatic
|
|
25
29
|
when '.haml'
|
26
30
|
Haml::Engine.new(self.source_content, :filename => source_path).render(binding)
|
27
31
|
when '.erb'
|
28
|
-
ERB.new
|
32
|
+
erb = ERB.new self.source_content, nil, '-'
|
33
|
+
erb.filename = source_path
|
34
|
+
erb.result(binding)
|
29
35
|
when '.html'
|
30
36
|
self.source_content
|
31
37
|
else
|
@@ -34,13 +40,13 @@ module SemiStatic
|
|
34
40
|
end
|
35
41
|
end
|
36
42
|
|
37
|
-
def layout_name
|
43
|
+
def layout_name #:nodoc:
|
38
44
|
unless source_metadata.nil? || !source_metadata.include?(:layout)
|
39
45
|
source_metadata[:layout].to_sym
|
40
46
|
end
|
41
47
|
end
|
42
48
|
|
43
|
-
def layout
|
49
|
+
def layout #:nodoc:
|
44
50
|
if layout_name.nil?
|
45
51
|
return nil
|
46
52
|
else
|
@@ -48,6 +54,9 @@ module SemiStatic
|
|
48
54
|
end
|
49
55
|
end
|
50
56
|
|
57
|
+
##
|
58
|
+
# Add the layout used (if any) to the list of files used to determine
|
59
|
+
# the objects modification time.
|
51
60
|
def source_mtime
|
52
61
|
mtime = super
|
53
62
|
if layout && layout.source_mtime > mtime
|
@@ -56,6 +65,8 @@ module SemiStatic
|
|
56
65
|
return mtime
|
57
66
|
end
|
58
67
|
|
68
|
+
##
|
69
|
+
# Wrap the formatted source file in the Layout (if any).
|
59
70
|
def render(options={})
|
60
71
|
content = self.content(options)
|
61
72
|
if layout
|
@@ -65,6 +76,8 @@ module SemiStatic
|
|
65
76
|
return content
|
66
77
|
end
|
67
78
|
|
79
|
+
##
|
80
|
+
# Helper method used to insert a Snippet into the formatted output.
|
68
81
|
def snippet(name)
|
69
82
|
name = name.to_s
|
70
83
|
site.snippets[name].render :page => self
|
@@ -73,7 +86,7 @@ module SemiStatic
|
|
73
86
|
# This method is adapted from Haml::Buffer#parse_object_ref -- it's
|
74
87
|
# used to make it easier for Haml and ERB layouts to generate the
|
75
88
|
# same output so I can use the same test output for both.
|
76
|
-
def object_ref(object)
|
89
|
+
def object_ref(object) #:nodoc:
|
77
90
|
return '' if object.nil?
|
78
91
|
name = underscore(object.class)
|
79
92
|
id = "#{name}_#{object.id || 'new'}"
|
@@ -83,7 +96,7 @@ module SemiStatic
|
|
83
96
|
# Changes a word from camel case to underscores. Based on the method
|
84
97
|
# of the same name in Rails' Inflector, but copied here so it'll run
|
85
98
|
# properly without Rails.
|
86
|
-
def underscore(camel_cased_word)
|
99
|
+
def underscore(camel_cased_word) #:nodoc:
|
87
100
|
camel_cased_word.to_s.gsub(/::/, '_').
|
88
101
|
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
89
102
|
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
data/lib/semi-static/index.rb
CHANGED
@@ -1,9 +1,27 @@
|
|
1
1
|
module SemiStatic
|
2
|
+
##
|
3
|
+
# Index is used to generate several site index pages that don't have a
|
4
|
+
# fixed path (i.e., the yearly index pages) from a single source file.
|
5
|
+
# It can have a Layout and use any number of Snippets. Index's modification
|
6
|
+
# time is the most recent of itself, its layout, and any Snippets used.
|
7
|
+
# Indices are also considered out-of-date if any posts in the index's range
|
8
|
+
# are changed.
|
2
9
|
class Index < Base
|
3
10
|
include Convertable
|
4
11
|
|
5
|
-
|
12
|
+
##
|
13
|
+
# Posts in range for the Index's current path.
|
14
|
+
attr_accessor :posts
|
6
15
|
|
16
|
+
##
|
17
|
+
# The Index's current context (usually a Date).
|
18
|
+
attr_accessor :context
|
19
|
+
|
20
|
+
##
|
21
|
+
# Initializes a new Index
|
22
|
+
#
|
23
|
+
# +site+:: The Site object we belong to
|
24
|
+
# +path+:: The relative path to the source file
|
7
25
|
def initialize(site, path)
|
8
26
|
super
|
9
27
|
@metadata = [ :layout ]
|
data/lib/semi-static/layout.rb
CHANGED
@@ -1,9 +1,18 @@
|
|
1
1
|
module SemiStatic
|
2
|
+
##
|
3
|
+
# Layout embeds the formatted output of a Convertable within a large document.
|
2
4
|
class Layout < Base
|
3
5
|
include Convertable
|
4
6
|
|
7
|
+
##
|
8
|
+
# The Layout's name
|
5
9
|
attr_reader :name
|
6
10
|
|
11
|
+
##
|
12
|
+
# Initialize a new Layout
|
13
|
+
#
|
14
|
+
# +site+: The Site we belong to.
|
15
|
+
# +path+: The path to the source file.
|
7
16
|
def initialize(site, path)
|
8
17
|
super
|
9
18
|
@metadata = [ :layout ]
|
data/lib/semi-static/post.rb
CHANGED
@@ -10,10 +10,6 @@ module SemiStatic
|
|
10
10
|
# The Post's name
|
11
11
|
attr_reader :name
|
12
12
|
|
13
|
-
##
|
14
|
-
# The Post's Category
|
15
|
-
attr_reader :category
|
16
|
-
|
17
13
|
##
|
18
14
|
# The Post's Tags
|
19
15
|
attr_reader :tags
|
@@ -57,9 +53,6 @@ module SemiStatic
|
|
57
53
|
|
58
54
|
@name = File.basename(source_path, source_ext)
|
59
55
|
|
60
|
-
@category = site.categories[source_metadata[:category]]
|
61
|
-
@category << self
|
62
|
-
|
63
56
|
@tags = []
|
64
57
|
unless source_metadata[:tags].nil?
|
65
58
|
for tag in source_metadata[:tags]
|
@@ -92,20 +85,6 @@ module SemiStatic
|
|
92
85
|
return "#{uri}"
|
93
86
|
end
|
94
87
|
|
95
|
-
# def comments_link
|
96
|
-
# "#{uri}#comments"
|
97
|
-
# end
|
98
|
-
#
|
99
|
-
# def comment_count
|
100
|
-
# 0
|
101
|
-
# end
|
102
|
-
|
103
|
-
##
|
104
|
-
# Formatted date the Post was published (i.e., "March 15, 2009")
|
105
|
-
def date
|
106
|
-
created.strftime '%B %e, %Y'
|
107
|
-
end
|
108
|
-
|
109
88
|
##
|
110
89
|
# Year the Post was published as a String (i.e., "2009")
|
111
90
|
def year
|
data/lib/semi-static/posts.rb
CHANGED
@@ -1,7 +1,27 @@
|
|
1
1
|
module SemiStatic
|
2
|
+
##
|
3
|
+
# Collection of Posts for the current site.
|
2
4
|
class Posts
|
3
|
-
|
5
|
+
##
|
6
|
+
# The Site object we belong to.
|
7
|
+
attr_reader :site
|
4
8
|
|
9
|
+
##
|
10
|
+
# The raw list of posts.
|
11
|
+
attr_reader :posts
|
12
|
+
|
13
|
+
##
|
14
|
+
# Posts indexed by name.
|
15
|
+
attr_reader :names
|
16
|
+
|
17
|
+
##
|
18
|
+
# Indices that correspond to the Posts.
|
19
|
+
attr_reader :indices
|
20
|
+
|
21
|
+
##
|
22
|
+
# Initializes a new Posts
|
23
|
+
#
|
24
|
+
# +site+: The Site we belong to.
|
5
25
|
def initialize(site)
|
6
26
|
@site = site
|
7
27
|
@posts = []
|
@@ -9,8 +29,14 @@ module SemiStatic
|
|
9
29
|
@indices = Set.new
|
10
30
|
end
|
11
31
|
|
32
|
+
##
|
33
|
+
# The format of the Date portion of a post's filename.
|
12
34
|
NAME_RE = /^([0-9]{4})-([0-9]{2})-([0-9]{2})-(.*)/
|
13
35
|
|
36
|
+
##
|
37
|
+
# Parse the given file as a Post and add it to the list.
|
38
|
+
#
|
39
|
+
# +source_path+: Path to the source file
|
14
40
|
def <<(source_path)
|
15
41
|
unless File.file?(source_path)
|
16
42
|
$stderr.puts "[#{source_path}]"
|
@@ -28,6 +54,10 @@ module SemiStatic
|
|
28
54
|
end
|
29
55
|
end
|
30
56
|
|
57
|
+
##
|
58
|
+
# Truncate the list of Posts to the given number (to speed up testing).
|
59
|
+
#
|
60
|
+
# +count+: The number of posts to keep.
|
31
61
|
def chop!(count)
|
32
62
|
raise ArgumentError unless count > 0
|
33
63
|
posts = self.posts.first(count)
|
@@ -43,10 +73,16 @@ module SemiStatic
|
|
43
73
|
end
|
44
74
|
end
|
45
75
|
|
76
|
+
##
|
77
|
+
# Number of posts.
|
46
78
|
def length
|
47
79
|
self.posts.length
|
48
80
|
end
|
49
81
|
|
82
|
+
##
|
83
|
+
# Fetch the least recent posts.
|
84
|
+
#
|
85
|
+
# +n+: Number of Posts to return.
|
50
86
|
def first(n=nil)
|
51
87
|
if n.nil?
|
52
88
|
self.posts.first
|
@@ -55,6 +91,10 @@ module SemiStatic
|
|
55
91
|
end
|
56
92
|
end
|
57
93
|
|
94
|
+
##
|
95
|
+
# Fetch the most recent posts.
|
96
|
+
#
|
97
|
+
# +n+: Number of Posts to return.
|
58
98
|
def last(n=nil)
|
59
99
|
if n.nil?
|
60
100
|
self.posts.last
|
@@ -63,6 +103,8 @@ module SemiStatic
|
|
63
103
|
end
|
64
104
|
end
|
65
105
|
|
106
|
+
##
|
107
|
+
# Fetch the Posts for the given Date range.
|
66
108
|
def from(year, month=nil, day=nil)
|
67
109
|
if year.is_a?(String) && month.nil? && day.nil?
|
68
110
|
date = year.split('/', 3)
|
@@ -95,15 +137,21 @@ module SemiStatic
|
|
95
137
|
return result
|
96
138
|
end
|
97
139
|
|
140
|
+
##
|
141
|
+
# Get the post with the given name.
|
98
142
|
def [](name)
|
99
143
|
return self.names[name]
|
100
144
|
end
|
101
145
|
|
102
|
-
|
146
|
+
##
|
147
|
+
# Iterate over all posts.
|
148
|
+
def each(&block) # :yields: Post
|
103
149
|
self.posts.each(&block)
|
104
150
|
end
|
105
151
|
|
106
|
-
|
152
|
+
##
|
153
|
+
# Iterate over all indices.
|
154
|
+
def each_index(&block) # :yields: String
|
107
155
|
indices.each(&block)
|
108
156
|
end
|
109
157
|
end
|