retter 0.2.5 → 1.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -11
  3. data/.travis.yml +4 -2
  4. data/ChangeLog.md +11 -5
  5. data/Gemfile +4 -1
  6. data/LICENSE.txt +22 -0
  7. data/README.md +163 -246
  8. data/Rakefile +25 -5
  9. data/bin/retter +2 -22
  10. data/lib/retter.rb +57 -43
  11. data/lib/retter/cli.rb +46 -0
  12. data/lib/retter/cli/edit.rb +33 -0
  13. data/lib/retter/cli/hooks.rb +46 -0
  14. data/lib/retter/cli/list.rb +15 -0
  15. data/lib/retter/cli/new.rb +20 -0
  16. data/lib/retter/cli/preview.rb +9 -0
  17. data/lib/retter/cli/publish.rb +22 -0
  18. data/lib/retter/deprecated.rb +160 -0
  19. data/lib/retter/entry.rb +31 -106
  20. data/lib/retter/entry/article.rb +36 -0
  21. data/lib/retter/entry/find_methods.rb +38 -0
  22. data/lib/retter/entry/model_base.rb +10 -0
  23. data/lib/retter/entry/pagination.rb +23 -0
  24. data/lib/retter/entry/sort_methods.rb +7 -0
  25. data/lib/retter/entry/utils.rb +12 -0
  26. data/lib/retter/initializing.rb +45 -0
  27. data/lib/retter/repository.rb +99 -12
  28. data/lib/retter/retterfile.rb +67 -0
  29. data/lib/retter/retterfile/context.rb +57 -0
  30. data/lib/retter/static_site.rb +34 -0
  31. data/lib/retter/static_site/app.rb +13 -0
  32. data/lib/retter/static_site/app/application.rb +94 -0
  33. data/lib/retter/{generator/skel/entries → static_site/app/assets/images}/.gitkeep +0 -0
  34. data/lib/retter/{generator/skel → static_site/app/assets}/images/orange/bg_body.jpg +0 -0
  35. data/lib/retter/{generator/skel → static_site/app/assets}/images/orange/bg_entry.jpg +0 -0
  36. data/lib/retter/{generator/skel → static_site/app/assets}/images/orange/bg_header.png +0 -0
  37. data/lib/retter/{generator/skel → static_site/app/assets}/images/orange/ic_li01.gif +0 -0
  38. data/lib/retter/{generator/skel/images → static_site/app/assets/javascripts}/.gitkeep +0 -0
  39. data/lib/retter/static_site/app/assets/stylesheets/application.css.scss +3 -0
  40. data/lib/retter/{generator/skel/stylesheets/base.css → static_site/app/assets/stylesheets/base.css.scss} +0 -0
  41. data/lib/retter/{generator/skel/stylesheets/pygments.css → static_site/app/assets/stylesheets/highlight.css.scss} +0 -0
  42. data/lib/retter/static_site/app/assets/stylesheets/orange.css.scss +262 -0
  43. data/lib/retter/static_site/app/assets/stylesheets/retter.css.scss +198 -0
  44. data/lib/retter/static_site/app/config.ru +7 -0
  45. data/lib/retter/static_site/app/controllers.rb +113 -0
  46. data/lib/retter/static_site/app/helpers.rb +36 -0
  47. data/lib/retter/{generator/skel/layouts/profile.html.haml → static_site/app/templates/about/show.html.haml} +0 -0
  48. data/lib/retter/static_site/app/templates/entries/articles/show.html.haml +7 -0
  49. data/lib/retter/static_site/app/templates/entries/index.html.haml +13 -0
  50. data/lib/retter/static_site/app/templates/entries/index.rss.haml +24 -0
  51. data/lib/retter/static_site/app/templates/entries/show.html.haml +11 -0
  52. data/lib/retter/static_site/app/templates/index/show.html.haml +14 -0
  53. data/lib/retter/static_site/app/templates/layouts/application.html.haml +34 -0
  54. data/lib/retter/static_site/builder.rb +106 -0
  55. data/lib/retter/static_site/cli.rb +25 -0
  56. data/lib/retter/static_site/cli/build.rb +85 -0
  57. data/lib/retter/static_site/cli/edit.rb +17 -0
  58. data/lib/retter/static_site/cli/migrate.rb +93 -0
  59. data/lib/retter/static_site/cli/new.rb +50 -0
  60. data/lib/retter/static_site/cli/preview.rb +66 -0
  61. data/lib/retter/static_site/markdown.rb +25 -0
  62. data/lib/retter/static_site/markdown/code_ray_renderer.rb +13 -0
  63. data/lib/retter/static_site/markdown/pygments_renderer.rb +18 -0
  64. data/lib/retter/static_site/markdown_entry.rb +111 -0
  65. data/lib/retter/static_site/monkey/sprockets_task.rb +10 -0
  66. data/lib/retter/version.rb +1 -1
  67. data/retter.gemspec +59 -43
  68. data/skel/.gitignore +2 -0
  69. data/skel/Retterfile +16 -0
  70. data/skel/config.ru +22 -0
  71. data/{lib/retter/generator/skel/javascripts → skel/retters}/.gitkeep +0 -0
  72. data/skel/retters/today.md +3 -0
  73. data/spec/cli/build_spec.rb +87 -0
  74. data/spec/cli/edit_spec.rb +76 -0
  75. data/spec/cli/invocation_spec.rb +19 -0
  76. data/spec/cli/list_spec.rb +64 -0
  77. data/spec/cli/migrate_spec.rb +65 -0
  78. data/spec/cli/new_spec.rb +30 -0
  79. data/{lib/retter/generator/skel → spec/fixtures/sites/site-0.2.5}/.gitignore +0 -0
  80. data/{lib/retter/generator/skel → spec/fixtures/sites/site-0.2.5}/Retterfile +6 -3
  81. data/{lib/retter/generator/skel → spec/fixtures/sites/site-0.2.5}/config.ru +0 -0
  82. data/{lib/retter/generator/skel/retters/.gitkeep → spec/fixtures/sites/site-0.2.5/entries.html} +0 -0
  83. data/spec/fixtures/sites/site-0.2.5/entries.rss +0 -0
  84. data/spec/fixtures/sites/site-0.2.5/entries/.gitkeep +0 -0
  85. data/spec/fixtures/sites/site-0.2.5/images/.gitkeep +0 -0
  86. data/spec/fixtures/sites/site-0.2.5/images/orange/bg_body.jpg +0 -0
  87. data/spec/fixtures/sites/site-0.2.5/images/orange/bg_entry.jpg +0 -0
  88. data/spec/fixtures/sites/site-0.2.5/images/orange/bg_header.png +0 -0
  89. data/{lib/retter/generator/skel → spec/fixtures/sites/site-0.2.5}/index.html +0 -0
  90. data/spec/fixtures/sites/site-0.2.5/javascripts/.gitkeep +0 -0
  91. data/{lib/retter/generator/skel → spec/fixtures/sites/site-0.2.5}/layouts/article.html.haml +0 -0
  92. data/{lib/retter/generator/skel → spec/fixtures/sites/site-0.2.5}/layouts/entries.html.haml +0 -0
  93. data/{lib/retter/generator/skel → spec/fixtures/sites/site-0.2.5}/layouts/entry.html.haml +0 -0
  94. data/{lib/retter/generator/skel → spec/fixtures/sites/site-0.2.5}/layouts/index.html.haml +0 -0
  95. data/spec/fixtures/sites/site-0.2.5/layouts/profile.html.haml +7 -0
  96. data/{lib/retter/generator/skel → spec/fixtures/sites/site-0.2.5}/layouts/retter.html.haml +0 -0
  97. data/spec/fixtures/sites/site-0.2.5/profile.html +0 -0
  98. data/spec/fixtures/sites/site-0.2.5/retters/.gitkeep +0 -0
  99. data/spec/fixtures/sites/site-0.2.5/stylesheets/base.css +22 -0
  100. data/{lib/retter/generator/skel → spec/fixtures/sites/site-0.2.5}/stylesheets/orange.css +0 -0
  101. data/spec/fixtures/sites/site-0.2.5/stylesheets/pygments.css +288 -0
  102. data/{lib/retter/generator/skel → spec/fixtures/sites/site-0.2.5}/stylesheets/retter.css +0 -0
  103. data/spec/retter/deprecated_spec.rb +106 -0
  104. data/spec/retter/initializing_spec.rb +86 -0
  105. data/spec/retter/retterfile_spec.rb +32 -0
  106. data/spec/spec_helper.rb +38 -27
  107. data/spec/support/example_helper.rb +46 -0
  108. data/spec/support/matchers.rb +14 -0
  109. data/spec/support/test_site.rb +59 -0
  110. metadata +329 -236
  111. data/lib/retter/binder.rb +0 -50
  112. data/lib/retter/command.rb +0 -192
  113. data/lib/retter/config.rb +0 -96
  114. data/lib/retter/configurable.rb +0 -26
  115. data/lib/retter/entries.rb +0 -115
  116. data/lib/retter/generator.rb +0 -7
  117. data/lib/retter/generator/base.rb +0 -65
  118. data/lib/retter/generator/creator.rb +0 -34
  119. data/lib/retter/generator/skel/Gemfile +0 -5
  120. data/lib/retter/markdown.rb +0 -31
  121. data/lib/retter/markdown/code_ray_renderer.rb +0 -11
  122. data/lib/retter/markdown/pygments_renderer.rb +0 -16
  123. data/lib/retter/page.rb +0 -43
  124. data/lib/retter/page/article.rb +0 -54
  125. data/lib/retter/page/base.rb +0 -97
  126. data/lib/retter/page/entries.rb +0 -17
  127. data/lib/retter/page/entry.rb +0 -46
  128. data/lib/retter/page/feed.rb +0 -63
  129. data/lib/retter/page/index.rb +0 -17
  130. data/lib/retter/page/profile.rb +0 -17
  131. data/lib/retter/page/view_helper.rb +0 -66
  132. data/lib/retter/preprint.rb +0 -34
  133. data/spec/command/callback_spec.rb +0 -27
  134. data/spec/command/clean_spec.rb +0 -20
  135. data/spec/command/commit_spec.rb +0 -40
  136. data/spec/command/edit_spec.rb +0 -119
  137. data/spec/command/list_spec.rb +0 -42
  138. data/spec/command/open_spec.rb +0 -12
  139. data/spec/command/preview_spec.rb +0 -40
  140. data/spec/command/rebind_spec.rb +0 -276
  141. data/spec/support/example_group_helper.rb +0 -98
data/lib/retter/entry.rb CHANGED
@@ -1,129 +1,54 @@
1
- # coding: utf-8
2
-
3
- require 'nokogiri'
1
+ require 'active_model'
2
+ require 'date'
3
+ require 'time'
4
4
 
5
5
  module Retter
6
6
  class Entry
7
- class Article
8
- attr_accessor :entry, :id, :title, :body
9
-
10
- def initialize(attrs = {})
11
- attrs = {actual: true}.merge(attrs)
7
+ autoload :Article, 'retter/entry/article'
8
+ autoload :FindMethods, 'retter/entry/find_methods'
9
+ autoload :ModelBase, 'retter/entry/model_base'
10
+ autoload :Pagination, 'retter/entry/pagination'
11
+ autoload :SortMethods, 'retter/entry/sort_methods'
12
+ autoload :Utils, 'retter/entry/utils'
12
13
 
13
- @id, @entry, @title, @body, @actual = attrs.values_at(:id, :entry, :title, :body, :actual)
14
- end
15
-
16
- # XXX return false if generated by Entry#to_article
17
- def actual?
18
- @actual
19
- end
20
-
21
- def to_s
22
- body
23
- end
24
-
25
- def next
26
- articles[index.next] || (entry.next && entry.next.articles.first)
27
- end
14
+ class << self
15
+ attr_writer :all
28
16
 
29
- def prev
30
- index.pred < 0 ? (entry.prev && entry.prev.articles.last) : articles[index.pred]
17
+ def all
18
+ @all ||= []
31
19
  end
32
20
 
33
- def index
34
- articles.index(self).to_i
35
- end
36
-
37
- def articles
38
- @articles ||= entry.articles
39
- end
40
-
41
- def snippet(length = 200)
42
- snip = tags_stripped_body[0, length]
43
-
44
- tags_stripped_body.length > length ? "#{snip}..." : snip
45
- end
46
-
47
- def tags_stripped_body
48
- @tags_stripped_body ||= body.gsub(/<\/?\s?[^>]+>/, '')
21
+ def generate_entry_path(keyword = nil)
22
+ super
49
23
  end
50
24
  end
51
25
 
52
- attr_accessor :date, :lede, :body, :articles
53
- attr_reader :path
26
+ extend FindMethods
27
+ extend SortMethods
54
28
 
55
- def initialize(attrs = {})
56
- @entries, @date, @body = attrs.values_at(:entries, :date, :body)
29
+ include ModelBase
30
+ include Pagination
57
31
 
58
- path_by_date = Entries.retters_dir.join(date.strftime('%Y%m%d.md'))
59
- @path = attrs[:path] || path_by_date
32
+ attr_reader :source_path
33
+ attr_reader :date, :lede
34
+ attr_reader :articles
60
35
 
61
- extract_articles
62
- assign_lede
63
- end
36
+ def date_as_time
37
+ return unless date
64
38
 
65
- def to_s
66
- body
39
+ date.to_time.getutc
67
40
  end
68
41
 
69
- def next
70
- @entries[index.next]
42
+ def modified_at
43
+ source_path.try(:mtime)
71
44
  end
72
45
 
73
- def prev
74
- @entries[index.pred] unless index.pred < 0
46
+ def id
47
+ date.strftime('%Y%m%d')
75
48
  end
76
49
 
77
- def index
78
- @entries.index(self) || 0
79
- end
80
-
81
- def to_article
82
- Article.new(entry: self, id: 'a0', title: date.to_s, body: body, actual: false)
83
- end
84
-
85
- private
86
-
87
- def body_elements
88
- Nokogiri::HTML(body)
89
- end
90
-
91
- def assign_ids
92
- html = body_elements
93
- html.search('//h1').each_with_index do |h1, seq|
94
- h1.set_attribute 'id', "a#{seq}"
95
- end
50
+ alias to_param id
96
51
 
97
- @body = html.search('//body/*').to_s
98
- end
99
-
100
- def extract_articles
101
- assign_ids
102
-
103
- @articles = body_elements.search('body > *').each_with_object([]) {|c, articles|
104
- if c.name == 'h1'
105
- articles << Article.new(entry: self, id: c.attr('id'), title: c.text, body: '')
106
- else
107
- next if articles.empty?
108
-
109
- article = articles.last
110
- article.body += c.to_s
111
- end
112
- }
113
-
114
- @articles = [to_article] if @articles.empty?
115
- end
116
-
117
- def assign_lede
118
- @lede =
119
- if articles.any?(&:actual?)
120
- body_elements.search('body > *').each_with_object('') {|c, r|
121
- break r if c.name == 'h1'
122
- r << c.to_s
123
- }
124
- else
125
- ''
126
- end
127
- end
52
+ include Deprecated::Entry
128
53
  end
129
54
  end
@@ -0,0 +1,36 @@
1
+ module Retter
2
+ class Entry
3
+ class Article
4
+ class << self
5
+ def all
6
+ Entry.all.flat_map(&:articles)
7
+ end
8
+ end
9
+
10
+ include ModelBase
11
+ include Pagination
12
+
13
+ attr_reader :index, :title, :body
14
+ attr_reader :entry
15
+
16
+ def initialize(attrs = {})
17
+ @index, @title, @body, @entry = *attrs.values_at(:index, :title, :body, :entry)
18
+
19
+ @index ||= 0
20
+ end
21
+
22
+ def id
23
+ "#{entry.id}#{relative_code}"
24
+ end
25
+
26
+ def relative_code
27
+ "a#{index}"
28
+ end
29
+
30
+ # XXX: to_param should returns identifiable value
31
+ alias to_param relative_code
32
+
33
+ include Deprecated::Entry::Article
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,38 @@
1
+ require 'chronic'
2
+
3
+ module Retter
4
+ module Entry::FindMethods
5
+ def find(date = nil, &block)
6
+ if date
7
+ find_by_date(date)
8
+ else
9
+ all.find(&block)
10
+ end
11
+ end
12
+
13
+ def find_by_date(date)
14
+ all.find {|e| e.date == date }
15
+ end
16
+
17
+ def find_by_keyword(str)
18
+ case str = str.to_s
19
+ when nil, ''
20
+ return nil
21
+ when /^e([0-9]+)$/
22
+ find_by_index_num($1.to_i)
23
+ when /^([0-9a-z]+\.md)$/
24
+ find_by_file_name($1)
25
+ else
26
+ find(Entry::Utils.parse_date(str))
27
+ end
28
+ end
29
+
30
+ def find_by_index_num(num)
31
+ all[num]
32
+ end
33
+
34
+ def find_by_file_name(name)
35
+ all.find {|entry| entry.source_path.basename.to_s == name }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,10 @@
1
+ module Retter
2
+ module Entry::ModelBase
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ extend ActiveModel::Naming
7
+ include ActiveModel::Conversion
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ module Retter
2
+ module Entry::Pagination
3
+ def next
4
+ collection[index.succ]
5
+ end
6
+
7
+ def prev
8
+ return nil unless index.pred < 0
9
+
10
+ collection[index.pred]
11
+ end
12
+
13
+ private
14
+
15
+ def index
16
+ collection.index(self)
17
+ end
18
+
19
+ def collection
20
+ self.class.all
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ module Retter
2
+ module Entry::SortMethods
3
+ def order_by(attr)
4
+ all.sort_by(&attr.intern)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ module Retter::Entry::Utils
2
+ module_function
3
+
4
+ def parse_date(str)
5
+ str = str.to_s.gsub(/\./, ' ')
6
+ date_or_time = (Chronic.parse(str) || Date.parse(str)) rescue nil
7
+
8
+ return nil unless date_or_time
9
+
10
+ date_or_time.to_date
11
+ end
12
+ end
@@ -0,0 +1,45 @@
1
+ module Retter::Initializing
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+ # Usage:
6
+ # Retter.on_initialize do |config|
7
+ # initialize process
8
+ # -> { after initialize process (optional) }
9
+ # end
10
+ def on_initialize(&block)
11
+ call_initializers(block).tap do |after_initialize_hooks|
12
+ after_initialize_hooks.each &:call
13
+ end if initialized?
14
+
15
+ initializers << block
16
+ end
17
+
18
+ private
19
+
20
+ def process_initialize
21
+ call_initializers.tap do |after_initialize_hooks|
22
+ @initialized = true
23
+
24
+ after_initialize_hooks.each &:call
25
+ end
26
+ end
27
+
28
+ def initialized?; @initialized end
29
+
30
+ def initializers
31
+ @initializers ||= []
32
+ end
33
+
34
+ def call_initializers(procs = initializers)
35
+ Array(procs).each.with_object([]) {|initialize_proc, after_procs|
36
+ returned = initialize_proc.call(config)
37
+
38
+ after_procs << returned if returned.respond_to?(:call)
39
+ }
40
+ end
41
+
42
+ # should be overwrite
43
+ def config; end
44
+ end
45
+ end
@@ -1,24 +1,111 @@
1
- # coding: utf-8
2
-
3
- require 'grit'
1
+ require 'open3'
4
2
 
5
3
  module Retter
6
4
  class Repository
7
- def self.open(working_dir, &block)
8
- new(working_dir).open(&block)
5
+ class RepositoryError < RuntimeError; end
6
+
7
+ class << self
8
+ attr_accessor :path
9
+ attr_writer :git
10
+
11
+ def checkout(branch, *rest, &block)
12
+ new do |repo|
13
+ repo.checkout branch, *rest, &block
14
+ end
15
+ end
16
+
17
+ def git
18
+ @git ||= `which git`.strip.presence
19
+ end
20
+ end
21
+
22
+ attr_reader :path, :git
23
+
24
+ def initialize(path = Repository.path, git = Repository.git)
25
+ @path, @git = Pathname(path).expand_path, git
26
+
27
+ Dir.chdir path do
28
+ yield self
29
+ end if block_given?
30
+ end
31
+
32
+ def commit(*args)
33
+ run command('commit', *args), false
34
+ end
35
+
36
+ def checkout(*args, &block)
37
+ return do_checkout *args unless block
38
+
39
+ checkout_temporary *args, &block
40
+ end
41
+
42
+ def current_branch
43
+ extract_branch_name(branch_list.grep(/\*/).first)
44
+ end
45
+
46
+ def branches
47
+ branch_list.map {|str| extract_branch_name(str) }
9
48
  end
10
49
 
11
- def initialize(working_dir)
12
- @repo = Grit::Repo.new(working_dir.to_s)
50
+ %w(init add reset rm).each do |subcommand|
51
+ define_method subcommand do |*args|
52
+ run command(subcommand, *args)
53
+ end
13
54
  end
14
55
 
15
- def open
16
- pwd = Dir.pwd
17
- Dir.chdir @repo.working_dir
56
+ private
57
+
58
+ def branch_list
59
+ capture(command('branch')).split("\n")
60
+ end
61
+
62
+ def extract_branch_name(str)
63
+ str.sub(/\*/, '').strip
64
+ end
65
+
66
+ def checkout_temporary(*args)
67
+ _branch = current_branch
68
+
69
+ do_checkout *args
70
+ yield self
71
+ ensure
72
+ do_checkout _branch
73
+ end
74
+
75
+ def do_checkout(name, *rest)
76
+ return if name == current_branch
77
+
78
+ run command('checkout', name, *rest)
79
+ rescue
80
+ warn "WARNING: can't checkout #{name}"
81
+ end
82
+
83
+ def command(command, *args)
84
+ raise %(git command not found. Command failed: `#{command}'.) unless git
85
+
86
+ [git, command.to_s, *args.map(&:to_s)]
87
+ end
88
+
89
+ def capture(cmd, raise_on_fail = true)
90
+ value, status = Open3.capture2e(*cmd, chdir: path)
91
+
92
+ if status.success?
93
+ value.strip
94
+ else
95
+ if raise_on_fail
96
+ warn value
97
+ raise RepositoryError, "command failed: #{Array(cmd).join(' ')}"
98
+ end
99
+
100
+ false
101
+ end
102
+ end
18
103
 
19
- yield @repo
104
+ alias run capture
20
105
 
21
- Dir.chdir pwd
106
+ Retter.on_initialize do |config|
107
+ self.path = config.root
108
+ self.git = config.git
22
109
  end
23
110
  end
24
111
  end