zzot-semi-static 0.0.2 → 0.0.3
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/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
|