retter 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/Rakefile +0 -0
- data/bin/retter +13 -0
- data/lib/generator/newretter.rb +62 -0
- data/lib/generator/skel/.gitignore +2 -0
- data/lib/generator/skel/Gemfile +5 -0
- data/lib/generator/skel/Retterfile +6 -0
- data/lib/generator/skel/config.ru +28 -0
- data/lib/generator/skel/entries/.gitkeep +0 -0
- data/lib/generator/skel/images/.gitkeep +0 -0
- data/lib/generator/skel/index.html +1 -0
- data/lib/generator/skel/javascripts/.gitkeep +0 -0
- data/lib/generator/skel/layouts/entries.html.haml +9 -0
- data/lib/generator/skel/layouts/entry.html.haml +4 -0
- data/lib/generator/skel/layouts/index.html.haml +7 -0
- data/lib/generator/skel/layouts/profile.html.haml +6 -0
- data/lib/generator/skel/layouts/retter.html.haml +25 -0
- data/lib/generator/skel/retters/.gitkeep +0 -0
- data/lib/generator/skel/stylesheets/application.css +114 -0
- data/lib/retter/command.rb +74 -0
- data/lib/retter/config.rb +89 -0
- data/lib/retter/entry.rb +37 -0
- data/lib/retter/stationery/binder.rb +130 -0
- data/lib/retter/stationery/previewer.rb +59 -0
- data/lib/retter/stationery/renderer.rb +9 -0
- data/lib/retter/stationery/view.rb +52 -0
- data/lib/retter/stationery.rb +47 -0
- data/lib/retter/version.rb +3 -0
- data/lib/retter.rb +25 -0
- data/retter.gemspec +34 -0
- data/spec/command/edit_spec.rb +52 -0
- data/spec/command/preview_spec.rb +43 -0
- data/spec/command/rebind_spec.rb +53 -0
- data/spec/spec_helper.rb +37 -0
- metadata +217 -0
data/.gitignore
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
*.gem
|
2
|
+
.bundle
|
3
|
+
Gemfile.lock
|
4
|
+
pkg/*
|
5
|
+
.rvmrc
|
6
|
+
lib/generator/skel/.gitignore
|
7
|
+
lib/generator/skel/.preview.html
|
8
|
+
lib/generator/skel/retters/*.md
|
9
|
+
lib/generator/skel/tmp/*
|
10
|
+
lib/generator/skel/entries.*
|
11
|
+
lib/generator/skel/entries/*.html
|
12
|
+
lib/generator/skel/vendor
|
13
|
+
tmp
|
14
|
+
.DS_Store
|
data/Gemfile
ADDED
data/Rakefile
ADDED
File without changes
|
data/bin/retter
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'thor/group'
|
4
|
+
require 'grit'
|
5
|
+
require 'bundler'
|
6
|
+
require 'bundler/cli'
|
7
|
+
|
8
|
+
class Newretter < Thor::Group
|
9
|
+
FILES = %w(
|
10
|
+
.gitignore
|
11
|
+
Gemfile
|
12
|
+
Retterfile
|
13
|
+
config.ru
|
14
|
+
layouts/entries.html.haml
|
15
|
+
layouts/entry.html.haml
|
16
|
+
layouts/profile.html.haml
|
17
|
+
layouts/index.html.haml
|
18
|
+
layouts/retter.html.haml
|
19
|
+
images/.gitkeep
|
20
|
+
index.html
|
21
|
+
entries/.gitkeep
|
22
|
+
javascripts/.gitkeep
|
23
|
+
stylesheets/application.css
|
24
|
+
retters/.gitkeep
|
25
|
+
)
|
26
|
+
|
27
|
+
include Thor::Actions
|
28
|
+
|
29
|
+
argument :name
|
30
|
+
|
31
|
+
def self.source_root
|
32
|
+
File.dirname(__FILE__)
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_files
|
36
|
+
FILES.each do |file|
|
37
|
+
template("skel/#{file}", "#{name}/#{file}")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def bundle_install
|
42
|
+
pwd = Dir.pwd
|
43
|
+
FileUtils.cd name
|
44
|
+
|
45
|
+
Bundler::CLI.new.install
|
46
|
+
|
47
|
+
FileUtils.cd pwd
|
48
|
+
end
|
49
|
+
|
50
|
+
def git_init
|
51
|
+
Grit::Repo.init "#{Dir.pwd}/#{name}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def notice_how_to_use
|
55
|
+
say <<-EOM, :green
|
56
|
+
-- Thanks for flying Retter :-> --
|
57
|
+
You have to set $RETTER_HOME variable to use #{name}.
|
58
|
+
example:
|
59
|
+
export RETTER_HOME=#{Dir.pwd}/#{name}
|
60
|
+
EOM
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rack'
|
2
|
+
|
3
|
+
use Rack::Static, root: '.', urls: %w(
|
4
|
+
/index.html
|
5
|
+
/profile.html
|
6
|
+
/entries.html
|
7
|
+
/entries.rss
|
8
|
+
/favicon.png
|
9
|
+
/entries
|
10
|
+
/stylesheets
|
11
|
+
/javascripts
|
12
|
+
/images
|
13
|
+
)
|
14
|
+
|
15
|
+
map '/' do
|
16
|
+
run ->(env) {
|
17
|
+
if env['PATH_INFO'] == '/'
|
18
|
+
[
|
19
|
+
200,
|
20
|
+
{'Content-Type' => 'text/html', 'Cache-Control' => 'public, max-age=86400'},
|
21
|
+
File.open('index.html', File::RDONLY)
|
22
|
+
]
|
23
|
+
else
|
24
|
+
[404, {'Content-Type' => 'text/plain'}, ['Not Found']]
|
25
|
+
end
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
:-)
|
File without changes
|
@@ -0,0 +1,25 @@
|
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%title= config.title
|
5
|
+
%meta{:'http-equiv' => 'Content-Type', content: 'text/html', charset: 'utf-8'}
|
6
|
+
%link{rel: 'icon', type: 'image/png', href: '/favicon.png'}
|
7
|
+
%link{href: '/stylesheets/application.css', media: 'screen', rel: 'stylesheet', type: 'text/css'}
|
8
|
+
%link{rel: 'alternate', type: 'application/rss+xml', title: 'RSS', href: '/entries.rss'}
|
9
|
+
%body
|
10
|
+
#header
|
11
|
+
%h1
|
12
|
+
%a{href: '/'}= config.title
|
13
|
+
%ul#menu
|
14
|
+
%li
|
15
|
+
%a{href: '/'} Home
|
16
|
+
%li
|
17
|
+
%a{href: '/profile.html'} Profile
|
18
|
+
%li
|
19
|
+
%a{href: '/entries.html'} Archives
|
20
|
+
%li
|
21
|
+
%a{href: '/entries.rss'} RSS
|
22
|
+
#page
|
23
|
+
#content= content
|
24
|
+
#footer
|
25
|
+
#{config.title} (C) #{config.author}
|
File without changes
|
@@ -0,0 +1,114 @@
|
|
1
|
+
html {
|
2
|
+
height: 100%;
|
3
|
+
}
|
4
|
+
|
5
|
+
body {
|
6
|
+
margin: 0 auto 0 auto;
|
7
|
+
padding: 0;
|
8
|
+
font-family: sans-serif;
|
9
|
+
/*lbackground: rgb(55,65,60);*/
|
10
|
+
background: #EEE;
|
11
|
+
height: 100%;
|
12
|
+
}
|
13
|
+
|
14
|
+
ul {
|
15
|
+
list-style: none;
|
16
|
+
}
|
17
|
+
|
18
|
+
a {
|
19
|
+
text-decoration: none;
|
20
|
+
color: rgb(25,30,10);
|
21
|
+
}
|
22
|
+
|
23
|
+
#header {
|
24
|
+
width: 100%;
|
25
|
+
padding: 0;
|
26
|
+
margin: 0;
|
27
|
+
}
|
28
|
+
|
29
|
+
#header h1 {
|
30
|
+
width: 100%;
|
31
|
+
margin: 0;
|
32
|
+
padding: 0.2em 0 0.2em 1em;
|
33
|
+
background: rgb(25,30,10);
|
34
|
+
color: rgb(77,144,253);
|
35
|
+
}
|
36
|
+
|
37
|
+
#header h1 a {
|
38
|
+
color: rgb(77,144,253);
|
39
|
+
}
|
40
|
+
|
41
|
+
#header ul#menu {
|
42
|
+
margin: 0.5em 0 3em 0;
|
43
|
+
padding: 0 0 0 2em;
|
44
|
+
background: #FFF;
|
45
|
+
}
|
46
|
+
|
47
|
+
#header ul#menu li {
|
48
|
+
float: left;
|
49
|
+
margin-right: 1em;
|
50
|
+
}
|
51
|
+
|
52
|
+
#page {
|
53
|
+
clear: both;
|
54
|
+
margin: 0 auto 0 auto;
|
55
|
+
width: 800px;
|
56
|
+
position: relative;
|
57
|
+
min-height: 100%;
|
58
|
+
}
|
59
|
+
|
60
|
+
article {
|
61
|
+
background: rgb(228,239,192);
|
62
|
+
color: rgb(0,30,67);
|
63
|
+
border-radius: 20px;
|
64
|
+
border: 3px rgb(25,30,10) solid;
|
65
|
+
-moz-border-radius: 20px;
|
66
|
+
-webkit-border-radius: 20px;
|
67
|
+
padding: 1em 1.5em 1em 1.5em;
|
68
|
+
margin: 1em 0 1em 0;
|
69
|
+
width 100%;
|
70
|
+
}
|
71
|
+
|
72
|
+
article h1 {
|
73
|
+
margin-top: 2em;
|
74
|
+
}
|
75
|
+
|
76
|
+
article h1.date {
|
77
|
+
font-size: 1em;
|
78
|
+
text-align: right;
|
79
|
+
margin-top: 0.5em;
|
80
|
+
margin-bottom: -2em;
|
81
|
+
}
|
82
|
+
|
83
|
+
article ul#entries > li {
|
84
|
+
margin-top: 1em;
|
85
|
+
}
|
86
|
+
|
87
|
+
article ul#entries {
|
88
|
+
line-height: 1.5em;
|
89
|
+
}
|
90
|
+
|
91
|
+
#entries {
|
92
|
+
width 100%;
|
93
|
+
}
|
94
|
+
|
95
|
+
pre {
|
96
|
+
background: #EEE;
|
97
|
+
color: rgb(0,30,67);
|
98
|
+
padding: 1em;
|
99
|
+
border-radius: 10px;
|
100
|
+
border: 1px #000 solid;
|
101
|
+
-moz-border-radius: 10px;
|
102
|
+
-webkit-border-radius: 10px;
|
103
|
+
}
|
104
|
+
|
105
|
+
#footer {
|
106
|
+
text-align: center;
|
107
|
+
margin: 1em 0 0 0;
|
108
|
+
padding: 0.5em 0.5em 0.5em 1em;
|
109
|
+
width: 100%;
|
110
|
+
background: rgb(0,40,40);
|
111
|
+
color: rgb(77,144,253);
|
112
|
+
position: relative; bottom: 0;
|
113
|
+
}
|
114
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
class Retter::Command < Thor
|
4
|
+
desc 'edit', 'Edit current entry with $EDITOR'
|
5
|
+
method_options date: :string
|
6
|
+
def edit
|
7
|
+
system config.editor, detected_retter_file.to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
default_task :edit
|
11
|
+
|
12
|
+
desc 'preview', 'Preview current entry'
|
13
|
+
method_options date: :string
|
14
|
+
def preview
|
15
|
+
preview = Retter::Stationery.previewer(detected_date, config)
|
16
|
+
|
17
|
+
preview.print
|
18
|
+
Launchy.open preview.file_path.to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'open', 'Open site statically'
|
22
|
+
def open
|
23
|
+
Launchy.open config.index_file.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'rebind', 'Re generate site pages'
|
27
|
+
def rebind
|
28
|
+
binder = Retter::Stationery.binder(config)
|
29
|
+
|
30
|
+
binder.commit_wip_file
|
31
|
+
binder.rebind!
|
32
|
+
end
|
33
|
+
|
34
|
+
desc 'bind', 'Generate site pages'
|
35
|
+
alias_method :bind, :rebind
|
36
|
+
|
37
|
+
desc 'new', 'Create new site'
|
38
|
+
def new
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def detected_retter_file
|
44
|
+
if options[:date]
|
45
|
+
config.retter_file(Date.parse(options[:date]), '.md')
|
46
|
+
else
|
47
|
+
todays_file = config.retter_file(Date.today, '.md')
|
48
|
+
todays_file.exist? ? todays_file : config.wip_file
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def detected_date
|
53
|
+
options[:date] ? Date.parse(options[:date]) : Date.today
|
54
|
+
end
|
55
|
+
|
56
|
+
def config
|
57
|
+
@retter_config ||= Retter::Config.new(ENV)
|
58
|
+
rescue Retter::EnvError
|
59
|
+
say 'Set $RETTER_HOME and $EDITOR, first.', :red
|
60
|
+
say <<-EOM, :green
|
61
|
+
usage:
|
62
|
+
export EDITOR=`which vim` # or other editor
|
63
|
+
cd /path/to/dir
|
64
|
+
retter new my_sweet_diary
|
65
|
+
export RETTER_HOME=/path/to/dir/my_sweet_diary
|
66
|
+
cd my_sweet_diary
|
67
|
+
retter # Write the article with markdown, and save.
|
68
|
+
retter preview # Draft article will be opened in your default browser.
|
69
|
+
retter bind # Your actual website will be generated.
|
70
|
+
bundle exec rackup # Open your browser, and visit http://localhost:9292/ .
|
71
|
+
EOM
|
72
|
+
exit 1
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
class Retter::Config
|
4
|
+
[:editor, :retter_home, :title, :description, :url, :author].each do |att|
|
5
|
+
class_eval <<-EOM
|
6
|
+
def #{att}(val = nil)
|
7
|
+
val ? @options[:#{att}] = val : @options[:#{att}]
|
8
|
+
end
|
9
|
+
EOM
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(env)
|
13
|
+
@env, @options = env, {}
|
14
|
+
|
15
|
+
detect_retter_home
|
16
|
+
raise Retter::EnvError unless env.values_at('EDITOR', 'RETTER_HOME').all?
|
17
|
+
|
18
|
+
editor env['EDITOR']
|
19
|
+
retter_home Pathname.new(env['RETTER_HOME'])
|
20
|
+
url 'http://example.com'
|
21
|
+
|
22
|
+
retterfile = retter_home.join('Retterfile')
|
23
|
+
instance_eval retterfile.read if retterfile.exist?
|
24
|
+
end
|
25
|
+
|
26
|
+
def detect_retter_home
|
27
|
+
@env['RETTER_HOME'] = Dir.pwd if File.exist? 'Retterfile'
|
28
|
+
end
|
29
|
+
|
30
|
+
def retters_dir
|
31
|
+
retter_home.join 'retters/'
|
32
|
+
end
|
33
|
+
|
34
|
+
def wip_file
|
35
|
+
retters_dir.join 'today.md'
|
36
|
+
end
|
37
|
+
|
38
|
+
def retter_file(date, suf)
|
39
|
+
retters_dir.join(date ? date.strftime("%Y%m%d#{suf}") : "today#{suf}")
|
40
|
+
end
|
41
|
+
|
42
|
+
def layouts_dir
|
43
|
+
retter_home.join 'layouts/'
|
44
|
+
end
|
45
|
+
|
46
|
+
def layout_file
|
47
|
+
layouts_dir.join 'retter.html.haml'
|
48
|
+
end
|
49
|
+
|
50
|
+
def profile_layout_file
|
51
|
+
layouts_dir.join 'profile.html.haml'
|
52
|
+
end
|
53
|
+
|
54
|
+
def entry_layout_file
|
55
|
+
layouts_dir.join 'entry.html.haml'
|
56
|
+
end
|
57
|
+
|
58
|
+
def entries_layout_file
|
59
|
+
layouts_dir.join 'entries.html.haml'
|
60
|
+
end
|
61
|
+
|
62
|
+
def index_layout_file
|
63
|
+
layouts_dir.join 'index.html.haml'
|
64
|
+
end
|
65
|
+
|
66
|
+
def entries_dir
|
67
|
+
retter_home.join 'entries/'
|
68
|
+
end
|
69
|
+
|
70
|
+
def entry_file(date)
|
71
|
+
entries_dir.join date.strftime('%Y%m%d.html')
|
72
|
+
end
|
73
|
+
|
74
|
+
def profile_file
|
75
|
+
retter_home.join 'profile.html'
|
76
|
+
end
|
77
|
+
|
78
|
+
def index_file
|
79
|
+
retter_home.join 'index.html'
|
80
|
+
end
|
81
|
+
|
82
|
+
def entries_file
|
83
|
+
retter_home.join 'entries.html'
|
84
|
+
end
|
85
|
+
|
86
|
+
def feed_file
|
87
|
+
retter_home.join 'entries.rss'
|
88
|
+
end
|
89
|
+
end
|
data/lib/retter/entry.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
class Retter::Entry
|
4
|
+
attr_accessor :date, :body, :titles
|
5
|
+
|
6
|
+
def initialize(attrs={})
|
7
|
+
@date, @body = attrs.values_at(:date, :body)
|
8
|
+
|
9
|
+
attach_titles
|
10
|
+
load_titles
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
body
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def body_elements
|
20
|
+
Nokogiri::HTML(body)
|
21
|
+
end
|
22
|
+
|
23
|
+
def attach_titles
|
24
|
+
html = body_elements
|
25
|
+
html.search('//h1').each_with_index do |h1, seq|
|
26
|
+
h1.set_attribute 'id', "a#{seq}"
|
27
|
+
end
|
28
|
+
|
29
|
+
@body = html.search('//body/*').to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
def load_titles
|
33
|
+
@titles = body_elements.search('//h1').each_with_object({}) {|h1, titles|
|
34
|
+
titles[h1.attr('id')] = h1.text
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Retter::Stationery
|
4
|
+
class Binder
|
5
|
+
attr_reader :config, :entries
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
@config = config
|
9
|
+
end
|
10
|
+
|
11
|
+
def view_scope
|
12
|
+
@view_scope ||= View::Scope.new(config, entries: entries)
|
13
|
+
end
|
14
|
+
|
15
|
+
def renderer
|
16
|
+
Haml::Engine.new(config.layout_file.read, ugly: true)
|
17
|
+
end
|
18
|
+
|
19
|
+
def entries_renderer
|
20
|
+
Haml::Engine.new(config.entries_layout_file.read, ugly: true)
|
21
|
+
end
|
22
|
+
|
23
|
+
def entry_renderer
|
24
|
+
Haml::Engine.new(config.entry_layout_file.read, ugly: true)
|
25
|
+
end
|
26
|
+
|
27
|
+
def index_renderer
|
28
|
+
Haml::Engine.new(config.index_layout_file.read, ugly: true)
|
29
|
+
end
|
30
|
+
|
31
|
+
def profile_renderer
|
32
|
+
Haml::Engine.new(config.profile_layout_file.read, ugly: true)
|
33
|
+
end
|
34
|
+
|
35
|
+
def rebind!
|
36
|
+
commit_wip_file
|
37
|
+
|
38
|
+
@entries = Retter::Stationery.scan(config.retters_dir)
|
39
|
+
|
40
|
+
bind_entries
|
41
|
+
print_index
|
42
|
+
print_profile
|
43
|
+
print_rss
|
44
|
+
end
|
45
|
+
|
46
|
+
def commit_wip_file
|
47
|
+
if config.wip_file.exist?
|
48
|
+
html = config.wip_file.read
|
49
|
+
config.retter_file(Date.today, '.md').open('a') {|f| f.puts html }
|
50
|
+
config.wip_file.unlink
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def bind_entries
|
55
|
+
@entries.each {|entry| print_entry entry }
|
56
|
+
print_toc
|
57
|
+
end
|
58
|
+
|
59
|
+
def print_entry(entry)
|
60
|
+
part = entry_renderer.render(view_scope, entry: entry)
|
61
|
+
html = renderer.render(view_scope, content: part)
|
62
|
+
|
63
|
+
config.entry_file(entry.date).open('w') do |f|
|
64
|
+
f.puts View::Helper.fix_path(html, '../')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def print_index
|
69
|
+
part = index_renderer.render(view_scope)
|
70
|
+
html = renderer.render(view_scope, content: part)
|
71
|
+
|
72
|
+
config.index_file.open('w') do |f|
|
73
|
+
f.puts View::Helper.fix_path(html, './')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def print_profile
|
78
|
+
part = profile_renderer.render(view_scope)
|
79
|
+
html = renderer.render(view_scope, content: part)
|
80
|
+
|
81
|
+
config.profile_file.open('w') do |f|
|
82
|
+
f.puts View::Helper.fix_path(html, './')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def print_toc
|
87
|
+
part = entries_renderer.render(view_scope)
|
88
|
+
html = renderer.render(view_scope, content: part)
|
89
|
+
|
90
|
+
config.entries_file.open('w') do |f|
|
91
|
+
f.puts View::Helper.fix_path(html, './')
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def print_rss
|
96
|
+
config.feed_file.open('w') {|f| f.puts rss }
|
97
|
+
end
|
98
|
+
|
99
|
+
def rss
|
100
|
+
xml = Builder::XmlMarkup.new
|
101
|
+
xml.instruct!
|
102
|
+
xml.rdf:RDF, :xmlns => 'http://purl.org/rss/1.0/',
|
103
|
+
:'xmlns:rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
|
104
|
+
:'xmlns:dc' => 'http://purl.org/dc/elements/1.1/',
|
105
|
+
:'xml:lang' => 'ja' do
|
106
|
+
xml.channel :'rdf:about' => config.url do
|
107
|
+
xml.title config.title
|
108
|
+
xml.link config.url
|
109
|
+
xml.dc:date, entries.first.date
|
110
|
+
xml.description config.description
|
111
|
+
xml.items { xml.rdf(:Seq) { entries.each {|e| xml.rdf:li, :'rdf:resource' => entry_url(e.date) } } }
|
112
|
+
end
|
113
|
+
|
114
|
+
entries.each do |entry|
|
115
|
+
xml.item about: entry_url(entry.date) do
|
116
|
+
xml.title entry.date.strftime('%Y/%m/%d')
|
117
|
+
xml.description { xml.cdata! entry.body }
|
118
|
+
xml.dc:date, entry.date
|
119
|
+
xml.link entry_url(entry.date)
|
120
|
+
xml.author config.author
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def entry_url(date, id = nil)
|
127
|
+
(URI.parse(config.url) + date.strftime('/entries/%Y%m%d.html')).to_s
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Retter::Stationery
|
4
|
+
class Previewer
|
5
|
+
attr_reader :config
|
6
|
+
|
7
|
+
def initialize(date, config)
|
8
|
+
@config, @date = config, date
|
9
|
+
@body, @entry = *nil
|
10
|
+
|
11
|
+
load_retter_file
|
12
|
+
load_wip_entry_if_needed
|
13
|
+
end
|
14
|
+
|
15
|
+
def file_path
|
16
|
+
config.retter_home.join '.preview.html'
|
17
|
+
end
|
18
|
+
|
19
|
+
def renderer
|
20
|
+
Haml::Engine.new(config.layout_file.read, ugly: true)
|
21
|
+
end
|
22
|
+
|
23
|
+
def entry_renderer
|
24
|
+
Haml::Engine.new(config.entry_layout_file.read, ugly: true)
|
25
|
+
end
|
26
|
+
|
27
|
+
def print
|
28
|
+
build_entry
|
29
|
+
print_html
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def print_html
|
35
|
+
scope = View::Scope.new(config)
|
36
|
+
part = entry_renderer.render(scope, entry: @entry)
|
37
|
+
html = renderer.render(scope, content: part, entries: [@entry])
|
38
|
+
|
39
|
+
file_path.open('w') do |file|
|
40
|
+
file.puts View::Helper.fix_path(html, './')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_entry
|
45
|
+
@entry = Retter::Entry.new(date: @date, body: Retter::Stationery.parser.render(@body))
|
46
|
+
end
|
47
|
+
|
48
|
+
def load_retter_file
|
49
|
+
retter_file = config.retter_file(@date, '.md')
|
50
|
+
@body = retter_file.exist? ? retter_file.read : ''
|
51
|
+
end
|
52
|
+
|
53
|
+
def load_wip_entry_if_needed
|
54
|
+
if @date == Date.today && config.wip_file.exist?
|
55
|
+
@body = [@body, config.wip_file.read].join("\n")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Retter::Stationery::View
|
4
|
+
module Helper
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def fix_path(html, prefix='./')
|
8
|
+
elements = Nokogiri::HTML(html)
|
9
|
+
|
10
|
+
elements.search("[src!=''][src!='']").each do |el|
|
11
|
+
src = el.attr('src').scan(/[^\.\/]{3}.*/).first
|
12
|
+
next if src =~ /^(?:http|https):\/\//
|
13
|
+
|
14
|
+
el.set_attribute 'src', [prefix, src].join
|
15
|
+
end
|
16
|
+
|
17
|
+
elements.search("[href][href!='#']").each do |el|
|
18
|
+
href = el.attr('href')
|
19
|
+
next if href =~ /^(?:http|https):\/\//
|
20
|
+
|
21
|
+
if href == '/'
|
22
|
+
el.set_attribute 'href', [prefix, 'index.html'].join
|
23
|
+
else
|
24
|
+
el.set_attribute 'href', [prefix, href.scan(/[^\.\/]{3}.*/).first].join
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
elements.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
def entry_path(date, id = nil)
|
32
|
+
date.strftime('/entries/%Y%m%d.html') + (id ? "##{id}" : '')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Scope
|
37
|
+
attr_reader :config
|
38
|
+
attr_accessor :assigns
|
39
|
+
|
40
|
+
include Helper
|
41
|
+
|
42
|
+
[:entries].each do |meth|
|
43
|
+
define_method meth do
|
44
|
+
@assigns[meth]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def initialize(config, assigns = {})
|
49
|
+
@config, @assigns = config, assigns
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Retter::Stationery
|
4
|
+
class << self
|
5
|
+
def scan(path)
|
6
|
+
entries = find_markup_files(path).map {|file|
|
7
|
+
date = file.basename('.*').to_s
|
8
|
+
mkup = File.open(file, &:read)
|
9
|
+
Retter::Entry.new date: Date.parse(date), body: parser.render(mkup)
|
10
|
+
}
|
11
|
+
|
12
|
+
entries.sort_by(&:date).reverse
|
13
|
+
end
|
14
|
+
|
15
|
+
def find_markup_files(path)
|
16
|
+
path = Pathname.new(path).realpath
|
17
|
+
Dir.open(path, &:to_a).grep(/^\d{4}(?:0[1-9]|1[012])(?:0[1-9]|[12][0-9]|3[01])\.(md)$/).map {|f| path.join f }
|
18
|
+
end
|
19
|
+
|
20
|
+
def parser
|
21
|
+
@parser ||= ::Redcarpet::Markdown.new(
|
22
|
+
Renderer,
|
23
|
+
autolink: true,
|
24
|
+
space_after_headers: true,
|
25
|
+
fenced_code_blocks: true,
|
26
|
+
strikethrough: true,
|
27
|
+
superscript: true,
|
28
|
+
fenced_code_blocks: true,
|
29
|
+
tables: true
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def previewer(date, config)
|
34
|
+
Previewer.new date, config
|
35
|
+
end
|
36
|
+
|
37
|
+
def binder(config)
|
38
|
+
Binder.new config
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
require 'retter/stationery/renderer'
|
44
|
+
require 'retter/stationery/view'
|
45
|
+
require 'retter/stationery/previewer'
|
46
|
+
require 'retter/stationery/binder'
|
47
|
+
|
data/lib/retter.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
here = File.dirname(__FILE__)
|
4
|
+
$LOAD_PATH.unshift here unless $LOAD_PATH.include?(here)
|
5
|
+
|
6
|
+
module Retter
|
7
|
+
class EnvError < RuntimeError; end
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'date'
|
11
|
+
require 'time'
|
12
|
+
require 'builder'
|
13
|
+
require 'pathname'
|
14
|
+
require 'thor'
|
15
|
+
require 'redcarpet'
|
16
|
+
require 'coderay'
|
17
|
+
require 'nokogiri'
|
18
|
+
require 'launchy'
|
19
|
+
require 'haml'
|
20
|
+
require 'uri'
|
21
|
+
require 'retter/version'
|
22
|
+
require 'retter/entry'
|
23
|
+
require 'retter/stationery'
|
24
|
+
require 'retter/config'
|
25
|
+
require 'retter/command'
|
data/retter.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "retter/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "retter"
|
7
|
+
s.version = Retter::VERSION
|
8
|
+
s.authors = ["hibariya"]
|
9
|
+
s.email = ["celluloid.key@gmail.com"]
|
10
|
+
s.homepage = "http://retter.heroku.com"
|
11
|
+
s.summary = %q{Lightweight diary workflow}
|
12
|
+
s.description = %q{Lightweight diary workflow}
|
13
|
+
|
14
|
+
#s.rubyforge_project = "retter"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_runtime_dependency 'thor'
|
22
|
+
s.add_runtime_dependency 'builder'
|
23
|
+
s.add_runtime_dependency 'redcarpet', ['>= 2.0.0b3']
|
24
|
+
s.add_runtime_dependency 'coderay'
|
25
|
+
s.add_runtime_dependency 'nokogiri'
|
26
|
+
s.add_runtime_dependency 'launchy'
|
27
|
+
s.add_runtime_dependency 'haml'
|
28
|
+
s.add_runtime_dependency 'bundler'
|
29
|
+
s.add_runtime_dependency 'grit'
|
30
|
+
|
31
|
+
s.add_development_dependency 'ir_b'
|
32
|
+
s.add_development_dependency 'tapp'
|
33
|
+
s.add_development_dependency 'rspec'
|
34
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
4
|
+
|
5
|
+
describe 'Retter::Command#edit', clean: :all do
|
6
|
+
let(:command) { Retter::Command.new }
|
7
|
+
let(:wip_file) { retter_config.wip_file }
|
8
|
+
|
9
|
+
before do
|
10
|
+
command.stub!(:config) { retter_config }
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'no options' do
|
14
|
+
before do
|
15
|
+
command.edit
|
16
|
+
end
|
17
|
+
|
18
|
+
it { wip_file.should be_exist }
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'no options after rebind' do
|
22
|
+
let(:date) { '20110101' }
|
23
|
+
|
24
|
+
before do
|
25
|
+
Date.stub!(:today).and_return(Date.parse(date))
|
26
|
+
|
27
|
+
command.edit
|
28
|
+
command.bind
|
29
|
+
command.edit
|
30
|
+
end
|
31
|
+
|
32
|
+
it { wip_file.should_not be_exist }
|
33
|
+
it { retter_config.retters_dir.join("#{date}.md").should be_exist }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'with date' do
|
37
|
+
let(:date) { '20110101' }
|
38
|
+
|
39
|
+
before do
|
40
|
+
command.stub!(:options) { {date: date} }
|
41
|
+
command.edit
|
42
|
+
end
|
43
|
+
|
44
|
+
it { wip_file.should_not be_exist }
|
45
|
+
|
46
|
+
describe 'target date file' do
|
47
|
+
subject { retter_config.retters_dir.join("#{date}.md") }
|
48
|
+
|
49
|
+
it { should be_exist }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
4
|
+
|
5
|
+
describe 'Retter::Command#preview', clean: :all do
|
6
|
+
let(:command) { Retter::Command.new }
|
7
|
+
let(:preview) { retter_config.retter_home.join('.preview.html').read }
|
8
|
+
let(:wip_file) { retter_config.wip_file }
|
9
|
+
let(:date_file) { retter_config.retter_file(Date.parse(date), '.md') }
|
10
|
+
|
11
|
+
before do
|
12
|
+
command.stub!(:config) { retter_config }
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'no options' do
|
16
|
+
let(:article) { 'w00t!' }
|
17
|
+
|
18
|
+
before do
|
19
|
+
wip_file.open('w') {|f| f.puts article }
|
20
|
+
Launchy.stub!(:open).with(anything)
|
21
|
+
|
22
|
+
command.preview
|
23
|
+
end
|
24
|
+
|
25
|
+
it { preview.should =~ /<body.*#{article}.*\/body>/mi }
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'with date' do
|
29
|
+
let(:article) { 'おはようございます' }
|
30
|
+
let(:date) { '20110101' }
|
31
|
+
|
32
|
+
before do
|
33
|
+
wip_file.open('w') {|f| f.puts 'おやすみなさい' }
|
34
|
+
date_file.open('w') {|f| f.puts article }
|
35
|
+
Launchy.stub!(:open).with(anything)
|
36
|
+
|
37
|
+
command.preview
|
38
|
+
end
|
39
|
+
|
40
|
+
it { preview =~ /#{article}/mi }
|
41
|
+
it { preview !~ /おやすみなさい/mi }
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
4
|
+
|
5
|
+
describe 'Retter::Command#rebind', clean: :all do
|
6
|
+
let(:command) { Retter::Command.new }
|
7
|
+
let(:wip_file) { retter_config.wip_file }
|
8
|
+
let(:date_file) { retter_config.retter_file(Date.parse(date), '.md') }
|
9
|
+
let(:date_html) { retter_config.retter_home.join('entries', "#{date}.html") }
|
10
|
+
|
11
|
+
before do
|
12
|
+
command.stub!(:config) { retter_config }
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'first post' do
|
16
|
+
let(:date) { '20110101' }
|
17
|
+
let(:article) { <<-EOM }
|
18
|
+
# 朝11時
|
19
|
+
|
20
|
+
おはようございます
|
21
|
+
|
22
|
+
# 夜1時
|
23
|
+
|
24
|
+
おやすみなさい
|
25
|
+
EOM
|
26
|
+
|
27
|
+
before do
|
28
|
+
wip_file.open('w') {|f| f.puts article }
|
29
|
+
Date.stub!(:today).and_return(Date.parse(date))
|
30
|
+
|
31
|
+
command.rebind
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'today.md' do
|
35
|
+
it { wip_file.should_not be_exist }
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'index.html' do
|
39
|
+
subject { Nokogiri::HTML(retter_config.retter_home.join('index.html').read) }
|
40
|
+
|
41
|
+
it { subject.search('body').text.should =~ /おはようございます/ }
|
42
|
+
it { subject.search('.entry h1.date').first.text.should be_include('2011/01/01') }
|
43
|
+
it { subject.search('.entry h1').map(&:text).map(&:strip).should == %w(2011/01/01 朝11時 夜1時) }
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'entries.html' do
|
47
|
+
subject { Nokogiri::HTML(retter_config.retter_home.join('entries.html').read) }
|
48
|
+
|
49
|
+
it { subject.search('a.entry').first.text.should be_include('2011/01/01') }
|
50
|
+
it { subject.search('a.title').map(&:text).map(&:strip).should == %w(朝11時 夜1時) }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
RETTER_ROOT = Pathname.new(File.dirname(__FILE__) + '/../').realpath
|
4
|
+
|
5
|
+
require RETTER_ROOT.join('lib', 'retter')
|
6
|
+
require 'tapp'
|
7
|
+
|
8
|
+
module Retter::ConfigSupport
|
9
|
+
def retter_config
|
10
|
+
return @config if @config
|
11
|
+
|
12
|
+
env = {
|
13
|
+
'EDITOR' => 'touch',
|
14
|
+
'RETTER_HOME' => RETTER_ROOT.join('tmp', 'test').to_s
|
15
|
+
}
|
16
|
+
|
17
|
+
@config = Retter::Config.new(env)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
RSpec.configure do |config|
|
22
|
+
config.filter_run focus: true
|
23
|
+
config.run_all_when_everything_filtered = true
|
24
|
+
|
25
|
+
retter_home = RETTER_ROOT.join('tmp', 'test')
|
26
|
+
skel = RETTER_ROOT.join('lib', 'generator', 'skel')
|
27
|
+
|
28
|
+
config.after(:each, clean: :all) do
|
29
|
+
FileUtils.cp_r skel, retter_home.dirname.join('test')
|
30
|
+
end
|
31
|
+
|
32
|
+
config.after(:each, clean: :all) do
|
33
|
+
FileUtils.rm_rf retter_home
|
34
|
+
end
|
35
|
+
|
36
|
+
config.include Retter::ConfigSupport
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: retter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- hibariya
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-09-08 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thor
|
16
|
+
requirement: &70260599810340 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70260599810340
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: builder
|
27
|
+
requirement: &70260599899920 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70260599899920
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: redcarpet
|
38
|
+
requirement: &70260599902380 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.0.0b3
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70260599902380
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: coderay
|
49
|
+
requirement: &70260599904040 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70260599904040
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: nokogiri
|
60
|
+
requirement: &70260599913220 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70260599913220
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: launchy
|
71
|
+
requirement: &70260599914340 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70260599914340
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: haml
|
82
|
+
requirement: &70260599913880 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70260599913880
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: bundler
|
93
|
+
requirement: &70260599913440 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :runtime
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70260599913440
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: grit
|
104
|
+
requirement: &70260599912660 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :runtime
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: *70260599912660
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: ir_b
|
115
|
+
requirement: &70260599910020 !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
type: :development
|
122
|
+
prerelease: false
|
123
|
+
version_requirements: *70260599910020
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: tapp
|
126
|
+
requirement: &70260599907780 !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
128
|
+
requirements:
|
129
|
+
- - ! '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: *70260599907780
|
135
|
+
- !ruby/object:Gem::Dependency
|
136
|
+
name: rspec
|
137
|
+
requirement: &70260599907300 !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
type: :development
|
144
|
+
prerelease: false
|
145
|
+
version_requirements: *70260599907300
|
146
|
+
description: Lightweight diary workflow
|
147
|
+
email:
|
148
|
+
- celluloid.key@gmail.com
|
149
|
+
executables:
|
150
|
+
- retter
|
151
|
+
extensions: []
|
152
|
+
extra_rdoc_files: []
|
153
|
+
files:
|
154
|
+
- .gitignore
|
155
|
+
- Gemfile
|
156
|
+
- Rakefile
|
157
|
+
- bin/retter
|
158
|
+
- lib/generator/newretter.rb
|
159
|
+
- lib/generator/skel/.gitignore
|
160
|
+
- lib/generator/skel/Gemfile
|
161
|
+
- lib/generator/skel/Retterfile
|
162
|
+
- lib/generator/skel/config.ru
|
163
|
+
- lib/generator/skel/entries/.gitkeep
|
164
|
+
- lib/generator/skel/images/.gitkeep
|
165
|
+
- lib/generator/skel/index.html
|
166
|
+
- lib/generator/skel/javascripts/.gitkeep
|
167
|
+
- lib/generator/skel/layouts/entries.html.haml
|
168
|
+
- lib/generator/skel/layouts/entry.html.haml
|
169
|
+
- lib/generator/skel/layouts/index.html.haml
|
170
|
+
- lib/generator/skel/layouts/profile.html.haml
|
171
|
+
- lib/generator/skel/layouts/retter.html.haml
|
172
|
+
- lib/generator/skel/retters/.gitkeep
|
173
|
+
- lib/generator/skel/stylesheets/application.css
|
174
|
+
- lib/retter.rb
|
175
|
+
- lib/retter/command.rb
|
176
|
+
- lib/retter/config.rb
|
177
|
+
- lib/retter/entry.rb
|
178
|
+
- lib/retter/stationery.rb
|
179
|
+
- lib/retter/stationery/binder.rb
|
180
|
+
- lib/retter/stationery/previewer.rb
|
181
|
+
- lib/retter/stationery/renderer.rb
|
182
|
+
- lib/retter/stationery/view.rb
|
183
|
+
- lib/retter/version.rb
|
184
|
+
- retter.gemspec
|
185
|
+
- spec/command/edit_spec.rb
|
186
|
+
- spec/command/preview_spec.rb
|
187
|
+
- spec/command/rebind_spec.rb
|
188
|
+
- spec/spec_helper.rb
|
189
|
+
homepage: http://retter.heroku.com
|
190
|
+
licenses: []
|
191
|
+
post_install_message:
|
192
|
+
rdoc_options: []
|
193
|
+
require_paths:
|
194
|
+
- lib
|
195
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
196
|
+
none: false
|
197
|
+
requirements:
|
198
|
+
- - ! '>='
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: '0'
|
201
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
202
|
+
none: false
|
203
|
+
requirements:
|
204
|
+
- - ! '>='
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: '0'
|
207
|
+
requirements: []
|
208
|
+
rubyforge_project:
|
209
|
+
rubygems_version: 1.8.6
|
210
|
+
signing_key:
|
211
|
+
specification_version: 3
|
212
|
+
summary: Lightweight diary workflow
|
213
|
+
test_files:
|
214
|
+
- spec/command/edit_spec.rb
|
215
|
+
- spec/command/preview_spec.rb
|
216
|
+
- spec/command/rebind_spec.rb
|
217
|
+
- spec/spec_helper.rb
|