fngtps-weblog 0.5.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/TODO +5 -0
- data/bin/weblog +47 -0
- data/lib/option_parser.rb +28 -0
- data/lib/weblog.rb +155 -0
- data/lib/weblog/helpers.rb +13 -0
- data/lib/weblog/index.rb +56 -0
- data/lib/weblog/month.rb +67 -0
- data/lib/weblog/post.rb +154 -0
- data/lib/weblog/snippet.rb +51 -0
- data/templates/index.html.erb +13 -0
- data/templates/index.rss.erb +23 -0
- data/templates/month.html.erb +13 -0
- data/templates/post.html.erb +18 -0
- metadata +162 -0
data/TODO
ADDED
data/bin/weblog
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
if $0 == __FILE__
|
4
|
+
require 'rubygems'
|
5
|
+
$:.unshift(File.expand_path('../../lib', __FILE__))
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'weblog'
|
9
|
+
require 'option_parser'
|
10
|
+
|
11
|
+
def usage
|
12
|
+
puts "Usage: #{File.basename($0)} <command>"
|
13
|
+
puts ""
|
14
|
+
puts "Commands:"
|
15
|
+
puts " init: Initialize a directory for use with the weblog tool"
|
16
|
+
puts " generate: Convert all Markdown source to an HTML file"
|
17
|
+
puts " publish: Move a draft directory into the public directory"
|
18
|
+
puts " info: Print information about the current working directory"
|
19
|
+
puts "Options:"
|
20
|
+
puts " -v, --verbose: Print informative messages"
|
21
|
+
end
|
22
|
+
|
23
|
+
options = {}
|
24
|
+
flags, args = OptionParser.parse(ARGV)
|
25
|
+
|
26
|
+
flags.each do |key, value|
|
27
|
+
case key
|
28
|
+
when 'h', 'help'
|
29
|
+
usage
|
30
|
+
exit 0
|
31
|
+
when 'v', 'verbose'
|
32
|
+
options[:verbose] = true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
case args[0]
|
37
|
+
when 'init'
|
38
|
+
Weblog.init(options)
|
39
|
+
when 'publish'
|
40
|
+
Weblog.publish(options, *args[1..-1])
|
41
|
+
when 'info'
|
42
|
+
Weblog.print_info(options)
|
43
|
+
when 'help'
|
44
|
+
usage
|
45
|
+
else
|
46
|
+
Weblog.generate(options)
|
47
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class OptionParser
|
2
|
+
def self.parse(argv)
|
3
|
+
return [{},[]] if argv.empty?
|
4
|
+
|
5
|
+
options = {}
|
6
|
+
rest = []
|
7
|
+
switch = nil
|
8
|
+
|
9
|
+
for value in argv
|
10
|
+
# values is a switch
|
11
|
+
if value[0] == 45
|
12
|
+
switch = value.slice((value[1] == 45 ? 2 : 1)..-1)
|
13
|
+
options[switch] = nil
|
14
|
+
else
|
15
|
+
if switch
|
16
|
+
# we encountered a switch so this
|
17
|
+
# value belongs to that switch
|
18
|
+
options[switch] = value
|
19
|
+
switch = nil
|
20
|
+
else
|
21
|
+
rest << value
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
[options, rest]
|
27
|
+
end
|
28
|
+
end
|
data/lib/weblog.rb
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'time'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
require 'rdiscount'
|
6
|
+
require 'erubis'
|
7
|
+
require 'json'
|
8
|
+
require 'git'
|
9
|
+
|
10
|
+
class Weblog
|
11
|
+
autoload :Helpers, "weblog/helpers"
|
12
|
+
autoload :Index, "weblog/index"
|
13
|
+
autoload :Month, "weblog/month"
|
14
|
+
autoload :Snippet, "weblog/snippet"
|
15
|
+
autoload :Post, "weblog/post"
|
16
|
+
|
17
|
+
DIRECTORIES = %w(
|
18
|
+
public/javascripts
|
19
|
+
public/stylesheets
|
20
|
+
draft
|
21
|
+
)
|
22
|
+
|
23
|
+
# --- Utilities
|
24
|
+
|
25
|
+
def self.source_root
|
26
|
+
File.expand_path('../../', __FILE__)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.template_path
|
30
|
+
File.join(source_root, 'templates')
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.find_working_directory(cwd)
|
34
|
+
candidate = cwd
|
35
|
+
while(candidate)
|
36
|
+
directory = File.join(candidate, 'public')
|
37
|
+
if File.exist?(directory)
|
38
|
+
return candidate
|
39
|
+
else
|
40
|
+
parts = candidate.split('/')
|
41
|
+
candidate = parts.empty? ? false : parts[0..-2].join('/')
|
42
|
+
end
|
43
|
+
end; nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize(cwd, options={})
|
47
|
+
@options = options
|
48
|
+
unless @path = self.class.find_working_directory(cwd)
|
49
|
+
puts "[!] Please use this tool from somewhere within the working directory"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def git
|
54
|
+
@git ||= Git.open(@path)
|
55
|
+
end
|
56
|
+
|
57
|
+
def verbose?
|
58
|
+
@options[:verbose]
|
59
|
+
end
|
60
|
+
|
61
|
+
# --- Attributes
|
62
|
+
|
63
|
+
attr_accessor :path
|
64
|
+
|
65
|
+
def title
|
66
|
+
@path.split('/').last.gsub(/[_-]/, ' ').capitalize
|
67
|
+
end
|
68
|
+
|
69
|
+
def months
|
70
|
+
Month.all(self)
|
71
|
+
end
|
72
|
+
|
73
|
+
def posts
|
74
|
+
if @posts.nil?
|
75
|
+
paths = Set.new
|
76
|
+
base_path = File.join(@path, 'public')
|
77
|
+
path_length = base_path.split('/').length
|
78
|
+
Dir.glob(File.join(base_path, '**/post.*')).each do |file|
|
79
|
+
paths << file.split('/')[path_length..-2].join('/')
|
80
|
+
end
|
81
|
+
@posts = paths.map do |path|
|
82
|
+
Weblog::Post.new(self, path)
|
83
|
+
end
|
84
|
+
end; @posts
|
85
|
+
end
|
86
|
+
|
87
|
+
def size
|
88
|
+
posts.size
|
89
|
+
end
|
90
|
+
|
91
|
+
def author
|
92
|
+
git.config('user.name')
|
93
|
+
end
|
94
|
+
|
95
|
+
# --- Commands
|
96
|
+
|
97
|
+
def index
|
98
|
+
Weblog::Index.new(self)
|
99
|
+
end
|
100
|
+
|
101
|
+
def generate
|
102
|
+
posts.each { |post| post.generate }
|
103
|
+
months.each { |month| month.generate }
|
104
|
+
index.generate
|
105
|
+
end
|
106
|
+
|
107
|
+
def publish(*directories)
|
108
|
+
year = Time.now.year.to_s
|
109
|
+
month = "%02d" % Time.now.month
|
110
|
+
directories.each do |directory|
|
111
|
+
name = directory.split('/').last
|
112
|
+
destination = File.join(@path, 'public', year, month, name)
|
113
|
+
FileUtils.mkdir_p(File.dirname(destination))
|
114
|
+
FileUtils.mv(directory, destination)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def print_info
|
119
|
+
months.each do |month|
|
120
|
+
puts "#{month.path}: #{month.size} #{month.size == 1 ? 'post' : 'posts'}"
|
121
|
+
end
|
122
|
+
puts [
|
123
|
+
"Directory: #{@path}",
|
124
|
+
"Title: #{title}",
|
125
|
+
"Author: #{author}",
|
126
|
+
"Total posts: #{size} #{size == 1 ? 'post' : 'posts'}"
|
127
|
+
].join("\n")
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.init(options)
|
131
|
+
DIRECTORIES.each { |path| FileUtils.mkdir_p(path) }
|
132
|
+
unless File.exist?('templates')
|
133
|
+
FileUtils.cp_r(template_path, 'templates')
|
134
|
+
FileUtils.rm_rf('templates/.svn')
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.generate(options)
|
139
|
+
weblog = new(Dir.pwd, options)
|
140
|
+
weblog.generate
|
141
|
+
weblog
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.publish(options, *directories)
|
145
|
+
weblog = new(Dir.pwd, options)
|
146
|
+
weblog.publish(*directories)
|
147
|
+
weblog
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.print_info(options)
|
151
|
+
weblog = new(Dir.pwd, options)
|
152
|
+
weblog.print_info
|
153
|
+
weblog
|
154
|
+
end
|
155
|
+
end
|
data/lib/weblog/index.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
class Weblog
|
2
|
+
class Index
|
3
|
+
SIZE = 5
|
4
|
+
|
5
|
+
def initialize(weblog)
|
6
|
+
@weblog = weblog
|
7
|
+
end
|
8
|
+
|
9
|
+
def posts
|
10
|
+
if @posts.nil?
|
11
|
+
@posts = []
|
12
|
+
@weblog.months.reverse.each do |month|
|
13
|
+
month.posts.each do |post|
|
14
|
+
@posts << post
|
15
|
+
return @posts if @posts.length >= SIZE
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end; @posts
|
19
|
+
end
|
20
|
+
|
21
|
+
# --- Rendering system
|
22
|
+
|
23
|
+
include Weblog::Helpers
|
24
|
+
|
25
|
+
def html_template_filename
|
26
|
+
File.join(@weblog.path, "templates/index.html.erb")
|
27
|
+
end
|
28
|
+
|
29
|
+
def feed_template_filename
|
30
|
+
File.join(@weblog.path, "templates/index.rss.erb")
|
31
|
+
end
|
32
|
+
|
33
|
+
def render(template_filename)
|
34
|
+
Erubis::EscapedEruby.new(
|
35
|
+
File.read(template_filename)
|
36
|
+
).result(binding)
|
37
|
+
end
|
38
|
+
|
39
|
+
def html_filename
|
40
|
+
File.join(@weblog.path, 'public', 'weblog.html')
|
41
|
+
end
|
42
|
+
|
43
|
+
def feed_filename
|
44
|
+
File.join(@weblog.path, 'public', 'weblog.rss')
|
45
|
+
end
|
46
|
+
|
47
|
+
def generate
|
48
|
+
FileUtils.mkdir_p(File.dirname(html_filename))
|
49
|
+
File.open(html_filename, 'w') { |file| file.write(render(html_template_filename)) }
|
50
|
+
puts "Generated weblog index" if @weblog.verbose?
|
51
|
+
FileUtils.mkdir_p(File.dirname(feed_filename))
|
52
|
+
File.open(feed_filename, 'w') { |file| file.write(render(feed_template_filename)) }
|
53
|
+
puts "Generated weblog feed" if @weblog.verbose?
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/weblog/month.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
class Weblog
|
2
|
+
class Month
|
3
|
+
attr_accessor :year, :month
|
4
|
+
|
5
|
+
def initialize(weblog, year, month)
|
6
|
+
@weblog = weblog
|
7
|
+
@year = year.to_i
|
8
|
+
@month = month.to_i
|
9
|
+
@path = File.join(@year.to_s, ("%02d" % @month))
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :path
|
13
|
+
|
14
|
+
# Returns a list of posts for this month in reverse chronological order
|
15
|
+
def posts
|
16
|
+
@weblog.posts.select do |post|
|
17
|
+
post.path.start_with?(@path)
|
18
|
+
end.sort_by { |post| -post.published_at.to_i }
|
19
|
+
end
|
20
|
+
|
21
|
+
def size
|
22
|
+
posts.size
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.all(weblog)
|
26
|
+
months = []
|
27
|
+
Dir.entries(File.join(weblog.path, 'public')).each do |year|
|
28
|
+
if year =~ /^\d{4}$/
|
29
|
+
Dir.entries(File.join(weblog.path, 'public', year)).each do |month|
|
30
|
+
if month =~ /^\d{2}$/
|
31
|
+
months << new(weblog, year, month)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
months.sort_by do |month|
|
37
|
+
[month.year, month.month]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# --- Rendering system
|
42
|
+
|
43
|
+
include Weblog::Helpers
|
44
|
+
|
45
|
+
def template_filename
|
46
|
+
File.join(@weblog.path, "templates/month.html.erb")
|
47
|
+
end
|
48
|
+
|
49
|
+
def render
|
50
|
+
Erubis::EscapedEruby.new(
|
51
|
+
File.read(template_filename)
|
52
|
+
).result(binding)
|
53
|
+
end
|
54
|
+
|
55
|
+
def index_filename
|
56
|
+
File.join(@weblog.path, 'public', @path, 'index.html')
|
57
|
+
end
|
58
|
+
|
59
|
+
def generate
|
60
|
+
FileUtils.mkdir_p(File.dirname(index_filename))
|
61
|
+
File.open(index_filename, 'w') do |file|
|
62
|
+
file.write(render)
|
63
|
+
end
|
64
|
+
puts "Generated #{@year}/#{"%02d" % @month}" if @weblog.verbose?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/weblog/post.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
class Weblog
|
2
|
+
class Post
|
3
|
+
attr_accessor :path
|
4
|
+
|
5
|
+
def initialize(weblog, path)
|
6
|
+
@weblog = weblog
|
7
|
+
@path = path
|
8
|
+
@post = self
|
9
|
+
_load_metadata
|
10
|
+
end
|
11
|
+
|
12
|
+
# --- Metadata
|
13
|
+
|
14
|
+
def metadata_filename
|
15
|
+
File.join(@weblog.path, 'public', @path, 'post.json')
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_writer :author
|
19
|
+
|
20
|
+
def published_at=(published_at)
|
21
|
+
@published_at = Time.parse(published_at)
|
22
|
+
end
|
23
|
+
|
24
|
+
def updated_at=(updated_at)
|
25
|
+
@updated_at = Time.parse(updated_at)
|
26
|
+
end
|
27
|
+
|
28
|
+
def _load_metadata
|
29
|
+
JSON.parse(File.read(metadata_filename)).each do |key, value|
|
30
|
+
self.send("#{key}=", value)
|
31
|
+
end if File.exist?(metadata_filename)
|
32
|
+
end
|
33
|
+
|
34
|
+
# --- Attributes
|
35
|
+
|
36
|
+
def blob
|
37
|
+
if File.exist?(index_filename)
|
38
|
+
@blob ||= @weblog.git.gblob(index_filename)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def last_commit
|
43
|
+
@last_commit ||= blob.log(1).first if blob
|
44
|
+
end
|
45
|
+
|
46
|
+
def first_commit
|
47
|
+
@first_commit ||= blob.log(10_000).map{|l|l}.last if blob
|
48
|
+
end
|
49
|
+
|
50
|
+
def modified?
|
51
|
+
@modified ||= @weblog.git.status.changed.any? do |filename, status|
|
52
|
+
snippet.filename.end_with?(filename)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# * Author:
|
57
|
+
# - When it's in the git repository: first commit author
|
58
|
+
# - Otherwise: configured author
|
59
|
+
def _author
|
60
|
+
if commit = first_commit
|
61
|
+
first_commit.author.name
|
62
|
+
else
|
63
|
+
@weblog.author
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def author
|
68
|
+
@author ||= _author
|
69
|
+
end
|
70
|
+
|
71
|
+
# * The created date:
|
72
|
+
# - When it's not in the git repository: current date and time
|
73
|
+
# - When it's in the git repository: first commit date
|
74
|
+
def _published_at
|
75
|
+
if commit = first_commit
|
76
|
+
commit.date
|
77
|
+
else
|
78
|
+
Time.now
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def published_at
|
83
|
+
@published_at ||= _published_at
|
84
|
+
end
|
85
|
+
|
86
|
+
# * The updated date:
|
87
|
+
# - When it's not in the git repository: nil
|
88
|
+
# - When it has modifications: current date and time
|
89
|
+
# - When it has no modifications: last commit date
|
90
|
+
def _updated_at
|
91
|
+
if modified?
|
92
|
+
Time.now
|
93
|
+
elsif commit = last_commit
|
94
|
+
commit.date
|
95
|
+
else
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def updated_at
|
101
|
+
@updated_at ||= _updated_at
|
102
|
+
end
|
103
|
+
|
104
|
+
def stylesheets
|
105
|
+
Dir.glob(File.join(@weblog.path, 'public', path, '*.css')).map do |path|
|
106
|
+
File.basename(path)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def javascripts
|
111
|
+
Dir.glob(File.join(@weblog.path, 'public', path, '*.js')).map do |path|
|
112
|
+
File.basename(path)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def snippet
|
117
|
+
@snippet ||= Snippet.new(@weblog, self, File.join('public', path))
|
118
|
+
end
|
119
|
+
|
120
|
+
def title
|
121
|
+
snippet.title.strip
|
122
|
+
end
|
123
|
+
|
124
|
+
def content
|
125
|
+
snippet.content
|
126
|
+
end
|
127
|
+
|
128
|
+
# --- Rendering system
|
129
|
+
|
130
|
+
include Weblog::Helpers
|
131
|
+
|
132
|
+
def template_filename
|
133
|
+
File.join(@weblog.path, "templates/post.html.erb")
|
134
|
+
end
|
135
|
+
|
136
|
+
def render
|
137
|
+
Erubis::EscapedEruby.new(
|
138
|
+
File.read(template_filename)
|
139
|
+
).result(binding)
|
140
|
+
end
|
141
|
+
|
142
|
+
def index_filename
|
143
|
+
File.join(@weblog.path, 'public', @path, 'index.html')
|
144
|
+
end
|
145
|
+
|
146
|
+
def generate
|
147
|
+
FileUtils.mkdir_p(File.dirname(index_filename))
|
148
|
+
File.open(index_filename, 'w') do |file|
|
149
|
+
file.write(render)
|
150
|
+
end
|
151
|
+
puts "Generated #{path}" if @weblog.verbose?
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class Weblog
|
2
|
+
class Snippet
|
3
|
+
attr_accessor :path, :filename
|
4
|
+
|
5
|
+
def initialize(weblog, object, path)
|
6
|
+
@weblog = weblog
|
7
|
+
@path = path
|
8
|
+
find_snippet_file
|
9
|
+
end
|
10
|
+
|
11
|
+
def candidates
|
12
|
+
%w(post.md post.html).map do |name|
|
13
|
+
File.join(@weblog.path, @path, name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_snippet_file
|
18
|
+
@filename = candidates.detect do |filename|
|
19
|
+
File.exist?(filename)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def source_type
|
24
|
+
@filename.end_with?('.md') ? :markdown : :html
|
25
|
+
end
|
26
|
+
|
27
|
+
def read
|
28
|
+
@read ||= File.read(filename).split("\n")
|
29
|
+
end
|
30
|
+
|
31
|
+
def title
|
32
|
+
return '' if read.empty?
|
33
|
+
case source_type
|
34
|
+
when :markdown
|
35
|
+
/^#(.*)$/.match(read[0])[1]
|
36
|
+
when :html
|
37
|
+
/<h1>(.*)<\/h1>/.match(read[0])[1]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def content
|
42
|
+
return '' if read.empty?
|
43
|
+
case source_type
|
44
|
+
when :markdown
|
45
|
+
RDiscount.new(read[1..-1].join("\n")).to_html
|
46
|
+
when :html
|
47
|
+
read[1..-1].join("\n")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title><%= @weblog.title %></title>
|
5
|
+
<meta charset="utf-8" />
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<% posts.each do |post| %>
|
9
|
+
<h1><a href="<%= post.path %>"><%= post.title %></a></h1>
|
10
|
+
<%== post.content %>
|
11
|
+
<% end %>
|
12
|
+
</body>
|
13
|
+
</html>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
3
|
+
<channel>
|
4
|
+
<title><%= @weblog.title %></title>
|
5
|
+
<atom:id>http://www.fngtps.com/index.rss</atom:id>
|
6
|
+
<atom:link rel="self" type="application/rss+xml" href="http://www.fngtps.com/index.rss"/>
|
7
|
+
<link>http://www.fngtps.com/index.rss</link>
|
8
|
+
<description>Recent posts on ‘Fingertips’</description>
|
9
|
+
<% unless posts.empty? %>
|
10
|
+
<lastBuildDate><%= (posts.first.updated_at || posts.first.published_at).rfc822 %></lastBuildDate>
|
11
|
+
<% end %>
|
12
|
+
<% posts.each do |post| %><% if post.published_at %>
|
13
|
+
<item>
|
14
|
+
<title><%= post.title %></title>
|
15
|
+
<link>http://www.fngtps.com/<%= post.path %></link>
|
16
|
+
<description><%= post.content %></description>
|
17
|
+
<pubDate><%= post.published_at.rfc822 %></pubDate>
|
18
|
+
<atom:updated><%= (post.updated_at || post.published_at).rfc822 %></atom:updated>
|
19
|
+
<guid>http://www.fngtps.com/<%= post.path %></guid>
|
20
|
+
</item>
|
21
|
+
<% end %><% end %>
|
22
|
+
</channel>
|
23
|
+
</rss>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title><%= @weblog.title %></title>
|
5
|
+
<meta charset="utf-8" />
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<% posts.each do |post| %>
|
9
|
+
<h1><a href="<%= post.path.split('/').last %>"><%= post.title %></a></h1>
|
10
|
+
<%== post.content %>
|
11
|
+
<% end %>
|
12
|
+
</body>
|
13
|
+
</html>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title><%= @weblog.title %></title>
|
5
|
+
<meta charset="utf-8" />
|
6
|
+
<% @post.stylesheets.each do |path| %>
|
7
|
+
<link rel="stylesheet" href="<%= path %>" />
|
8
|
+
<% end %>
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<h1><%= @post.title %></h1>
|
12
|
+
<%== @post.content %>
|
13
|
+
<p><%= @post.author %>, <%= format_date(@post.published_at) %><% if @post.updated_at %>, updated at <%= format_date_and_time(@post.updated_at) %><% end %></p>
|
14
|
+
<% @post.javascripts.each do |path| %>
|
15
|
+
<script src="<%= path %>" type="text/javascript"></script>
|
16
|
+
<% end %>
|
17
|
+
</body>
|
18
|
+
</html>
|
metadata
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fngtps-weblog
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 11
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 5
|
9
|
+
- 0
|
10
|
+
version: 0.5.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Manfred Stienstra
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-11-18 00:00:00 +01:00
|
19
|
+
default_executable: weblog
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rdiscount
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: erubis
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: git
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :runtime
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: json
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
type: :runtime
|
76
|
+
version_requirements: *id004
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: mocha
|
79
|
+
prerelease: false
|
80
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
type: :development
|
90
|
+
version_requirements: *id005
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: test-spec
|
93
|
+
prerelease: false
|
94
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
type: :development
|
104
|
+
version_requirements: *id006
|
105
|
+
description: Weblog tools.
|
106
|
+
email: manfred@fngtps.com
|
107
|
+
executables:
|
108
|
+
- weblog
|
109
|
+
extensions: []
|
110
|
+
|
111
|
+
extra_rdoc_files:
|
112
|
+
- TODO
|
113
|
+
files:
|
114
|
+
- bin/weblog
|
115
|
+
- lib/option_parser.rb
|
116
|
+
- lib/weblog.rb
|
117
|
+
- lib/weblog/helpers.rb
|
118
|
+
- lib/weblog/index.rb
|
119
|
+
- lib/weblog/month.rb
|
120
|
+
- lib/weblog/post.rb
|
121
|
+
- lib/weblog/snippet.rb
|
122
|
+
- templates/index.html.erb
|
123
|
+
- templates/index.rss.erb
|
124
|
+
- templates/month.html.erb
|
125
|
+
- templates/post.html.erb
|
126
|
+
- TODO
|
127
|
+
has_rdoc: true
|
128
|
+
homepage:
|
129
|
+
licenses: []
|
130
|
+
|
131
|
+
post_install_message:
|
132
|
+
rdoc_options:
|
133
|
+
- --charset=UTF-8
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
hash: 3
|
142
|
+
segments:
|
143
|
+
- 0
|
144
|
+
version: "0"
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
none: false
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
hash: 3
|
151
|
+
segments:
|
152
|
+
- 0
|
153
|
+
version: "0"
|
154
|
+
requirements: []
|
155
|
+
|
156
|
+
rubyforge_project:
|
157
|
+
rubygems_version: 1.3.7
|
158
|
+
signing_key:
|
159
|
+
specification_version: 3
|
160
|
+
summary: Weblog tools.
|
161
|
+
test_files: []
|
162
|
+
|