zine 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a7ad3b9767a3c9799f9b328a1f28ca0435ca3b1b
4
+ data.tar.gz: ede87c6d35d6aae470c47c9df26c98259cbfe940
5
+ SHA512:
6
+ metadata.gz: 6e186e86c35fab7f7bd41ac7357c11585cf3a275bdc56618c426e79c9957ea138d45ffe46eddb3fd8986fabc408114f064bb209b2f20eb90427529cbe20ce7a2
7
+ data.tar.gz: 2d5f1023c075f0cb4b49c1c75ff9f2828f674e13a94ecff38e380f4021f3daa6911d332830ef71d57d5087cba0b9650ff8347811061da9ee3c0d1cd114968e19
@@ -0,0 +1,241 @@
1
+ # 100 Days Of Code - Log
2
+
3
+ ### Day 1: January 24, 2017
4
+
5
+ **Today's Progress**:
6
+
7
+ - set up the blog & repos, my first project is a static blog engine called Zine
8
+ - set up bundler, wrote some rspec tests & got the gem to build & installed it locally
9
+ - using Thor for the menu & as a generator for scaffold files for new blog posts is the first functional part of the gem
10
+
11
+ **Thoughts:**
12
+
13
+ I might push the code up every few days, not sure about that yet.
14
+
15
+ **Links to work**
16
+
17
+ 1. [(empty) Zine repo](https://github.com/mikekreuzer/zine)
18
+ 2. [Tweet](https://twitter.com/mikekreuzer/status/823876650316111872)
19
+ 3. [Blog](https://mikekreuzer.com/blog/2017/1/100-days-of-code.html)
20
+
21
+ ### Day 2: January 25, 2017
22
+
23
+ **Today's Progress**:
24
+
25
+ - generate a (still mostly empty) new site scaffold
26
+ - read a YAML options file
27
+ - have a Site object pushing file names to Page objects
28
+
29
+ **Thoughts:**
30
+
31
+ Next up is the the meat of the blog engine - reading the YAML & Markdown, generating the folder structure & pushing text through Kramdown & ERB. That's where I'd hoped to get to tonight.
32
+
33
+ **Links to work**
34
+
35
+ 1. [Tweet](https://twitter.com/mikekreuzer/status/824237414306627589)
36
+
37
+ ### Day 3: January 26, 2017
38
+
39
+ **Today's Progress**:
40
+
41
+ - reading the files' YAML front matter & Markdown
42
+ - generating the folder structure from the YAML dates (& spending ages with date errors in Psych.... they need to be quoted it turns out, it did used to know that I think)
43
+ - Kramdown
44
+
45
+ **Thoughts:**
46
+
47
+ Didn't get as far as the ERB templates - still have to translate my current Jade templates across, probably via the Jade's HTML output. That's for tomorrow.
48
+
49
+ Big time saver today was remembering to chain bash commands:
50
+ ```bash
51
+ gem uninstall zine -x && gem build zine.gemspec && gem install ./zine-0.1.0.gem
52
+ ```
53
+
54
+ **Links to work**
55
+
56
+ 1. [Tweet](https://twitter.com/mikekreuzer/status/824602333359190017)
57
+
58
+ ### Day 4: January 27, 2017
59
+
60
+ **Today's Progress**:
61
+
62
+ - moved the log to the Zine repo
63
+ - went with Slim templates instead - rendering & partials both working, yet to translate the existing templates though
64
+ - wrote some more rspec tests, played with cucumber for a while but decided not to use it, it's a DSL too far.
65
+
66
+ **Thoughts:**
67
+
68
+ Couldn't resist the terse syntax of Slim. Lagging behind on the test front.
69
+
70
+ **Links to work**
71
+
72
+ 1. [Tweet](https://twitter.com/mikekreuzer/status/824948475355762688)
73
+
74
+ ### Day 5: January 28, 2017
75
+
76
+ **Today's Progress**:
77
+
78
+ - dropped Slim, back with ERB - translation was going to take too long
79
+ - added HTML compression, even though the difference is only around 1kb a page
80
+
81
+ **Thoughts:**
82
+
83
+ Simplicity rules. Terse syntax is neat, but yet another DSL is a burden.
84
+
85
+ On a positive note I feel like I'm on a bit of a roll with this project now. Tags next, I think.
86
+
87
+ **Links to work**
88
+
89
+ 1. [Tweet](https://twitter.com/mikekreuzer/status/825327843059994625)
90
+
91
+ ### Day 6: January 29, 2017
92
+
93
+ **Today's Progress**:
94
+
95
+ - ERB partials
96
+ - working posts & tags
97
+ - draft of the README.md file
98
+
99
+ **Thoughts:**
100
+
101
+ I'm occasionally missing the safety check of a compile failing when using a compiled language. Also structs in Ruby aren't the best... but those are both partly a problem of my development habits. Still thinking about Cucumber & Slim, and seeing DSLs as a cost, as a topic for a blog post. Thinking of swapping colorize for pastel too (only because of the monkey patching).
102
+
103
+ Next up: the home & article list pages, pages that aren't posts like the about page, and copying across the CSS - all up that would probably represent a minimum viable product. Much less than I plan to do in the end, but enough for a first cut of the gem I think. End of week one tomorrow!
104
+
105
+ **Links to work**
106
+
107
+ 1. [Tweet](https://twitter.com/mikekreuzer/status/825689819204300800)
108
+
109
+ ### Day 7: January 30, 2017
110
+
111
+ **Today's Progress**:
112
+
113
+ - delete added as a CLI option
114
+ - refactoring of tags (to be continued, to swap out ERB::Util for a slug name method, I think)
115
+
116
+ **Thoughts:**
117
+
118
+ Might push the template and CSS folders into a layouts/default folder, in case anyone ever wants to make other layouts. Tomorrow. Busy day. One week though, nice.
119
+
120
+ **Links to work**
121
+
122
+ 1. [Tweet](https://twitter.com/mikekreuzer/status/826045386405998594)
123
+
124
+ ### Day 8: January 31, 2017
125
+
126
+ **Today's Progress**:
127
+
128
+ - replaced Colorize with Rainbow
129
+ - replaced ERB::Util with a slug name generator
130
+ - added dates to tag lists
131
+
132
+ **Thoughts:**
133
+
134
+ Refactoring my monolithic page class tomorrow, cleaning up tags was preparation for that.
135
+
136
+ **Links to work**
137
+
138
+ 1. [Tweet](https://twitter.com/mikekreuzer/status/826414672542732288)
139
+
140
+ ### Day 9: February 1, 2017
141
+
142
+ **Today's Progress**:
143
+
144
+ - Ripley for February
145
+ - Ripley 0.7.1
146
+
147
+ **Thoughts:**
148
+
149
+ A very brief break from Zine to detour back to some Elixir coding. The March edition of Ripley could be a Zine site, in time for its first anniversary in April.
150
+
151
+ **Links to work**
152
+
153
+ 1. [Ripley](https://mikekreuzer.github.io/Ripley/)
154
+ 2. [Ripley code](https://github.com/mikekreuzer/Ripley)
155
+ 3. [Tweet](https://twitter.com/mikekreuzer/status/826775864696147969)
156
+
157
+ ### Day 10: February 2, 2017
158
+
159
+ **Today's Progress**:
160
+
161
+ - copies files that aren't Markdown or templates to the build directory, preserving the folder structure
162
+ - a simple WEBrick server for preview, with SSL
163
+
164
+ **Thoughts:**
165
+
166
+ As well as breaking up Page I'm going to have break up a monolithic Site class, these things grow like topsy. Will do that when this cold abates.
167
+
168
+ **Links to work**
169
+
170
+ 1. [Tweet](https://twitter.com/mikekreuzer/status/827135313621311488)
171
+
172
+ ### Day 11: February 3, 2017
173
+
174
+ **Today's Progress**:
175
+
176
+ - moved yesterday's local server out of the site class
177
+
178
+ **Thoughts:**
179
+
180
+ Fruitlessly debugged ERB. The cold continues. Real progress when I stop coughing.
181
+
182
+ **Links to work**
183
+
184
+ 1. [Tweet](https://twitter.com/mikekreuzer/status/827504315430367232)
185
+
186
+ ### Day 12: February 4, 2017
187
+
188
+ **Today's Progress**:
189
+
190
+ - WEBrick swapped out for Thin - WEBrick's been ridiculously slow
191
+ - DataPage class carved out of Page
192
+ - home & all tags index pages
193
+
194
+ **Thoughts:**
195
+
196
+ The index page of all the tag pages is the first bit of Zine that pushes beyond the envelope of what I'm using now. That feels good.
197
+
198
+ I'm wondering how much of my memory of having speed issue with Jekyll was caused by WEBrick.
199
+
200
+ Finally starting to feel better, summer colds are the pits.
201
+
202
+ **Links to work**
203
+
204
+ 1. [Tweet](https://twitter.com/mikekreuzer/status/827857782330138628)
205
+
206
+ ### Day 13: February 5, 2017
207
+
208
+ **Today's Progress**:
209
+
210
+ - more serious site & page class refactoring
211
+ - pages that aren't blog posts
212
+ - started into RSS/Atom feeds, and the standard library docs are borderline nonexistent
213
+
214
+ **Thoughts:**
215
+
216
+ Lucky 13.
217
+
218
+ RSS would round out the two week mark nicely, if I get it to work. I have escaped content, but getting CDATA in there without writing the generator myself would be nice.
219
+
220
+ Two weeks to get the rough structure right, and to get something like a minimum viable product feels about right. While that would be much less than I intend to do it'd be time to start pushing code to GitHub & to release this as more than a stub of a gem. Tomorrow, maybe, with a bit of luck.
221
+
222
+ **Links to work**
223
+
224
+ 1. [Tweet](https://twitter.com/mikekreuzer/status/828231071770632193)
225
+
226
+ ### Day 14: February 6, 2017
227
+
228
+ **Today's Progress**:
229
+
230
+ - claimed the feed content's xhtml to get it to work, will revisit & fix this with CDATA
231
+ - started testing the engine against old blog posts
232
+ - first code to GitHub
233
+ - gem published
234
+
235
+ **Thoughts:**
236
+
237
+ Two weeks, and here's the first cut of code to GitHub & a (slightly) more than just a stub of a gem. Plenty of room to improve, but a nice start.
238
+
239
+ **Links to work**
240
+
241
+ To follow
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Mike Kreuzer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,82 @@
1
+ # zine
2
+ Yet another blog aware static site generator.
3
+
4
+ ## Warning: pre-release code
5
+
6
+ These are the very early days of zine, expect breaking changes.
7
+
8
+ ## Why yet another static blog engine?
9
+
10
+ Written in a #100DaysOfCode challenge -- my [progress log's here](CHANGELOG.md). Despite the [proliferation in these things][engine_list] (450!) I still find it more comfortable to use my own tools.
11
+
12
+ Presented here in the hope it's of use to someone else too.
13
+
14
+ ## Installation
15
+
16
+ Install the gem.
17
+
18
+ ```shell
19
+ $ gem install zine
20
+ ```
21
+
22
+ Then generate a new site scaffold, cd to a new folder and:
23
+
24
+ ```shell
25
+ $ zine site
26
+ ```
27
+
28
+ Then update your site's name, your name & so on in zine.yaml.
29
+
30
+ ## Day to day usage
31
+
32
+ To set up a new blog post:
33
+
34
+ ```shell
35
+ $ zine post 'Your chosen title'
36
+ ```
37
+
38
+ Your new post will have some fields set up in the YAML front matter, feel free to edit them too.
39
+
40
+ Once you're done writing, build your new site:
41
+
42
+ ```shell
43
+ $ zine build
44
+ ```
45
+
46
+ ### Halp!
47
+
48
+ To see the options available:
49
+
50
+ ```shell
51
+ $ zine
52
+ ```
53
+
54
+ ### Up next
55
+
56
+ This is only a first cut at this gem, the stuff I considered a (barely) minimum viable product. Up next are:
57
+
58
+ - CSS preprocessing
59
+ - file watching
60
+ - migration scripts from eg Jekyll? Maybe.
61
+ - Apple News
62
+ - SSH uploads, as well as
63
+ - much refactoring
64
+ - docs
65
+ - tests, lots of tests
66
+ - and a few other things
67
+
68
+ ## Contributing
69
+
70
+ Yes please. Bug reports and pull requests are welcome on GitHub at https://github.com/mikekreuzer/zine.
71
+
72
+ ## Tests
73
+
74
+ ```shell
75
+ bundle exec rspec spec # or your alias for that
76
+ ```
77
+
78
+ ## License
79
+
80
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
81
+
82
+ [engine_list]: https://staticsitegenerators.net
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'zine'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
+
4
+ require 'zine/cli'
5
+ Zine::CLI.start
@@ -0,0 +1,156 @@
1
+ require 'erb'
2
+ require 'rainbow'
3
+ require 'zine/data_page'
4
+ require 'zine/page'
5
+ require 'zine/feed'
6
+ require 'zine/post'
7
+ require 'zine/server'
8
+ require 'zine/tag'
9
+ require 'zine/templates'
10
+ require 'zine/version'
11
+
12
+ module Zine
13
+ # the site
14
+ class Site
15
+ attr_reader :options
16
+
17
+ def initialize
18
+ @post_array = []
19
+ @templates_by_name = {}
20
+ init_options
21
+ clean_option_paths
22
+ init_templates
23
+ end
24
+
25
+ def init_options
26
+ @options ||= begin
27
+ YAML.safe_load File.open('zine.yaml')
28
+ rescue ArgumentError => err
29
+ puts Rainbow("Could not parse YAML options: #{err.message}").red
30
+ end
31
+ end
32
+
33
+ def init_templates
34
+ tem_array = Dir[File.join(@options['directories']['templates'], '*.erb')]
35
+ tem_array.each do |tem|
36
+ @templates_by_name.merge!(File.basename(tem, '.*') =>
37
+ ERB.new(File.read(tem), 0, '-'))
38
+ end
39
+ end
40
+
41
+ def build_site
42
+ read_post_markdown_files
43
+ sort_posts_by_date
44
+ write_posts
45
+ housekeeping_copy
46
+ write_other_markdown_pages
47
+ write_feed
48
+ preview
49
+ end
50
+
51
+ def clean_option_paths
52
+ %w(assets posts styles templates).each do |dir|
53
+ @options['directories'][dir] =
54
+ File.join @options['directories']['source'],
55
+ @options['directories'][dir]
56
+ end
57
+ @options['directories']['blog'] =
58
+ File.join @options['directories']['build'],
59
+ @options['directories']['blog']
60
+ end
61
+
62
+ def housekeeping_copy
63
+ src_dir = @options['directories']['source']
64
+ search = File.join src_dir, '**', '*.*'
65
+ dir_options = @options['directories']
66
+ possible = Dir.glob(search, File::FNM_DOTMATCH).reject do |found|
67
+ found =~ /^.+\.md$|^.+\.erb$|^\.DS_Store$|^\.$|^\.\.$'/ ||
68
+ File.directory?(found) || found[dir_options['posts']] ||
69
+ found[dir_options['templates']]
70
+ end
71
+ possible.each do |file|
72
+ dir = Pathname(File.dirname(file)).relative_path_from(Pathname(src_dir))
73
+ filename = File.basename file
74
+ dest = File.join @options['directories']['build'], dir
75
+ FileUtils.mkdir_p dest
76
+ FileUtils.cp file, File.join(dest, filename)
77
+ end
78
+ end
79
+
80
+ def make_template_bundle(type)
81
+ TemplateFiles.new(
82
+ if @templates_by_name.key?(type)
83
+ @templates_by_name[type]
84
+ else
85
+ @templates_by_name['default']
86
+ end,
87
+ @templates_by_name['header_partial'],
88
+ @templates_by_name['footer_partial']
89
+ )
90
+ end
91
+
92
+ def preview
93
+ Server.new File.absolute_path(@options['directories']['build'])
94
+ end
95
+
96
+ def read_post_markdown_files
97
+ file_name_array = Dir[File.join(@options['directories']['posts'], '*.md')]
98
+ file_name_array.each do |file|
99
+ @post_array << Zine::Post.new(file,
100
+ make_template_bundle('post'),
101
+ @options)
102
+ end
103
+ end
104
+
105
+ def sort_posts_by_date
106
+ @post_array.sort_by! do |post|
107
+ post.formatted_data.page[:date_rfc3339]
108
+ end.reverse!
109
+ @post_array.freeze
110
+ end
111
+
112
+ def write_feed
113
+ number = @options['options']['number_items_in_RSS']
114
+ feed = Zine::Feed.new(@post_array.first(number), @options)
115
+ feed.process
116
+ end
117
+
118
+ def write_homepage
119
+ homepage_data = { build_dir: @options['directories']['build'],
120
+ name: 'index', title: 'Home', post_array: [] }
121
+ @post_array.first(@options['options']['num_items_on_home']).each do |post|
122
+ homepage_data[:post_array] << { page: post.formatted_data.page,
123
+ html: post.formatted_data.html }
124
+ end
125
+ home_page = DataPage.new(homepage_data, make_template_bundle('home'),
126
+ @options)
127
+ home_page.write
128
+ end
129
+
130
+ def write_other_markdown_pages
131
+ dir_options = @options['directories']
132
+ src_dir = dir_options['source']
133
+ search = File.join src_dir, '**', '*.md'
134
+ Dir[search].reject { |found| found[dir_options['posts']] }.each do |file|
135
+ dir = Pathname(File.dirname(file)).relative_path_from(Pathname(src_dir))
136
+ file_name = "#{File.basename(file, '.*')}.html"
137
+ dest = File.join dir_options['build'], dir
138
+ FileUtils.mkdir_p dest
139
+ page = Zine::Page.new(file, File.join(dest, file_name),
140
+ make_template_bundle('default'), @options)
141
+ page.process
142
+ end
143
+ end
144
+
145
+ def write_posts
146
+ tags_by_post = []
147
+ @post_array.each do |post|
148
+ tags_by_post << post.process
149
+ end
150
+ tags = Zine::Tag.new tags_by_post, make_template_bundle('tag'),
151
+ make_template_bundle('tag_index'), @options
152
+ tags.write_tags
153
+ write_homepage
154
+ end
155
+ end
156
+ end