korma 1.0.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/bin/korma +236 -0
- data/korma.gemspec +23 -0
- metadata +90 -0
data/bin/korma
ADDED
@@ -0,0 +1,236 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'redcloth'
|
5
|
+
require "builder"
|
6
|
+
require "fileutils"
|
7
|
+
require "erb"
|
8
|
+
require 'digest/md5'
|
9
|
+
require "pathname"
|
10
|
+
require "time"
|
11
|
+
|
12
|
+
KORMA_DIR = File.expand_path(File.dirname(__FILE__))
|
13
|
+
|
14
|
+
module Korma
|
15
|
+
module Blog
|
16
|
+
|
17
|
+
include FileUtils
|
18
|
+
|
19
|
+
class Entry
|
20
|
+
def initialize(file, author="")
|
21
|
+
entry_data = Blog.parse_entry(file.read)
|
22
|
+
|
23
|
+
@filename = "#{file.basename}.html"
|
24
|
+
@author = Blog.authors[author]
|
25
|
+
@title = entry_data[:title]
|
26
|
+
@description = entry_data[:description]
|
27
|
+
@entry = entry_data[:entry]
|
28
|
+
@published_date = entry_data[:timestamp]
|
29
|
+
@url = "/#{@author.base_path}#{@filename}"
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :title, :description, :entry, :published_date, :url, :author, :filename
|
33
|
+
end
|
34
|
+
|
35
|
+
class Author
|
36
|
+
|
37
|
+
def initialize(account, name, email, guest)
|
38
|
+
@account, @name, @email, @guest = account, name, email, guest
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_reader :account, :name, :email, :guest
|
42
|
+
|
43
|
+
def base_path
|
44
|
+
"posts/#{account}/"
|
45
|
+
end
|
46
|
+
|
47
|
+
def index_uri
|
48
|
+
"/#{base_path}index.html"
|
49
|
+
end
|
50
|
+
|
51
|
+
def bio_uri
|
52
|
+
"/about/#{account}.html"
|
53
|
+
end
|
54
|
+
|
55
|
+
def feed_uri
|
56
|
+
"/feed/#{account}.xml"
|
57
|
+
end
|
58
|
+
|
59
|
+
def gravatar(size=80)
|
60
|
+
"http://www.gravatar.com/avatar/#{Digest::MD5.hexdigest(email)}?s=#{size}"
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
extend self
|
66
|
+
attr_accessor :repository, :www_dir, :title, :domain, :description
|
67
|
+
attr_reader :authors
|
68
|
+
|
69
|
+
def authors=(data)
|
70
|
+
@authors = {}
|
71
|
+
|
72
|
+
data.each do |k,v|
|
73
|
+
@authors[k] = Author.new(k, v['name'], v['email'], v['guest'])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def normalize_path(path)
|
78
|
+
path.gsub(%r{/+},"/")
|
79
|
+
end
|
80
|
+
|
81
|
+
def parse_entry(entry)
|
82
|
+
entry =~ /=title(.*)=timestamp(.*)=description(.*)=entry(.*)/m
|
83
|
+
{ :title => $1.strip, :description => $3.strip,
|
84
|
+
:entry => $4.strip, :timestamp => Time.parse($2) }
|
85
|
+
end
|
86
|
+
|
87
|
+
def author_names
|
88
|
+
authors.keys
|
89
|
+
end
|
90
|
+
|
91
|
+
def all_entries
|
92
|
+
entries = []
|
93
|
+
author_names.each do |a|
|
94
|
+
entries.concat entries_for_author(a)
|
95
|
+
end
|
96
|
+
entries.sort! { |a,b| b.published_date <=> a.published_date }
|
97
|
+
end
|
98
|
+
|
99
|
+
def site_feed
|
100
|
+
to_rss(all_entries)
|
101
|
+
end
|
102
|
+
|
103
|
+
def entries_for_author(author)
|
104
|
+
tree = Pathname.glob "#{repository}/posts/#{author}/*"
|
105
|
+
return [] unless tree
|
106
|
+
tree.select { |e| e.file? }.map { |e| Entry.new(e, author) }
|
107
|
+
end
|
108
|
+
|
109
|
+
def feed(author)
|
110
|
+
to_rss entries_for_author(author).sort { |a,b| b.published_date <=> a.published_date }
|
111
|
+
end
|
112
|
+
|
113
|
+
def author_index(author)
|
114
|
+
@author = authors[author]
|
115
|
+
@entries = entries_for_author(author).sort { |a,b| b.published_date <=> a.published_date }
|
116
|
+
erb :author_index
|
117
|
+
end
|
118
|
+
|
119
|
+
def site_index
|
120
|
+
@entries = Korma::Blog.all_entries
|
121
|
+
erb :index
|
122
|
+
end
|
123
|
+
|
124
|
+
def bio(author)
|
125
|
+
@author = Korma::Blog.authors[author]
|
126
|
+
file = repository + "about/#{author}"
|
127
|
+
|
128
|
+
layout { RedCloth.new(ERB.new(file.read).result(binding)).to_html }
|
129
|
+
end
|
130
|
+
|
131
|
+
def update_stylesheet
|
132
|
+
file = repository + "styles.css"
|
133
|
+
|
134
|
+
if file.exist?
|
135
|
+
write "styles.css", file.read
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def layout
|
140
|
+
file = repository + "layout.erb"
|
141
|
+
|
142
|
+
if file.exist?
|
143
|
+
ERB.new(file.read).result(binding)
|
144
|
+
else
|
145
|
+
yield
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def generate_static_files
|
150
|
+
# fix relative path names
|
151
|
+
self.repository = repository.realpath unless repository.absolute?
|
152
|
+
|
153
|
+
mkdir_p www_dir
|
154
|
+
cd www_dir
|
155
|
+
write "feed.xml", site_feed
|
156
|
+
|
157
|
+
write 'index.html', site_index
|
158
|
+
|
159
|
+
mkdir_p "feed"
|
160
|
+
mkdir_p "about"
|
161
|
+
|
162
|
+
about = repository + "about/index"
|
163
|
+
|
164
|
+
if about.exist?
|
165
|
+
write "about/index.html", layout { RedCloth.new(about.read).to_html }
|
166
|
+
end
|
167
|
+
|
168
|
+
update_stylesheet
|
169
|
+
|
170
|
+
author_names.each do |author|
|
171
|
+
write "feed/#{author}.xml", feed(author)
|
172
|
+
mkdir_p "posts/#{author}"
|
173
|
+
write "posts/#{author}/index.html", author_index(author)
|
174
|
+
entries_for_author(author).each do |e|
|
175
|
+
@post = e
|
176
|
+
@author = authors[author]
|
177
|
+
@contents = RedCloth.new(e.entry).to_html
|
178
|
+
write "posts/#{author}/#{e.filename}", erb(:post)
|
179
|
+
end
|
180
|
+
write "about/#{author}.html", bio(author)
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
|
185
|
+
def write(file, contents)
|
186
|
+
File.open(file, "w") { |f| f << contents }
|
187
|
+
end
|
188
|
+
|
189
|
+
def erb(file)
|
190
|
+
file = repository + "views/#{file}.erb"
|
191
|
+
|
192
|
+
if File.exist? file
|
193
|
+
engine = ERB.new(file.read)
|
194
|
+
layout { engine.result(binding) }
|
195
|
+
else
|
196
|
+
raise "File not found #{file}"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def to_rss(entries)
|
201
|
+
xml = Builder::XmlMarkup.new
|
202
|
+
xml.instruct!
|
203
|
+
xml.rss :version => "2.0" do
|
204
|
+
xml.channel do
|
205
|
+
xml.title title
|
206
|
+
xml.link "http://#{domain}/"
|
207
|
+
xml.description description
|
208
|
+
xml.language "en-us"
|
209
|
+
|
210
|
+
entries.each do |entry|
|
211
|
+
xml.item do
|
212
|
+
xml.title entry.title.gsub( %r{</?[^>]+?>}, '' )
|
213
|
+
xml.description RedCloth.new(entry.entry).to_html
|
214
|
+
xml.author "#{entry.author.email} (#{entry.author.name})"
|
215
|
+
xml.pubDate entry.published_date.rfc822
|
216
|
+
xml.link "http://#{domain}#{entry.url}"
|
217
|
+
xml.guid "http://#{domain}#{entry.url}"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
Korma::Blog.repository = Pathname.new(ARGV[0] || ".")
|
228
|
+
config = YAML.load((Korma::Blog.repository + "korma_config.yml").read)
|
229
|
+
|
230
|
+
Korma::Blog.title = config['title']
|
231
|
+
Korma::Blog.domain = config['domain']
|
232
|
+
Korma::Blog.description = config['description']
|
233
|
+
Korma::Blog.authors = config['authors']
|
234
|
+
Korma::Blog.www_dir = ARGV[1] || "public"
|
235
|
+
|
236
|
+
Korma::Blog.generate_static_files
|
data/korma.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
KORMA_VERSION = "1.0.0"
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "korma"
|
5
|
+
spec.version = KORMA_VERSION
|
6
|
+
spec.platform = Gem::Platform::RUBY
|
7
|
+
spec.summary = "A static site generator for bloggers with multiple author support"
|
8
|
+
spec.files = Dir.glob("{bin,lib}/*") + ["korma.gemspec"]
|
9
|
+
spec.require_path = "lib"
|
10
|
+
spec.bindir = "bin"
|
11
|
+
spec.executables << "korma"
|
12
|
+
|
13
|
+
spec.test_files = Dir[ "test/*_test.rb" ]
|
14
|
+
spec.has_rdoc = false
|
15
|
+
spec.author = "Gregory Brown"
|
16
|
+
spec.email = " gregory.t.brown@gmail.com"
|
17
|
+
spec.add_dependency('builder')
|
18
|
+
spec.add_dependency('RedCloth')
|
19
|
+
spec.homepage = "http://prawn.majesticseacreature.com"
|
20
|
+
spec.description = <<END_DESC
|
21
|
+
A static site generator for bloggers with multiple author support
|
22
|
+
END_DESC
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: korma
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 1.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Gregory Brown
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-02-26 00:00:00 -05:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: builder
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: RedCloth
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :runtime
|
45
|
+
version_requirements: *id002
|
46
|
+
description: " A static site generator for bloggers with multiple author support\n"
|
47
|
+
email: " gregory.t.brown@gmail.com"
|
48
|
+
executables:
|
49
|
+
- korma
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
extra_rdoc_files: []
|
53
|
+
|
54
|
+
files:
|
55
|
+
- bin/korma
|
56
|
+
- korma.gemspec
|
57
|
+
has_rdoc: true
|
58
|
+
homepage: http://prawn.majesticseacreature.com
|
59
|
+
licenses: []
|
60
|
+
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 1.3.7
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: A static site generator for bloggers with multiple author support
|
89
|
+
test_files: []
|
90
|
+
|