ignoramos 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.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +18 -0
- data/Guardfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +63 -0
- data/Rakefile +8 -0
- data/bin/ignoramos +5 -0
- data/ignoramos.gemspec +22 -0
- data/lib/commands/build_command.rb +188 -0
- data/lib/commands/new_command.rb +34 -0
- data/lib/commands/tweet_command.rb +64 -0
- data/lib/ignoramos.rb +29 -0
- data/lib/models/app_config.rb +32 -0
- data/lib/models/page.rb +11 -0
- data/lib/models/post.rb +123 -0
- data/rebuild_gem +7 -0
- data/spec/commands/build_command_spec.rb +379 -0
- data/spec/commands/new_command_spec.rb +36 -0
- data/spec/commands/tweet_command_spec.rb +59 -0
- data/spec/models/app_config_spec.rb +66 -0
- data/spec/models/page_spec.rb +47 -0
- data/spec/models/post_spec.rb +156 -0
- data/spec/spec_helper.rb +2 -0
- metadata +105 -0
data/lib/ignoramos.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'commands/new_command'
|
2
|
+
require 'commands/build_command'
|
3
|
+
require 'commands/tweet_command'
|
4
|
+
|
5
|
+
class Ignoramos
|
6
|
+
def initialize(args = [])
|
7
|
+
command(args).execute
|
8
|
+
end
|
9
|
+
|
10
|
+
def command(args)
|
11
|
+
cmd = args[0] unless args.empty?
|
12
|
+
|
13
|
+
if cmd == 'new'
|
14
|
+
NewCommand.new(args[1])
|
15
|
+
elsif cmd == 'build'
|
16
|
+
BuildCommand.new
|
17
|
+
elsif cmd == 'tweet'
|
18
|
+
TweetCommand.new(args[1])
|
19
|
+
else
|
20
|
+
NilCommand.new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
NilCommand = Struct.new(:args) do
|
25
|
+
def execute
|
26
|
+
puts 'command not supported'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'redcarpet'
|
3
|
+
|
4
|
+
class AppConfig
|
5
|
+
attr_accessor :vars
|
6
|
+
|
7
|
+
def initialize(content)
|
8
|
+
@vars = YAML::load(content)
|
9
|
+
@vars = {} if @vars.nil?
|
10
|
+
end
|
11
|
+
|
12
|
+
def site_description
|
13
|
+
@site_description ||= html(site.fetch('description', ''))
|
14
|
+
end
|
15
|
+
|
16
|
+
def site_map
|
17
|
+
@site_map ||= html(site.fetch('site_map', ''))
|
18
|
+
end
|
19
|
+
|
20
|
+
def user
|
21
|
+
@user ||= site.fetch('user', '')
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def site
|
26
|
+
@site ||= vars.fetch('site', {})
|
27
|
+
end
|
28
|
+
|
29
|
+
def html(markdown)
|
30
|
+
Redcarpet::Markdown.new(Redcarpet::Render::HTML).render(markdown).strip
|
31
|
+
end
|
32
|
+
end
|
data/lib/models/page.rb
ADDED
data/lib/models/post.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'liquid'
|
3
|
+
require 'redcarpet'
|
4
|
+
require 'time'
|
5
|
+
require 'rouge'
|
6
|
+
require 'rouge/plugins/redcarpet'
|
7
|
+
|
8
|
+
class Post
|
9
|
+
attr_accessor :content
|
10
|
+
attr_accessor :vars
|
11
|
+
|
12
|
+
DEFAULT_VARS = {
|
13
|
+
'layout' => 'default',
|
14
|
+
'markup' => 'ext',
|
15
|
+
'timestamp' => DateTime.now
|
16
|
+
}
|
17
|
+
|
18
|
+
def initialize(content)
|
19
|
+
@content = strip_yaml(content)
|
20
|
+
@vars = DEFAULT_VARS.merge(YAML::load(content) || {})
|
21
|
+
end
|
22
|
+
|
23
|
+
def permalink
|
24
|
+
if @vars.has_key?('permalink')
|
25
|
+
"#{ path }/#{ normalize_custom_permalink }.html"
|
26
|
+
else
|
27
|
+
"#{ path }/#{ slug }.html"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def slug
|
32
|
+
return '' unless @vars['title']
|
33
|
+
@slug ||= @vars['title'].downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '')
|
34
|
+
end
|
35
|
+
|
36
|
+
def path
|
37
|
+
@path ||= "/#{ date.year }/#{ date.month.to_s.rjust(2, '0') }/#{ date.day.to_s.rjust(2, '0') }"
|
38
|
+
end
|
39
|
+
|
40
|
+
def html
|
41
|
+
@html ||= Liquid::Template.parse(markdown_to_html).render(@vars)
|
42
|
+
end
|
43
|
+
|
44
|
+
def timestamp
|
45
|
+
@timestamp ||= @vars['timestamp']
|
46
|
+
end
|
47
|
+
|
48
|
+
def title
|
49
|
+
@title ||= @vars['title']
|
50
|
+
end
|
51
|
+
|
52
|
+
def tags
|
53
|
+
return [] unless @vars['tags']
|
54
|
+
@tags ||= @vars['tags'].split(',').map { |x| x.strip }.sort
|
55
|
+
end
|
56
|
+
|
57
|
+
def external_link
|
58
|
+
@external_link ||= @vars['external_link']
|
59
|
+
end
|
60
|
+
|
61
|
+
def title_link
|
62
|
+
@title_link ||= if has_external_link?
|
63
|
+
external_link
|
64
|
+
else
|
65
|
+
permalink
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def post_type
|
70
|
+
@post_type ||= has_external_link? ? :link_post : :self_post
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_liquid
|
74
|
+
{
|
75
|
+
'html' => html,
|
76
|
+
'title' => title,
|
77
|
+
'permalink' => permalink,
|
78
|
+
'slug' => slug,
|
79
|
+
'timestamp' => timestamp.iso8601,
|
80
|
+
'tags' => tags,
|
81
|
+
'external_link' => external_link,
|
82
|
+
'post_type' => post_type.to_s,
|
83
|
+
'title_link' => title_link,
|
84
|
+
'layout' => @vars['layout']
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
protected
|
89
|
+
def normalize_custom_permalink
|
90
|
+
permalink = @vars['permalink']
|
91
|
+
if permalink[0] == '/'
|
92
|
+
return permalink[1..-1]
|
93
|
+
else
|
94
|
+
return permalink
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
def post_vars
|
100
|
+
end
|
101
|
+
|
102
|
+
def has_external_link?
|
103
|
+
!external_link.nil?
|
104
|
+
end
|
105
|
+
|
106
|
+
def strip_yaml(text)
|
107
|
+
text.to_s.gsub(/---(.|\n)*---/, '').strip
|
108
|
+
end
|
109
|
+
|
110
|
+
def date
|
111
|
+
@date ||= timestamp.to_date
|
112
|
+
end
|
113
|
+
|
114
|
+
def markdown_to_html
|
115
|
+
Redcarpet::Markdown.new(Redcarpet::Render::HTML).
|
116
|
+
render(@content).
|
117
|
+
strip
|
118
|
+
end
|
119
|
+
|
120
|
+
class HTML < Redcarpet::Render::HTML
|
121
|
+
include Rouge::Plugins::Redcarpet
|
122
|
+
end
|
123
|
+
end
|
data/rebuild_gem
ADDED
@@ -0,0 +1,379 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'commands/build_command'
|
3
|
+
require 'commands/new_command'
|
4
|
+
|
5
|
+
RSpec.describe BuildCommand do
|
6
|
+
describe '#execute' do
|
7
|
+
let(:test_dir) { 'tmp/testsite' }
|
8
|
+
let(:command) { BuildCommand.new(test_dir) }
|
9
|
+
|
10
|
+
before do
|
11
|
+
FileUtils.rm_rf(test_dir)
|
12
|
+
NewCommand.new(test_dir).execute
|
13
|
+
|
14
|
+
FileUtils.mkdir_p("#{ test_dir }/_includes/default")
|
15
|
+
FileUtils.mkdir_p("#{ test_dir }/_layouts/default")
|
16
|
+
FileUtils.mkdir_p("#{ test_dir }/rand/dir")
|
17
|
+
|
18
|
+
new_post_file = File.new("#{ test_dir }/rand/dir/test-post.html", 'w')
|
19
|
+
new_post_file.write('random data')
|
20
|
+
new_post_file.close
|
21
|
+
|
22
|
+
new_post_file = File.new("#{ test_dir }/testfile", 'w')
|
23
|
+
new_post_file.write('test data')
|
24
|
+
new_post_file.close
|
25
|
+
|
26
|
+
new_post_file = File.new("#{ test_dir }/_includes/default/_header.liquid", 'w')
|
27
|
+
new_post_file.write('header {{title}} {{site.description}}')
|
28
|
+
new_post_file.close
|
29
|
+
|
30
|
+
new_post_file = File.new("#{ test_dir }/_includes/default/_footer.liquid", 'w')
|
31
|
+
new_post_file.write('footer {{title}} {{site.description}}')
|
32
|
+
new_post_file.close
|
33
|
+
|
34
|
+
new_post_file = File.new("#{ test_dir }/_includes/default/_post.liquid", 'w')
|
35
|
+
new_post_file.write('{{post.html}}{{post.permalink}}')
|
36
|
+
new_post_file.close
|
37
|
+
|
38
|
+
new_post_file = File.new("#{ test_dir }/_includes/default/_page.liquid", 'w')
|
39
|
+
new_post_file.write('{{page.html}}{{post.permalink}}')
|
40
|
+
new_post_file.close
|
41
|
+
|
42
|
+
layout = <<-LAYOUT
|
43
|
+
{% include 'default/header' %}
|
44
|
+
|
45
|
+
{% for tag in tags %}
|
46
|
+
\#{{ tag.name }}
|
47
|
+
{% for post in tag.posts %}
|
48
|
+
{{ post.title }}
|
49
|
+
{% endfor %}
|
50
|
+
{% endfor %}
|
51
|
+
|
52
|
+
{% include 'default/footer' %}
|
53
|
+
LAYOUT
|
54
|
+
|
55
|
+
new_post_file = File.new("#{ test_dir }/_layouts/default/tags.liquid", 'w')
|
56
|
+
new_post_file.write(layout)
|
57
|
+
new_post_file.close
|
58
|
+
|
59
|
+
layout = <<-LAYOUT
|
60
|
+
{% include 'default/header' %}
|
61
|
+
|
62
|
+
{% for post in posts %}
|
63
|
+
{% include 'default/post' %}
|
64
|
+
{% endfor %}
|
65
|
+
|
66
|
+
{% include 'default/footer' %}
|
67
|
+
LAYOUT
|
68
|
+
|
69
|
+
new_post_file = File.new("#{ test_dir }/_layouts/default/posts.liquid", 'w')
|
70
|
+
new_post_file.write(layout)
|
71
|
+
new_post_file.close
|
72
|
+
|
73
|
+
layout = <<-LAYOUT
|
74
|
+
{% include 'default/header' %}
|
75
|
+
|
76
|
+
{% include 'default/post' %}
|
77
|
+
|
78
|
+
{% include 'default/footer' %}
|
79
|
+
LAYOUT
|
80
|
+
|
81
|
+
new_post_file = File.new("#{ test_dir }/_layouts/default/post.liquid", 'w')
|
82
|
+
new_post_file.write(layout)
|
83
|
+
new_post_file.close
|
84
|
+
|
85
|
+
layout = <<-LAYOUT
|
86
|
+
{% include 'default/header' %}
|
87
|
+
|
88
|
+
{% include 'default/page' %}
|
89
|
+
|
90
|
+
{% include 'default/footer' %}
|
91
|
+
LAYOUT
|
92
|
+
|
93
|
+
new_post_file = File.new("#{ test_dir }/_layouts/default/page.liquid", 'w')
|
94
|
+
new_post_file.write(layout)
|
95
|
+
new_post_file.close
|
96
|
+
|
97
|
+
page = <<-POST
|
98
|
+
---
|
99
|
+
title: First Page
|
100
|
+
timestamp: 2014-07-27T00:26:45-04:00
|
101
|
+
tags: tag1, tag2
|
102
|
+
permalink: custom-perm
|
103
|
+
---
|
104
|
+
|
105
|
+
Hey page!
|
106
|
+
POST
|
107
|
+
|
108
|
+
new_post_file = File.new("#{ test_dir }/_pages/hello-world-pt-3.md", 'w')
|
109
|
+
new_post_file.write(page)
|
110
|
+
new_post_file.close
|
111
|
+
|
112
|
+
page = <<-POST
|
113
|
+
---
|
114
|
+
title: First Page
|
115
|
+
timestamp: 2014-07-27T00:26:45-04:00
|
116
|
+
tags: tag1, tag2
|
117
|
+
---
|
118
|
+
|
119
|
+
Hey page!
|
120
|
+
POST
|
121
|
+
|
122
|
+
new_post_file = File.new("#{ test_dir }/_pages/hello-world-pt-2.md", 'w')
|
123
|
+
new_post_file.write(page)
|
124
|
+
new_post_file.close
|
125
|
+
|
126
|
+
post = <<-POST
|
127
|
+
---
|
128
|
+
title: First Post
|
129
|
+
timestamp: 2014-07-27T00:26:45-04:00
|
130
|
+
tags: tag1, tag2
|
131
|
+
---
|
132
|
+
|
133
|
+
Hey world!
|
134
|
+
POST
|
135
|
+
|
136
|
+
new_post_file = File.new("#{ test_dir }/_posts/2014-07-27-hello-world-pt-2.md", 'w')
|
137
|
+
new_post_file.write(post)
|
138
|
+
new_post_file.close
|
139
|
+
|
140
|
+
post = <<-POST
|
141
|
+
---
|
142
|
+
title: Test Post
|
143
|
+
timestamp: 2014-06-22T00:26:45-04:00
|
144
|
+
tags: tag2, tag3
|
145
|
+
---
|
146
|
+
|
147
|
+
This is a test post. It's title is {{title}}.
|
148
|
+
POST
|
149
|
+
|
150
|
+
new_post_file = File.new("#{ test_dir }/_posts/2014-06-22-hello-world.md", 'w')
|
151
|
+
new_post_file.write(post)
|
152
|
+
new_post_file.close
|
153
|
+
|
154
|
+
post = <<-POST
|
155
|
+
---
|
156
|
+
title: Another Test Post
|
157
|
+
timestamp: 2014-06-22T00:26:45-04:00
|
158
|
+
tags: tag2, tag3
|
159
|
+
---
|
160
|
+
|
161
|
+
This is a test post. It's title is {{title}}.
|
162
|
+
POST
|
163
|
+
|
164
|
+
new_post_file = File.new("#{ test_dir }/_posts/2014-06-22-another-world.md", 'w')
|
165
|
+
new_post_file.write(post)
|
166
|
+
new_post_file.close
|
167
|
+
|
168
|
+
FileUtils.mkdir_p("#{ test_dir }/2014/06/22")
|
169
|
+
new_post_file = File.new("#{ test_dir }/2014/06/22/another-test-post.html", 'w')
|
170
|
+
new_post_file.write('overridden data')
|
171
|
+
new_post_file.close
|
172
|
+
|
173
|
+
command.execute
|
174
|
+
end
|
175
|
+
|
176
|
+
describe 'tag index' do
|
177
|
+
it 'lists all posts ordered by tags' do
|
178
|
+
contents = File.open("#{ test_dir }/_site/tags.html", 'r') do |file|
|
179
|
+
file.read()
|
180
|
+
end
|
181
|
+
|
182
|
+
actual = <<-ACTUAL
|
183
|
+
header Tag Index - My First Blog <p>Site description</p>
|
184
|
+
|
185
|
+
|
186
|
+
#tag1
|
187
|
+
|
188
|
+
First Post
|
189
|
+
|
190
|
+
|
191
|
+
#tag2
|
192
|
+
|
193
|
+
Another Test Post
|
194
|
+
|
195
|
+
First Post
|
196
|
+
|
197
|
+
Test Post
|
198
|
+
|
199
|
+
|
200
|
+
#tag3
|
201
|
+
|
202
|
+
Another Test Post
|
203
|
+
|
204
|
+
Test Post
|
205
|
+
|
206
|
+
|
207
|
+
|
208
|
+
footer Tag Index - My First Blog <p>Site description</p>
|
209
|
+
ACTUAL
|
210
|
+
|
211
|
+
expect(contents).to eq(actual)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe 'tag index per tag' do
|
216
|
+
it 'lists all posts ordered alphabetically' do
|
217
|
+
contents = File.open("#{ test_dir }/_site/tags/tag1.html", 'r') do |file|
|
218
|
+
file.read()
|
219
|
+
end
|
220
|
+
|
221
|
+
actual = <<-ACTUAL
|
222
|
+
header #tag1 - My First Blog <p>Site description</p>
|
223
|
+
|
224
|
+
|
225
|
+
#tag1
|
226
|
+
|
227
|
+
First Post
|
228
|
+
|
229
|
+
|
230
|
+
|
231
|
+
footer #tag1 - My First Blog <p>Site description</p>
|
232
|
+
ACTUAL
|
233
|
+
expect(contents).to eq(actual)
|
234
|
+
|
235
|
+
contents = File.open("#{ test_dir }/_site/tags/tag2.html", 'r') do |file|
|
236
|
+
file.read()
|
237
|
+
end
|
238
|
+
|
239
|
+
actual = <<-ACTUAL
|
240
|
+
header #tag2 - My First Blog <p>Site description</p>
|
241
|
+
|
242
|
+
|
243
|
+
#tag2
|
244
|
+
|
245
|
+
Another Test Post
|
246
|
+
|
247
|
+
First Post
|
248
|
+
|
249
|
+
Test Post
|
250
|
+
|
251
|
+
|
252
|
+
|
253
|
+
footer #tag2 - My First Blog <p>Site description</p>
|
254
|
+
ACTUAL
|
255
|
+
expect(contents).to eq(actual)
|
256
|
+
contents = File.open("#{ test_dir }/_site/tags/tag3.html", 'r') do |file|
|
257
|
+
file.read()
|
258
|
+
end
|
259
|
+
|
260
|
+
actual = <<-ACTUAL
|
261
|
+
header #tag3 - My First Blog <p>Site description</p>
|
262
|
+
|
263
|
+
|
264
|
+
#tag3
|
265
|
+
|
266
|
+
Another Test Post
|
267
|
+
|
268
|
+
Test Post
|
269
|
+
|
270
|
+
|
271
|
+
|
272
|
+
footer #tag3 - My First Blog <p>Site description</p>
|
273
|
+
ACTUAL
|
274
|
+
expect(contents).to eq(actual)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
describe 'home page' do
|
279
|
+
it 'prints the last 5 posts in descending order' do
|
280
|
+
contents = File.open("#{ test_dir }/_site/index.html", 'r') do |file|
|
281
|
+
file.read()
|
282
|
+
end
|
283
|
+
|
284
|
+
actual = <<-ACTUAL
|
285
|
+
header My First Blog <p>Site description</p>
|
286
|
+
|
287
|
+
|
288
|
+
<p>Hey world!</p>/2014/07/27/first-post.html
|
289
|
+
|
290
|
+
<p>This is a test post. It's title is Test Post.</p>/2014/06/22/test-post.html
|
291
|
+
|
292
|
+
<p>This is a test post. It's title is Another Test Post.</p>/2014/06/22/another-test-post.html
|
293
|
+
|
294
|
+
|
295
|
+
footer My First Blog <p>Site description</p>
|
296
|
+
ACTUAL
|
297
|
+
|
298
|
+
expect(contents).to eq(actual)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
it 'drops rendered pages into the _site directory' do
|
303
|
+
contents = File.open("#{ test_dir }/_site/first-page.html", 'r') do |file|
|
304
|
+
file.read()
|
305
|
+
end
|
306
|
+
|
307
|
+
actual = <<-ACTUAL
|
308
|
+
header First Page - My First Blog <p>Site description</p>
|
309
|
+
|
310
|
+
<p>Hey page!</p>
|
311
|
+
|
312
|
+
footer First Page - My First Blog <p>Site description</p>
|
313
|
+
ACTUAL
|
314
|
+
|
315
|
+
expect(contents).to eq(actual)
|
316
|
+
|
317
|
+
contents = File.open("#{ test_dir }/_site/custom-perm.html", 'r') do |file|
|
318
|
+
file.read()
|
319
|
+
end
|
320
|
+
|
321
|
+
actual = <<-ACTUAL
|
322
|
+
header First Page - My First Blog <p>Site description</p>
|
323
|
+
|
324
|
+
<p>Hey page!</p>
|
325
|
+
|
326
|
+
footer First Page - My First Blog <p>Site description</p>
|
327
|
+
ACTUAL
|
328
|
+
|
329
|
+
expect(contents).to eq(actual)
|
330
|
+
end
|
331
|
+
|
332
|
+
it 'drops rendered posts into the _site directory' do
|
333
|
+
contents = File.open("#{ test_dir }/_site/2014/07/27/first-post.html", 'r') do |file|
|
334
|
+
file.read()
|
335
|
+
end
|
336
|
+
|
337
|
+
actual = <<-ACTUAL
|
338
|
+
header First Post - My First Blog <p>Site description</p>
|
339
|
+
|
340
|
+
<p>Hey world!</p>/2014/07/27/first-post.html
|
341
|
+
|
342
|
+
footer First Post - My First Blog <p>Site description</p>
|
343
|
+
ACTUAL
|
344
|
+
|
345
|
+
expect(contents).to eq(actual)
|
346
|
+
|
347
|
+
contents = File.open("#{ test_dir }/_site/2014/06/22/test-post.html", 'r') do |file|
|
348
|
+
file.read()
|
349
|
+
end
|
350
|
+
|
351
|
+
actual = <<-ACTUAL
|
352
|
+
header Test Post - My First Blog <p>Site description</p>
|
353
|
+
|
354
|
+
<p>This is a test post. It's title is Test Post.</p>/2014/06/22/test-post.html
|
355
|
+
|
356
|
+
footer Test Post - My First Blog <p>Site description</p>
|
357
|
+
ACTUAL
|
358
|
+
|
359
|
+
expect(contents).to eq(actual)
|
360
|
+
end
|
361
|
+
|
362
|
+
context 'custom files' do
|
363
|
+
it 'copies all files not in _ folders into _site' do
|
364
|
+
contents = File.open("#{ test_dir }/_site/rand/dir/test-post.html", 'r').
|
365
|
+
read
|
366
|
+
expect(contents).to eq('random data')
|
367
|
+
|
368
|
+
contents = File.open("#{ test_dir }/_site/testfile", 'r').read
|
369
|
+
expect(contents).to eq('test data')
|
370
|
+
end
|
371
|
+
|
372
|
+
it 'overrides existing files' do
|
373
|
+
contents = File.open("#{ test_dir }/_site/2014/06/22/another-test-post.html", 'r').
|
374
|
+
read
|
375
|
+
expect(contents).to eq('overridden data')
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
379
|
+
end
|