jnicklas-lilliput 0.0.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/LICENSE +20 -0
- data/README.md +51 -0
- data/Rakefile +36 -0
- data/TODO +0 -0
- data/lib/lilliput.rb +122 -0
- data/spec/fixtures/2006-05-12.md +6 -0
- data/spec/fixtures/2008-08-10-monkey.md +14 -0
- data/spec/fixtures/2008-09-12-activerecord-shenanigans.md +12 -0
- data/spec/fixtures/2020-02-03-seek-nirvana.md +4 -0
- data/spec/lilliput_spec.rb +76 -0
- data/spec/post_spec.rb +101 -0
- data/spec/spec_helper.rb +9 -0
- metadata +67 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Jonas Nicklas
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
Lilliput
|
2
|
+
======
|
3
|
+
|
4
|
+
Lilliput is a blogging engine so minimalistic, it doesn't even include a webframework.
|
5
|
+
|
6
|
+
You can use Lilliput with Sinatra like this:
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'sinatra'
|
10
|
+
require 'lilliput'
|
11
|
+
|
12
|
+
Lilliput.folder = File.join(File.dirname(__FILE__), 'posts')
|
13
|
+
|
14
|
+
get '/' do
|
15
|
+
@posts = Lilliput.all
|
16
|
+
erb :index
|
17
|
+
end
|
18
|
+
|
19
|
+
get '/:slug' do
|
20
|
+
@post = Lilliput.find(params[:slug])
|
21
|
+
erb :show
|
22
|
+
end
|
23
|
+
|
24
|
+
This will serve markdown files from the ./posts folder. The name of the markdown file must
|
25
|
+
contain a date, an may contain a slug, where the post is accessible
|
26
|
+
|
27
|
+
2009-02-14.md
|
28
|
+
2009-02-14-my-first-lilliput-post.md
|
29
|
+
|
30
|
+
The first line of the post is used as title. If there is no slug in the filename, the title
|
31
|
+
is parameterized and used. The markdown file can contain an optional author annotation like this:
|
32
|
+
|
33
|
+
/ Jonas Nicklas <jonas.nicklas@gmail.com
|
34
|
+
|
35
|
+
It must be the last line of the file.
|
36
|
+
|
37
|
+
In your view, you can do something like this:
|
38
|
+
|
39
|
+
<% @posts.each do |post| %>
|
40
|
+
<h1><%= post.title %><
|
41
|
+
|
42
|
+
<p class="date"><%= post.published_at %></p>
|
43
|
+
|
44
|
+
<%= @post.html %>
|
45
|
+
<% end %>
|
46
|
+
|
47
|
+
There's also
|
48
|
+
|
49
|
+
Lilliput.published
|
50
|
+
|
51
|
+
which will find only those posts with a date that is in the past.
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
|
4
|
+
GEM_NAME = "lilliput"
|
5
|
+
GEM_VERSION = "0.0.1"
|
6
|
+
AUTHOR = "Jonas Nicklas"
|
7
|
+
EMAIL = "jonas.nicklas@gmail.com"
|
8
|
+
HOMEPAGE = "http://www.example.com"
|
9
|
+
SUMMARY = "Super simple blogging engine"
|
10
|
+
|
11
|
+
spec = Gem::Specification.new do |s|
|
12
|
+
s.rubyforge_project = 'lilliput'
|
13
|
+
s.name = GEM_NAME
|
14
|
+
s.version = GEM_VERSION
|
15
|
+
s.platform = Gem::Platform::RUBY
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.extra_rdoc_files = ["README.md", "LICENSE", 'TODO']
|
18
|
+
s.summary = SUMMARY
|
19
|
+
s.description = s.summary
|
20
|
+
s.author = AUTHOR
|
21
|
+
s.email = EMAIL
|
22
|
+
s.homepage = HOMEPAGE
|
23
|
+
s.require_path = 'lib'
|
24
|
+
s.files = %w(LICENSE README.md Rakefile TODO) + Dir.glob("{lib,spec}/**/*")
|
25
|
+
end
|
26
|
+
|
27
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
28
|
+
pkg.gem_spec = spec
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "Create a gemspec file"
|
32
|
+
task :gemspec do
|
33
|
+
File.open("#{GEM_NAME}.gemspec", "w") do |file|
|
34
|
+
file.puts spec.to_ruby
|
35
|
+
end
|
36
|
+
end
|
data/TODO
ADDED
File without changes
|
data/lib/lilliput.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'maruku'
|
2
|
+
|
3
|
+
module Lilliput
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
attr_accessor :folder, :author, :email, :show_unpublished
|
8
|
+
|
9
|
+
def all
|
10
|
+
files = Dir.glob(File.join(folder, '*')).reverse
|
11
|
+
posts = files.map { |f| Post.new(f) }
|
12
|
+
posts = posts.select { |p| p.published? } unless Lilliput.show_unpublished
|
13
|
+
posts
|
14
|
+
end
|
15
|
+
|
16
|
+
def find(slug)
|
17
|
+
all.select{ |p| p.slug == slug }.first
|
18
|
+
end
|
19
|
+
|
20
|
+
def first
|
21
|
+
all.first
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
class Post
|
27
|
+
|
28
|
+
def initialize(path)
|
29
|
+
@path = path
|
30
|
+
end
|
31
|
+
|
32
|
+
def published_on
|
33
|
+
date = filename.match(/^([\d]{4}-[\d]{2}-[\d]{2})/)[1]
|
34
|
+
Date.parse(date) if date
|
35
|
+
end
|
36
|
+
|
37
|
+
def published?
|
38
|
+
published_on < Date.today
|
39
|
+
end
|
40
|
+
|
41
|
+
def title
|
42
|
+
lines.first.chomp
|
43
|
+
end
|
44
|
+
|
45
|
+
def author
|
46
|
+
credentials[0] || Lilliput.author
|
47
|
+
end
|
48
|
+
|
49
|
+
def email
|
50
|
+
credentials[1] || Lilliput.email
|
51
|
+
end
|
52
|
+
|
53
|
+
def slug
|
54
|
+
slug = filename.match(/^[\d]{4}-[\d]{2}-[\d]{2}-([a-z0-9\-]+)/i)
|
55
|
+
if slug
|
56
|
+
slug[1]
|
57
|
+
else
|
58
|
+
lines.first.downcase.gsub(/[^a-z0-9\-]/, '-').gsub(/^\-*(.*?)\-*$/, '\1')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def content
|
63
|
+
strip_off_blank_lines(lines[1..-1]).join("\n")
|
64
|
+
end
|
65
|
+
|
66
|
+
def html
|
67
|
+
Maruku.new(content).to_html
|
68
|
+
end
|
69
|
+
|
70
|
+
def previous
|
71
|
+
Lilliput.all[post_nr + 1]
|
72
|
+
end
|
73
|
+
|
74
|
+
def next
|
75
|
+
Lilliput.all[post_nr - 1] unless post_nr <= 0
|
76
|
+
end
|
77
|
+
|
78
|
+
def ==(other_post)
|
79
|
+
slug == other_post.slug
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def post_nr
|
85
|
+
Lilliput.all.map { |p| p.slug == slug }.index(true)
|
86
|
+
end
|
87
|
+
|
88
|
+
def strip_off_blank_lines(lines)
|
89
|
+
until lines.first =~ /[^\s=]/ or lines.empty?
|
90
|
+
lines.shift
|
91
|
+
end
|
92
|
+
until lines.last =~ /[^\s=]/ or lines.empty?
|
93
|
+
lines.pop
|
94
|
+
end
|
95
|
+
lines
|
96
|
+
end
|
97
|
+
|
98
|
+
def read
|
99
|
+
File.read(@path)
|
100
|
+
end
|
101
|
+
|
102
|
+
def credentials
|
103
|
+
match = lines.last.match(/\/(.*?)(?:<(.*?)>)?[\s]*$/)
|
104
|
+
if match
|
105
|
+
author = match[1].strip
|
106
|
+
email = match[2].strip
|
107
|
+
return [author, email]
|
108
|
+
end
|
109
|
+
[nil, nil]
|
110
|
+
end
|
111
|
+
|
112
|
+
def lines
|
113
|
+
Array(read)
|
114
|
+
end
|
115
|
+
|
116
|
+
def filename
|
117
|
+
File.basename(@path)
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Monkey
|
2
|
+
======
|
3
|
+
|
4
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
|
5
|
+
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
|
6
|
+
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
|
7
|
+
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
|
8
|
+
deserunt mollit anim id est laborum.
|
9
|
+
|
10
|
+
Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
|
11
|
+
enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
12
|
+
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
|
13
|
+
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit
|
14
|
+
anim id est laborum.
|
@@ -0,0 +1,12 @@
|
|
1
|
+
How to Cheat at AR
|
2
|
+
==================
|
3
|
+
|
4
|
+
Irure dolor in reprehenderit in voluptate velit esse cillum dolore
|
5
|
+
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
|
6
|
+
deserunt mollit anim id est laborum.
|
7
|
+
|
8
|
+
Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
|
9
|
+
enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
10
|
+
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
|
11
|
+
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit
|
12
|
+
anim id est laborum.
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Lilliput do
|
4
|
+
|
5
|
+
before do
|
6
|
+
Lilliput.folder = fixture_path
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '.all' do
|
10
|
+
it "should return a list of published posts" do
|
11
|
+
all = Lilliput.all
|
12
|
+
all.map! { |p| p.slug }
|
13
|
+
all.should include('monkey')
|
14
|
+
all.should_not include('seek-nirvana')
|
15
|
+
all.should include('activerecord-shenanigans')
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should return a list of all posts if show_unpublished is true" do
|
19
|
+
Lilliput.show_unpublished = true
|
20
|
+
all = Lilliput.all
|
21
|
+
all.map! { |p| p.slug }
|
22
|
+
all.should include('monkey')
|
23
|
+
all.should include('seek-nirvana')
|
24
|
+
all.should include('activerecord-shenanigans')
|
25
|
+
Lilliput.show_unpublished = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should sort by date in a descending order" do
|
29
|
+
all = Lilliput.all
|
30
|
+
all.map! { |p| p.slug }
|
31
|
+
all.should == ['activerecord-shenanigans', 'monkey', 'hostile-takeover']
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '.find' do
|
36
|
+
it "should be nil if the slug doesn't exit" do
|
37
|
+
Lilliput.find('hello-world').should be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it "only find published posts" do
|
41
|
+
Lilliput.find('seek-nirvana').should be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it "find unpublished posts if show_unpublished is true" do
|
45
|
+
Lilliput.show_unpublished = true
|
46
|
+
Lilliput.find('seek-nirvana').should_not be_nil
|
47
|
+
Lilliput.show_unpublished = nil
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should return a post" do
|
51
|
+
post = Lilliput.find('activerecord-shenanigans')
|
52
|
+
post.slug.should == 'activerecord-shenanigans'
|
53
|
+
post.published_on.should == Date.civil(2008, 9, 12)
|
54
|
+
post.title.should == 'How to Cheat at AR'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'first' do
|
59
|
+
it "should return the first published post" do
|
60
|
+
post = Lilliput.first
|
61
|
+
post.slug.should == 'activerecord-shenanigans'
|
62
|
+
post.published_on.should == Date.civil(2008, 9, 12)
|
63
|
+
post.title.should == 'How to Cheat at AR'
|
64
|
+
end
|
65
|
+
|
66
|
+
it "return an unpublished post if show_unpublished is true" do
|
67
|
+
Lilliput.show_unpublished = true
|
68
|
+
post = Lilliput.first
|
69
|
+
post.slug.should == 'seek-nirvana'
|
70
|
+
Lilliput.show_unpublished = nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
end
|
data/spec/post_spec.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Lilliput::Post do
|
4
|
+
|
5
|
+
before do
|
6
|
+
Lilliput.author = 'Monkey Boy'
|
7
|
+
Lilliput.email = 'monkey@example.com'
|
8
|
+
Lilliput.folder = fixture_path
|
9
|
+
|
10
|
+
@shenanigans = Lilliput::Post.new fixture_path('2008-09-12-activerecord-shenanigans.md')
|
11
|
+
@nirvana = Lilliput::Post.new fixture_path('2020-02-03-seek-nirvana.md')
|
12
|
+
@hostile = Lilliput::Post.new fixture_path('2006-05-12.md')
|
13
|
+
@monkey = Lilliput::Post.new fixture_path('2008-08-10-monkey.md')
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#author' do
|
17
|
+
it "should get the author from the last line" do
|
18
|
+
@hostile.author.should == 'Jonas Nicklas'
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should get the author from lilliput if there isn't on in the post" do
|
22
|
+
@shenanigans.author.should == 'Monkey Boy'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#email' do
|
27
|
+
it "should get the email from the last line" do
|
28
|
+
@hostile.email.should == 'jonas.nicklas@gmail.com'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should get the email from lilliput if there isn't on in the post" do
|
32
|
+
@shenanigans.email.should == 'monkey@example.com'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#published_on' do
|
37
|
+
it "should get the date from the filename" do
|
38
|
+
@shenanigans.published_on.should == Date.civil(2008, 9, 12)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#slug' do
|
43
|
+
it "should get the slug from the filename" do
|
44
|
+
@shenanigans.slug.should == 'activerecord-shenanigans'
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should get the slug from the first line if not in filename" do
|
48
|
+
@hostile.slug.should == 'hostile-takeover'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#title' do
|
53
|
+
it "should get the title from the first line" do
|
54
|
+
@shenanigans.title.should == 'How to Cheat at AR'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#contents' do
|
59
|
+
it "should get the contents without the title" do
|
60
|
+
@shenanigans.content.should =~ /^Irure dolor/
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#html' do
|
65
|
+
it "should transform the contents to html" do
|
66
|
+
@shenanigans.html.should =~ /<p>Irure dolor/
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#published?' do
|
71
|
+
it "should be true if the published on date is in the past" do
|
72
|
+
@shenanigans.should be_published
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should be false if the published on date is in the future" do
|
76
|
+
@nirvana.should_not be_published
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#previous' do
|
81
|
+
it "should return the previous published post" do
|
82
|
+
@shenanigans.previous.should == @monkey
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should be nil if there isn't one" do
|
86
|
+
@hostile.previous.should be_nil
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe '#next' do
|
91
|
+
it "should return the next published post" do
|
92
|
+
@hostile.next.should == @monkey
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should be nil if there isn't one" do
|
96
|
+
p @shenanigans.next
|
97
|
+
@shenanigans.next.should be_nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jnicklas-lilliput
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jonas Nicklas
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-03-20 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Super simple blogging engine
|
17
|
+
email: jonas.nicklas@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.md
|
24
|
+
- LICENSE
|
25
|
+
- TODO
|
26
|
+
files:
|
27
|
+
- LICENSE
|
28
|
+
- README.md
|
29
|
+
- Rakefile
|
30
|
+
- TODO
|
31
|
+
- lib/lilliput.rb
|
32
|
+
- spec/fixtures
|
33
|
+
- spec/fixtures/2006-05-12.md
|
34
|
+
- spec/fixtures/2008-08-10-monkey.md
|
35
|
+
- spec/fixtures/2008-09-12-activerecord-shenanigans.md
|
36
|
+
- spec/fixtures/2020-02-03-seek-nirvana.md
|
37
|
+
- spec/lilliput_spec.rb
|
38
|
+
- spec/post_spec.rb
|
39
|
+
- spec/spec_helper.rb
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: http://www.example.com
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project: lilliput
|
62
|
+
rubygems_version: 1.2.0
|
63
|
+
signing_key:
|
64
|
+
specification_version: 2
|
65
|
+
summary: Super simple blogging engine
|
66
|
+
test_files: []
|
67
|
+
|