retter 0.1.0 → 0.1.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.
Files changed (45) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +1 -0
  3. data/README.md +54 -4
  4. data/bin/retter +2 -0
  5. data/lib/retter/command.rb +37 -41
  6. data/lib/retter/config.rb +94 -84
  7. data/lib/retter/entries.rb +93 -0
  8. data/lib/retter/entry.rb +46 -9
  9. data/lib/retter/generator/skel/images/orange/ic_li01.gif +0 -0
  10. data/lib/retter/generator/skel/layouts/article.html.haml +16 -3
  11. data/lib/retter/generator/skel/layouts/entries.html.haml +2 -2
  12. data/lib/retter/generator/skel/layouts/entry.html.haml +17 -3
  13. data/lib/retter/generator/skel/layouts/index.html.haml +14 -4
  14. data/lib/retter/generator/skel/stylesheets/base.css +1 -1
  15. data/lib/retter/generator/skel/stylesheets/orange.css +17 -2
  16. data/lib/retter/page/view_helper.rb +33 -0
  17. data/lib/retter/page.rb +86 -0
  18. data/lib/retter/pages/archive.rb +13 -0
  19. data/lib/retter/pages/article.rb +35 -0
  20. data/lib/retter/pages/entry.rb +28 -0
  21. data/lib/retter/pages/feed.rb +46 -0
  22. data/lib/retter/pages/index.rb +13 -0
  23. data/lib/retter/pages/profile.rb +13 -0
  24. data/lib/retter/pages.rb +40 -0
  25. data/lib/retter/preprint.rb +21 -0
  26. data/lib/retter/{stationery/renderer.rb → renderer.rb} +1 -1
  27. data/lib/retter/repository.rb +21 -0
  28. data/lib/retter/version.rb +1 -1
  29. data/lib/retter.rb +36 -3
  30. data/retter.gemspec +31 -0
  31. data/spec/command/callback_spec.rb +1 -1
  32. data/spec/command/commit_spec.rb +1 -1
  33. data/spec/command/edit_spec.rb +1 -1
  34. data/spec/command/invoke_after_spec.rb +2 -2
  35. data/spec/command/list_spec.rb +47 -0
  36. data/spec/command/open_spec.rb +1 -1
  37. data/spec/command/preview_spec.rb +1 -1
  38. data/spec/command/rebind_spec.rb +8 -8
  39. data/spec/spec_helper.rb +2 -0
  40. data/spec/support/stream_capture.rb +16 -0
  41. metadata +84 -39
  42. data/lib/retter/stationery/binder.rb +0 -150
  43. data/lib/retter/stationery/previewer.rb +0 -64
  44. data/lib/retter/stationery/view.rb +0 -68
  45. data/lib/retter/stationery.rb +0 -47
@@ -1,11 +1,21 @@
1
- #entries
2
- - entries[0..5].each do |entry|
1
+ #entries.autopagerize_page_element
2
+ - recent_entries = entries[0..4]
3
+ - recent_entries.each do |entry|
3
4
  %article
4
5
  %h1.date
5
- %a{href: entry_path(entry.date)}= entry.date.strftime('%Y/%m/%d')
6
+ %a{href: entry_path(entry)}= entry.date
7
+
6
8
  - unless entry.lede.empty?
7
9
  = entry.lede
10
+
8
11
  - entry.articles.each do |article|
9
12
  %h1{id: article.id}
10
- %a{href: article_path(entry.date, article.id)}= article.title
13
+ %a{href: article_path(article)}= article.title
11
14
  = article
15
+
16
+ .nav
17
+ .next
18
+ - if next_entry = recent_entries.last.next
19
+ %link{href: entry_path(next_entry), rel: :next}
20
+
21
+ .autopagerize_insert_before
@@ -4,5 +4,5 @@ dl dd {
4
4
  }
5
5
 
6
6
  pre {
7
- overflow: scroll;
7
+ overflow: hidden;
8
8
  }
@@ -11,6 +11,7 @@ body {
11
11
  background: #EEE;
12
12
  background-image:url("../images/orange/bg_body.jpg");
13
13
  height: 100%;
14
+ line-height:1.4;
14
15
  }
15
16
 
16
17
  ul {
@@ -22,6 +23,10 @@ a {
22
23
  color: rgb(25,30,10);
23
24
  }
24
25
 
26
+ code{
27
+ padding:0 5px;
28
+ }
29
+
25
30
  #header {
26
31
  padding: 0;
27
32
  margin: 0;
@@ -84,6 +89,18 @@ article {
84
89
  position:relative;
85
90
  }
86
91
 
92
+ article ul li {
93
+ list-style-image:url("../images/orange/ic_li01.gif");
94
+ }
95
+
96
+ article p a {
97
+ color:#F30;
98
+ }
99
+
100
+ article p a:hover {
101
+ color:#F93;
102
+ }
103
+
87
104
  article .date {
88
105
  font-size: 1em;
89
106
  text-align: center;
@@ -91,7 +108,6 @@ article .date {
91
108
  padding:10px;
92
109
  width:100px;
93
110
  float:right;
94
-
95
111
  position:absolute;
96
112
  top:-24px;
97
113
  left:650px;
@@ -151,4 +167,3 @@ pre {
151
167
  #footer a:hover {
152
168
  color: #669;
153
169
  }
154
-
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+
3
+ module Retter::Page
4
+ module ViewHelper
5
+ include Retter::Stationery
6
+
7
+ def entry_path(*args)
8
+ case args.first
9
+ when Date, Time
10
+ date, id = *args
11
+ date.strftime('/entries/%Y%m%d.html') + (id ? "##{id}" : '')
12
+ when Retter::Entry
13
+ entry = args.first
14
+ entry_path(entry.date)
15
+ else
16
+ raise TypeError, "wrong argument type #{args.first.class} (expected Date, Time or Retter::Entry)"
17
+ end
18
+ end
19
+
20
+ def article_path(*args)
21
+ case args.first
22
+ when Date, Time
23
+ date, id = *args
24
+ date.strftime("/entries/%Y%m%d/#{id}.html")
25
+ when Retter::Entry::Article
26
+ article = args.first
27
+ article_path(article.entry.date, article.id)
28
+ else
29
+ raise TypeError, "wrong argument type #{args.first.class} (expected Date, Time or Retter::Entry::Article)"
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,86 @@
1
+ # coding: utf-8
2
+
3
+ module Retter
4
+ module Page
5
+ require 'retter/page/view_helper'
6
+
7
+ include Retter::Stationery
8
+
9
+ attr_reader :path_prefix, :title
10
+
11
+ def initialize
12
+ @path_prefix = './'
13
+ @title = config.title
14
+ end
15
+
16
+ def print
17
+ part = Haml::Engine.new(part_layout_pathname.read, ugly: true).render(view_scope)
18
+
19
+ print_with_layout part
20
+ end
21
+
22
+ def pathname
23
+ raise NotImplementedError
24
+ end
25
+
26
+ def path
27
+ pathname.to_s
28
+ end
29
+
30
+ def part_layout_pathname
31
+ raise NotImplementedError
32
+ end
33
+
34
+ private
35
+
36
+ def print_with_layout(content)
37
+ draft = layout_renderer.render(view_scope, content: content, title: title)
38
+ path_fixed = fix_path(draft, path_prefix)
39
+
40
+ pathname.open('w') {|f| f.puts path_fixed }
41
+ end
42
+
43
+ def layout_renderer
44
+ @layout_renderer ||= Haml::Engine.new(config.layout_file.read, ugly: true)
45
+ end
46
+
47
+ def fix_path(html, prefix='./')
48
+ elements = Nokogiri::HTML(html)
49
+
50
+ fix_href_path(fix_src_path(elements, prefix), prefix).to_s
51
+ end
52
+
53
+ def fix_src_path(elements, prefix = './')
54
+ elements.search("[src!=''][src!='']").each do |el|
55
+ src = el.attr('src').scan(/[^\.\/]{3}.*/).first
56
+ next if src =~ /^(?:http|https):\/\//
57
+
58
+ el.set_attribute 'src', [prefix, src].join
59
+ end
60
+
61
+ elements
62
+ end
63
+
64
+ def fix_href_path(elements, prefix = './')
65
+ elements.search("[href][href!='#']").each do |el|
66
+ href = el.attr('href')
67
+ next if href =~ /^(?:http|https):\/\//
68
+
69
+ if href == '/'
70
+ el.set_attribute 'href', [prefix, 'index.html'].join
71
+ else
72
+ el.set_attribute 'href', [prefix, href.scan(/[^\.\/]{3}.*/).first].join
73
+ end
74
+ end
75
+
76
+ elements
77
+ end
78
+
79
+ view_scope = Object.new
80
+ view_scope.extend ViewHelper
81
+
82
+ define_method :view_scope do
83
+ view_scope
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,13 @@
1
+ # coding: utf-8
2
+
3
+ class Retter::Pages::Archive
4
+ include Retter::Page
5
+
6
+ def pathname
7
+ config.entries_file
8
+ end
9
+
10
+ def part_layout_pathname
11
+ config.entries_layout_file
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+
3
+ class Retter::Pages::Article
4
+ include Retter::Page
5
+
6
+ attr_reader :article
7
+
8
+ def initialize(article)
9
+ super()
10
+ @path_prefix = '../../'
11
+ @article = article
12
+ @title = "#{article.title} - #{config.title}"
13
+ end
14
+
15
+ def pathname
16
+ config.entry_dir(article.entry.date).join("#{article.id}.html")
17
+ end
18
+
19
+ def part_layout_pathname
20
+ config.article_layout_file
21
+ end
22
+
23
+ def print
24
+ options = {entry: article.entry, article: article}
25
+ part = Haml::Engine.new(part_layout_pathname.read, ugly: true).render(view_scope, options)
26
+
27
+ mkdir
28
+ print_with_layout part
29
+ end
30
+
31
+ def mkdir
32
+ entry_dir = config.entry_dir(article.entry.date)
33
+ entry_dir.mkdir unless entry_dir.directory?
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+
3
+ class Retter::Pages::Entry
4
+ include Retter::Page
5
+
6
+ attr_reader :entry
7
+
8
+ def initialize(entry)
9
+ super()
10
+ @path_prefix = '../'
11
+ @entry = entry
12
+ @title = "#{entry.date} - #{config.title}"
13
+ end
14
+
15
+ def pathname
16
+ config.entry_file(entry.date)
17
+ end
18
+
19
+ def part_layout_pathname
20
+ config.entry_layout_file
21
+ end
22
+
23
+ def print
24
+ part = Haml::Engine.new(part_layout_pathname.read, ugly: true).render(view_scope, entry: entry)
25
+
26
+ print_with_layout part
27
+ end
28
+ end
@@ -0,0 +1,46 @@
1
+ # coding: utf-8
2
+
3
+ class Retter::Pages::Feed
4
+ include Retter::Page
5
+
6
+ def pathname
7
+ config.feed_file
8
+ end
9
+
10
+ def print
11
+ pathname.open('w') {|f| f.puts rss }
12
+ end
13
+
14
+ private
15
+
16
+ def entry_url(date, id = nil)
17
+ (URI.parse(config.url) + date.strftime('/entries/%Y%m%d.html')).to_s
18
+ end
19
+
20
+ def rss
21
+ xml = Builder::XmlMarkup.new
22
+ xml.instruct!
23
+ xml.rdf:RDF, :xmlns => 'http://purl.org/rss/1.0/',
24
+ :'xmlns:rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
25
+ :'xmlns:dc' => 'http://purl.org/dc/elements/1.1/',
26
+ :'xml:lang' => 'ja' do
27
+ xml.channel :'rdf:about' => config.url do
28
+ xml.title config.title
29
+ xml.link config.url
30
+ xml.dc:date, entries.empty? ? nil : entries.first.date
31
+ xml.description config.description
32
+ xml.items { xml.rdf(:Seq) { entries.each {|e| xml.rdf:li, :'rdf:resource' => entry_url(e.date) } } }
33
+ end
34
+
35
+ entries.each do |entry|
36
+ xml.item about: entry_url(entry.date) do
37
+ xml.title entry.date.strftime('%Y/%m/%d')
38
+ xml.description { xml.cdata! entry.body }
39
+ xml.dc:date, entry.date
40
+ xml.link entry_url(entry.date)
41
+ xml.author config.author
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,13 @@
1
+ # coding: utf-8
2
+
3
+ class Retter::Pages::Index
4
+ include Retter::Page
5
+
6
+ def pathname
7
+ config.index_file
8
+ end
9
+
10
+ def part_layout_pathname
11
+ config.index_layout_file
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # coding: utf-8
2
+
3
+ class Retter::Pages::Profile
4
+ include Retter::Page
5
+
6
+ def pathname
7
+ config.profile_file
8
+ end
9
+
10
+ def part_layout_pathname
11
+ config.profile_layout_file
12
+ end
13
+ end
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+
3
+ module Retter
4
+ class Pages
5
+ require 'retter/pages/index'
6
+ require 'retter/pages/profile'
7
+ require 'retter/pages/archive'
8
+ require 'retter/pages/feed'
9
+ require 'retter/pages/entry'
10
+ require 'retter/pages/article'
11
+
12
+ include Retter::Stationery
13
+
14
+ attr_reader :index, :profile, :archive, :feed, :singleton_pages
15
+
16
+ def initialize
17
+ @singleton_pages = [Index, Profile, Archive, Feed].map(&:new)
18
+ @index, @profile, @archive, @feed = *singleton_pages
19
+ end
20
+
21
+ def bind!
22
+ print_entries
23
+
24
+ singleton_pages.each(&:print)
25
+ end
26
+
27
+
28
+ def print_entries
29
+ entries.each do |entry|
30
+ entry_page = Entry.new(entry)
31
+ entry_page.print
32
+
33
+ entry.articles.each do |article|
34
+ article_page = Article.new(article)
35
+ article_page.print
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+
3
+ module Retter
4
+ class Preprint
5
+ include Retter::Page
6
+
7
+ def pathname
8
+ config.retter_home.join '.preview.html'
9
+ end
10
+
11
+ def part_layout_pathname
12
+ config.entry_layout_file
13
+ end
14
+
15
+ def print(entry)
16
+ part = Haml::Engine.new(part_layout_pathname.read, ugly: true).render(view_scope, entry: entry)
17
+
18
+ print_with_layout part
19
+ end
20
+ end
21
+ end
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
- module Retter::Stationery
3
+ module Retter
4
4
  class Renderer < ::Redcarpet::Render::HTML
5
5
  def block_code(code, lang)
6
6
  ::CodeRay.scan(code, lang ? lang.intern : :plain).div
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+
3
+ module Retter
4
+ class Repository
5
+ include Retter::Stationery
6
+
7
+ def initialize
8
+ working_dir = config.retter_home.to_s
9
+ @repo = Grit::Repo.new(working_dir)
10
+ end
11
+
12
+ def open
13
+ pwd = Dir.pwd
14
+ Dir.chdir @repo.working_dir
15
+
16
+ yield @repo
17
+
18
+ Dir.chdir pwd
19
+ end
20
+ end
21
+ end
@@ -1,3 +1,3 @@
1
1
  module Retter
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
data/lib/retter.rb CHANGED
@@ -4,7 +4,34 @@ here = File.dirname(__FILE__)
4
4
  $LOAD_PATH.unshift here unless $LOAD_PATH.include?(here)
5
5
 
6
6
  module Retter
7
- class EnvError < RuntimeError; end
7
+ module Stationery
8
+ [:config, :entries, :preprint, :pages, :repository].each do |meth|
9
+ define_method meth do
10
+ Retter.send meth
11
+ end
12
+ end
13
+ end
14
+
15
+ class << self
16
+ def load_config(env)
17
+ @config = Config.new(env)
18
+ end
19
+
20
+ def config
21
+ @config
22
+ end
23
+
24
+ def reset_entries!
25
+ @entries = nil
26
+ end
27
+
28
+ singletons = [:entries, :preprint, :pages, :repository]
29
+ singletons.each do |sym|
30
+ define_method sym do
31
+ eval "@#{sym} ||= #{sym.capitalize}.new"
32
+ end
33
+ end
34
+ end
8
35
 
9
36
  autoload :Generator, 'retter/generator'
10
37
  end
@@ -22,8 +49,14 @@ require 'haml'
22
49
  require 'uri'
23
50
  require 'forwardable'
24
51
  require 'grit'
52
+
25
53
  require 'retter/version'
26
- require 'retter/entry'
27
54
  require 'retter/config'
28
- require 'retter/stationery'
55
+ require 'retter/renderer'
56
+ require 'retter/entry'
57
+ require 'retter/entries'
58
+ require 'retter/page'
59
+ require 'retter/pages'
60
+ require 'retter/preprint'
61
+ require 'retter/repository'
29
62
  require 'retter/command'
data/retter.gemspec CHANGED
@@ -11,6 +11,35 @@ Gem::Specification.new do |s|
11
11
  s.summary = %q{Flyweight diary workflow}
12
12
  s.description = %q{Flyweight diary workflow. ruby-1.9.2 or later is required.}
13
13
 
14
+
15
+ s.post_install_message = <<-EOM
16
+ **Important** Some features were added or updated.
17
+
18
+ * Article has Permlink in retter-0.1.0 or later.
19
+ If error occured, try overwrite templates by `retter gen $RETTER_HOME`. (overwrite layouts/*.html.haml)
20
+
21
+ * Relative date is now available in `--date` option.
22
+ Examples:
23
+ $ retter edit yesterday
24
+ $ retter edit today
25
+ $ retter edit tomorrow
26
+ $ retter preview 2.days.ago
27
+
28
+ * `--key` option is now available in edit (and preview).
29
+ Examples:
30
+ $ retter list
31
+ [e0] 2011-10-12 article3, article4
32
+ [e1] 2011-10-10 article1, article2
33
+ $ retter edit --key e0
34
+ ... or ...
35
+ $ retter edit e0
36
+
37
+ * Default date format has changed.
38
+ 2011/01/01 -> 2011-01-01
39
+
40
+ -- Thanks for flying Retter :-> --
41
+ EOM
42
+
14
43
  #s.rubyforge_project = "retter"
15
44
 
16
45
  s.files = `git ls-files`.split("\n")
@@ -27,6 +56,8 @@ Gem::Specification.new do |s|
27
56
  s.add_runtime_dependency 'haml', ['>= 3.1.3']
28
57
  s.add_runtime_dependency 'bundler', ['>= 1.0']
29
58
  s.add_runtime_dependency 'grit', ['>= 2.4.1']
59
+ s.add_runtime_dependency 'activesupport', ['>= 3.1.0']
60
+ s.add_runtime_dependency 'i18n', ['>= 0.6.0']
30
61
 
31
62
  s.add_development_dependency 'rake', ['>= 0.9.2']
32
63
  s.add_development_dependency 'ir_b', ['>= 1.4.0']
@@ -6,7 +6,7 @@ describe 'Retter::Command#callback', clean: :all do
6
6
  let(:command) { Retter::Command.new }
7
7
 
8
8
  before do
9
- command.stub!(:config) { retter_config }
9
+ Retter.stub!(:config) { retter_config }
10
10
 
11
11
  retter_config.after(:edit) { commit }
12
12
  command.should_receive(:commit).and_return(true)
@@ -11,7 +11,7 @@ describe 'Retter::Command#commit', clean: :all do
11
11
  before do
12
12
  Grit::Repo.init retter_config.retter_home.to_s
13
13
 
14
- command.stub!(:config) { retter_config }
14
+ Retter.stub!(:config) { retter_config }
15
15
  command.stub!(:say) { true }
16
16
  wip_file.open('w') {|f| f.puts article }
17
17
  command.rebind
@@ -7,7 +7,7 @@ describe 'Retter::Command#edit', clean: :all do
7
7
  let(:wip_file) { retter_config.wip_file }
8
8
 
9
9
  before do
10
- command.stub!(:config) { retter_config }
10
+ Retter.stub!(:config) { retter_config }
11
11
  end
12
12
 
13
13
  context 'no options' do
@@ -7,7 +7,7 @@ describe 'Retter::Command#invoke_after', clean: :all do
7
7
 
8
8
  context 'invoke with proc' do
9
9
  before do
10
- command.stub!(:config) { retter_config }
10
+ Retter.stub!(:config) { retter_config }
11
11
 
12
12
  retter_config.after(:edit) { commit }
13
13
  command.should_receive(:commit).and_return(true)
@@ -18,7 +18,7 @@ describe 'Retter::Command#invoke_after', clean: :all do
18
18
 
19
19
  context 'invoke with symbol' do
20
20
  before do
21
- command.stub!(:config) { retter_config }
21
+ Retter.stub!(:config) { retter_config }
22
22
 
23
23
  retter_config.after(:edit, :commit)
24
24
  command.should_receive(:invoke).with(:commit).and_return(true)
@@ -0,0 +1,47 @@
1
+ # coding: utf-8
2
+
3
+ require File.dirname(__FILE__) + '/../spec_helper'
4
+
5
+ describe 'Retter::Command#list', clean: :all do
6
+ let(:command) { Retter::Command.new }
7
+ let(:wip_file) { retter_config.wip_file }
8
+
9
+ before do
10
+ Retter.stub!(:config) { retter_config }
11
+ end
12
+
13
+ context 'happy case' do
14
+ before do
15
+ retter_config.retter_file(Date.parse('20110101')).open('w') do |f|
16
+ f.puts <<-EOM
17
+ # 朝11時
18
+
19
+ おはようございます
20
+
21
+ # 夜1時
22
+
23
+ おやすみなさい
24
+ EOM
25
+ end
26
+
27
+ retter_config.retter_file(Date.parse('20110222')).open('w') do |f|
28
+ f.puts <<-EOM
29
+ # 朝11時30分
30
+
31
+ おはようございます
32
+
33
+ # 夜1時30分
34
+
35
+ おやすみなさい
36
+ EOM
37
+ end
38
+ end
39
+
40
+ subject { capture(:stdout) { command.list }.split(/\n+/) }
41
+
42
+ its([0]) { should match /\[e0\]\s+2011\-02\-22/ }
43
+ its([1]) { should match /朝11時30分, 夜1時30分/ }
44
+ its([2]) { should match /\[e1\]\s+2011\-01\-01/ }
45
+ its([3]) { should match /朝11時, 夜1時/ }
46
+ end
47
+ end
@@ -7,7 +7,7 @@ describe 'Retter::Command#open', clean: :all do
7
7
  let(:wip_file) { retter_config.wip_file }
8
8
 
9
9
  before do
10
- command.stub!(:config) { retter_config }
10
+ Retter.stub!(:config) { retter_config }
11
11
  end
12
12
 
13
13
  it 'should be open application' do
@@ -9,7 +9,7 @@ describe 'Retter::Command#preview', clean: :all do
9
9
  let(:date_file) { retter_config.retter_file(Date.parse(date_str)) }
10
10
 
11
11
  before do
12
- command.stub!(:config) { retter_config }
12
+ Retter.stub!(:config) { retter_config }
13
13
  end
14
14
 
15
15
  context 'no options' do