middleman-webcomic 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/ChangeLog.md +11 -0
- data/Gemfile +3 -0
- data/License +18 -0
- data/Rakefile +22 -0
- data/Readme.md +22 -0
- data/lib/middleman-webcomic/cli.rb +5 -0
- data/lib/middleman-webcomic/data.rb +213 -0
- data/lib/middleman-webcomic/feature.rb +172 -0
- data/lib/middleman-webcomic/mock_app.rb +31 -0
- data/lib/middleman-webcomic/pager.rb +51 -0
- data/lib/middleman-webcomic/tasks.rb +53 -0
- data/lib/middleman-webcomic/template/Gemfile.tt +7 -0
- data/lib/middleman-webcomic/template/Rakefile.tt +28 -0
- data/lib/middleman-webcomic/template/config.ru +16 -0
- data/lib/middleman-webcomic/template/config.tt +71 -0
- data/lib/middleman-webcomic/template/source/about.html.slim +11 -0
- data/lib/middleman-webcomic/template/source/comics/index.html.slim +14 -0
- data/lib/middleman-webcomic/template/source/comics/template.html.slim +1 -0
- data/lib/middleman-webcomic/template/source/feed.xml.builder +30 -0
- data/lib/middleman-webcomic/template/source/index.html.slim +1 -0
- data/lib/middleman-webcomic/template/source/layout.slim +63 -0
- data/lib/middleman-webcomic/template/source/robots.txt +3 -0
- data/lib/middleman-webcomic/template/source/theme/_comic.slim +4 -0
- data/lib/middleman-webcomic/template/source/theme/_layout_tall.slim +17 -0
- data/lib/middleman-webcomic/template/source/theme/_layout_wide.slim +16 -0
- data/lib/middleman-webcomic/template/source/theme/_sidebar.slim +13 -0
- data/lib/middleman-webcomic/template/source/theme/images/favicon.png +0 -0
- data/lib/middleman-webcomic/template/source/theme/scripts/app.js.coffee +4 -0
- data/lib/middleman-webcomic/template/source/theme/styles/_utils.scss +399 -0
- data/lib/middleman-webcomic/template/source/theme/styles/screen.css.sass +89 -0
- data/lib/middleman-webcomic/template.rb +30 -0
- data/lib/middleman-webcomic/version.rb +7 -0
- data/lib/middleman-webcomic.rb +11 -0
- data/lib/middleman_init.rb +1 -0
- data/middleman-webcomic.gemspec +29 -0
- metadata +113 -0
data/.gitignore
ADDED
data/ChangeLog.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# v0.5.0
|
2
|
+
- Updated to support Middleman's new auto-discovery.
|
3
|
+
- Includes boilerplate site.
|
4
|
+
|
5
|
+
# v0.4.0
|
6
|
+
- Added storyline support and helpers.
|
7
|
+
|
8
|
+
This introduces a breaking change to how the data is added to middle data_content, fortunately I'm the only one using it right now. :)
|
9
|
+
|
10
|
+
# v0.2.1
|
11
|
+
- Initial release. Yay!
|
data/Gemfile
ADDED
data/License
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (C) 2011 by Matt McCray
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
2
|
+
require "middleman-webcomic/version"
|
3
|
+
|
4
|
+
desc "builds gem"
|
5
|
+
task :build do
|
6
|
+
system "gem build middleman-webcomic.gemspec"
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "releases gem"
|
10
|
+
task :release => :build do
|
11
|
+
system "gem push middleman-webcomic-#{Middleman::Webcomic::VERSION}.gem"
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "installs gem"
|
15
|
+
task :install => :build do
|
16
|
+
system "gem install middleman-webcomic-#{Middleman::Webcomic::VERSION}"
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "uninstalls gem"
|
20
|
+
task :uninstall do
|
21
|
+
system "gem uninstall middleman-webcomic"
|
22
|
+
end
|
data/Readme.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Webcomic for MiddleMan
|
2
|
+
|
3
|
+
*Updated for Middleman auto-discovery.*
|
4
|
+
|
5
|
+
After you install the gem:
|
6
|
+
|
7
|
+
gem install middleman-webcomic
|
8
|
+
|
9
|
+
Create a new webcomic site like this:
|
10
|
+
|
11
|
+
middleman init MY_SITE --template=webcomic
|
12
|
+
|
13
|
+
Then customize to your satisfaction.
|
14
|
+
|
15
|
+
# Live Sites
|
16
|
+
|
17
|
+
This extension is used in conjunction with MiddleMan on the following sites:
|
18
|
+
|
19
|
+
* [ZooDotCom](http://www.zoodotcom.com)
|
20
|
+
* [Tactless Comics](http://tactless.inkwellian.com)
|
21
|
+
* [Darkshore Detectives](http://darkshore.inkwellian.com)
|
22
|
+
|
@@ -0,0 +1,213 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
class String
|
5
|
+
def create_slug
|
6
|
+
s= self.downcase.gsub(/'/, '').gsub(/[^a-z0-9]+/, '-')
|
7
|
+
s.chop! if s[-1] == '-'
|
8
|
+
s
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Middleman
|
13
|
+
|
14
|
+
module Webcomic
|
15
|
+
|
16
|
+
def self.load_from(path, app)
|
17
|
+
all= []
|
18
|
+
Dir["#{path}/*.comic*"].each do |filename| # Hardcoded for markdown... For now
|
19
|
+
comic = Comic.new(filename, app)
|
20
|
+
#puts comic.pub_date.inspect
|
21
|
+
all << comic if comic.publishable?
|
22
|
+
end
|
23
|
+
|
24
|
+
if app.settings.webcomic_sort_by == :publish_date
|
25
|
+
all.sort! {|x,y| y.pub_date <=> x.pub_date }
|
26
|
+
else
|
27
|
+
fld= app.settings.webcomic_sort_by
|
28
|
+
all.sort! {|x,y| y[fld] <=> x[fld] }
|
29
|
+
end
|
30
|
+
|
31
|
+
# Update all the position info...
|
32
|
+
cl= all.length
|
33
|
+
all.each_with_index do |comic, i|
|
34
|
+
comic[:position]= (cl - i)
|
35
|
+
comic[:index]= i
|
36
|
+
comic.first= all[-1]
|
37
|
+
comic.last= all[0]
|
38
|
+
comic.next= i > 0 ? all[i - 1] : nil
|
39
|
+
comic.prev= i < (cl - 1) ? all[i + 1] : nil
|
40
|
+
if app.settings.webcomic_enable_stories and comic.story
|
41
|
+
Story.find_or_create_for comic
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
stories= Story.all
|
46
|
+
stories.sort! {|x,y| y.pub_date <=> x.pub_date }
|
47
|
+
sl= stories.length
|
48
|
+
stories.each_with_index do |story, i|
|
49
|
+
story.position= (sl - i)
|
50
|
+
# puts "##{story.position} - #{story.title}(#{story.slug}): #{story.comics.length}"
|
51
|
+
end
|
52
|
+
|
53
|
+
[all, stories]
|
54
|
+
end
|
55
|
+
|
56
|
+
class Story
|
57
|
+
attr_accessor :title, :slug, :comics, :position
|
58
|
+
|
59
|
+
def initialize(title)
|
60
|
+
@title= title
|
61
|
+
@slug= @title.create_slug
|
62
|
+
@comics= []
|
63
|
+
@position= nil
|
64
|
+
end
|
65
|
+
|
66
|
+
def pub_date
|
67
|
+
@comics.last.pub_date
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_comic(comic)
|
71
|
+
@comics << comic
|
72
|
+
end
|
73
|
+
|
74
|
+
class << self
|
75
|
+
|
76
|
+
def all
|
77
|
+
@stories ||= {}
|
78
|
+
@stories.values
|
79
|
+
end
|
80
|
+
|
81
|
+
def find_or_create_for(comic)
|
82
|
+
title= comic.story
|
83
|
+
@stories ||= {}
|
84
|
+
unless @stories.has_key? title
|
85
|
+
story= @stories[title]= new(title)
|
86
|
+
end
|
87
|
+
@stories[title].add_comic comic
|
88
|
+
@stories[title]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class Comic
|
94
|
+
|
95
|
+
attr_accessor :content, :source, :metadata, :path, :next, :prev, :first, :last
|
96
|
+
|
97
|
+
def initialize(path, app)
|
98
|
+
@app= app
|
99
|
+
settings= app.settings
|
100
|
+
@path= path
|
101
|
+
@source= ""
|
102
|
+
@content= ""
|
103
|
+
@next= nil
|
104
|
+
@prev= nil
|
105
|
+
@first= nil
|
106
|
+
@last= nil
|
107
|
+
@metadata= ::Thor::CoreExt::HashWithIndifferentAccess.new({})
|
108
|
+
@metadata[:ext]= File.extname(path)
|
109
|
+
@metadata[:publish_date]= Date.today #Time.now.strftime "%Y-%m-%d"
|
110
|
+
@metadata[:slug]= File.basename(path).gsub( @metadata[:ext], '').gsub('.comic','')
|
111
|
+
|
112
|
+
if /^([\d]{2})([\d]{2})([\d]{2})\-(.*)(\.comic#{@metadata[:ext]})$/ =~ File.basename(path)
|
113
|
+
year= "20#{ $1 }"
|
114
|
+
month= $2
|
115
|
+
day= $3
|
116
|
+
@metadata[:publish_date]= Date.parse "#{year}-#{month}-#{day}"
|
117
|
+
@metadata[:slug]= $4
|
118
|
+
end
|
119
|
+
|
120
|
+
@metadata[:title]= @metadata[:slug].titleize rescue @metadata[:slug]
|
121
|
+
@metadata[:slug]= @metadata[:slug].downcase
|
122
|
+
|
123
|
+
# Parse yaml header...
|
124
|
+
begin
|
125
|
+
read_yaml()
|
126
|
+
rescue
|
127
|
+
puts "Error reading YAML! #{self.slug}"
|
128
|
+
end
|
129
|
+
|
130
|
+
if self.filename.nil?
|
131
|
+
throw "Filename Missing: Comics must define a filename! (#{self.slug})"
|
132
|
+
end
|
133
|
+
|
134
|
+
if publishable?
|
135
|
+
# Dont' waste time if it's not a publishable comic
|
136
|
+
engine= Tilt[path].new { @source }
|
137
|
+
@content= engine.render
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def [](key)
|
142
|
+
@metadata[key]
|
143
|
+
end
|
144
|
+
def []=(key, value)
|
145
|
+
#puts "Setting #{key} to #{value}"
|
146
|
+
@metadata[key]= value
|
147
|
+
end
|
148
|
+
|
149
|
+
def method_missing(key, value=nil)
|
150
|
+
if @metadata.has_key? key
|
151
|
+
@metadata[key]
|
152
|
+
elsif @metadata.has_key? key.to_s
|
153
|
+
@metadata[key.to_s]
|
154
|
+
else
|
155
|
+
#super Should it throw an error?
|
156
|
+
nil
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def to_json *a
|
161
|
+
data= @metadata.reject {|k,v| k == :ext or k == "ext" }
|
162
|
+
data.to_json *a
|
163
|
+
end
|
164
|
+
|
165
|
+
def publishable?
|
166
|
+
@is_publishable ||= begin
|
167
|
+
now= Time.now
|
168
|
+
now_string = now.strftime "%Y-%m-%d"
|
169
|
+
today= Date.parse(now_string)
|
170
|
+
pubdate= self.pub_date
|
171
|
+
case pubdate
|
172
|
+
when String
|
173
|
+
self['publish_date']= Date.parse(pubdate)
|
174
|
+
pubdate <= now_string
|
175
|
+
when Time
|
176
|
+
self['publish_date']= Date.parse(pubdate.strftime('%Y-%m-%d'))
|
177
|
+
pubdate <= now
|
178
|
+
when Date
|
179
|
+
pubdate <= today
|
180
|
+
else
|
181
|
+
true
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def pub_date
|
187
|
+
date= self.publish_on || self.publish_date || self.date
|
188
|
+
case date
|
189
|
+
when String
|
190
|
+
Date.parse(date)
|
191
|
+
when Time
|
192
|
+
Date.parse(date.strftime('%Y-%m-%d'))
|
193
|
+
when Date
|
194
|
+
date
|
195
|
+
else
|
196
|
+
Date.today
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
private
|
201
|
+
|
202
|
+
def read_yaml()
|
203
|
+
@raw = File.read(@path)
|
204
|
+
data, source= @app.parse_front_matter @raw
|
205
|
+
data.each_pair do |k,v|
|
206
|
+
@metadata[k]= v
|
207
|
+
end
|
208
|
+
@source= source
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Middleman
|
4
|
+
module Features
|
5
|
+
module Webcomic
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def registered(app)
|
9
|
+
puts "Webcomic v#{::Middleman::Webcomic::VERSION}"
|
10
|
+
|
11
|
+
# Default settings:
|
12
|
+
app.set :webcomic_images, "images/comics"
|
13
|
+
app.set :webcomic_source, "comics"
|
14
|
+
app.set :webcomic_source_images, "comics/images"
|
15
|
+
app.set :webcomic_source_type, :markdown
|
16
|
+
app.set :webcomic_uri, "comics"
|
17
|
+
app.set :webcomic_template, "/comics/template.html"
|
18
|
+
app.set :webcomic_domain, "http://MYSITE.dev" # ?
|
19
|
+
|
20
|
+
# ???
|
21
|
+
app.set :webcomic_enable_stories, false
|
22
|
+
app.set :webcomic_story_uri, "story"
|
23
|
+
app.set :webcomic_story_template, "/comics/story_template.html"
|
24
|
+
|
25
|
+
app.set :webcomic_enable_tags, false
|
26
|
+
app.set :webcomic_sort_by, :publish_date # or slug? and metadata
|
27
|
+
app.set :webcomic_slug_field, :slug
|
28
|
+
|
29
|
+
app.set :webcomic_include_comic_in_feed, true
|
30
|
+
|
31
|
+
app.helpers ::Middleman::Features::Webcomic::Helpers
|
32
|
+
|
33
|
+
app.after_configuration do
|
34
|
+
comics, stories= ::Middleman::Webcomic.load_from( File.join(app.root, app.settings.webcomic_source), app )
|
35
|
+
|
36
|
+
# puts comics.inspect
|
37
|
+
|
38
|
+
comics.each do |comic|
|
39
|
+
#puts "-> #{comic.filename} (#{comic.metadata.inspect})"
|
40
|
+
src_path= File.join(app.root, app.settings.webcomic_source_images, comic.filename)
|
41
|
+
tgt_path= File.join(app.views, app.settings.webcomic_images, comic.filename)
|
42
|
+
|
43
|
+
unless File.exists? tgt_path
|
44
|
+
if File.exists? src_path
|
45
|
+
puts "Moving into place: #{comic.filename}"
|
46
|
+
FileUtils.mkdir_p File.dirname(tgt_path), :verbose=>false
|
47
|
+
FileUtils.cp src_path, tgt_path, :verbose=>false
|
48
|
+
else
|
49
|
+
puts "MISSING COMIC: #{comic.filename}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
slug_field= app.settings.webcomic_slug_field
|
54
|
+
if File.exists? tgt_path
|
55
|
+
#puts "Building: /#{app.settings.webcomic_uri}/#{comic[slug_field]}.html"
|
56
|
+
app.page "/#{app.settings.webcomic_uri}/#{comic[slug_field]}.html", :proxy=>app.settings.webcomic_template, :ignore=>true do
|
57
|
+
@comic= comic
|
58
|
+
end
|
59
|
+
else
|
60
|
+
puts "Skipping #{comic.filename} (#{comic[slug_field]})"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
if app.settings.webcomic_enable_stories
|
65
|
+
stories.each do |story|
|
66
|
+
app.page "/#{app.settings.webcomic_story_uri}/#{story.slug}.html", :proxy=>app.settings.webcomic_story_template, :ignore=>true do
|
67
|
+
@story= story
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
app.data_content 'webcomic', {
|
73
|
+
:strips=>comics,
|
74
|
+
:stories=>stories
|
75
|
+
}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
alias :included :registered
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
module Helpers
|
83
|
+
def current_comic
|
84
|
+
(@comic || last_comic)
|
85
|
+
end
|
86
|
+
|
87
|
+
def first_comic
|
88
|
+
data.webcomic.strips.last
|
89
|
+
end
|
90
|
+
|
91
|
+
def last_comic
|
92
|
+
data.webcomic.strips.first
|
93
|
+
end
|
94
|
+
|
95
|
+
def next_comic
|
96
|
+
current_comic.next
|
97
|
+
end
|
98
|
+
|
99
|
+
def prev_comic
|
100
|
+
current_comic.prev
|
101
|
+
end
|
102
|
+
|
103
|
+
def comic_image_url(comic)
|
104
|
+
"/#{settings.webcomic_images}/#{comic.filename}"
|
105
|
+
end
|
106
|
+
alias :comic_image_for :comic_image_url
|
107
|
+
|
108
|
+
def current_comic_image
|
109
|
+
comic_image_for current_comic
|
110
|
+
end
|
111
|
+
alias :current_comic_image_url :current_comic_image
|
112
|
+
|
113
|
+
def comic_path_url(comic)
|
114
|
+
"/#{settings.webcomic_uri}/#{comic[settings.webcomic_slug_field]}"
|
115
|
+
end
|
116
|
+
alias :comic_path_for :comic_path_url
|
117
|
+
|
118
|
+
def current_comic_path
|
119
|
+
comic_path_for current_comic
|
120
|
+
end
|
121
|
+
|
122
|
+
def first_comic_path
|
123
|
+
comic_path_for first_comic
|
124
|
+
end
|
125
|
+
|
126
|
+
def last_comic_path
|
127
|
+
comic_path_for last_comic
|
128
|
+
end
|
129
|
+
|
130
|
+
def next_comic_path
|
131
|
+
comic_path_for next_comic
|
132
|
+
end
|
133
|
+
|
134
|
+
def prev_comic_path
|
135
|
+
comic_path_for prev_comic
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
# Story Helpers
|
140
|
+
def start_story_path_for(object)
|
141
|
+
story = if object.is_a? Story
|
142
|
+
object
|
143
|
+
else # it's a comic... right?
|
144
|
+
data.webcomic.stories.detect {|s| s.title == object.story }
|
145
|
+
end
|
146
|
+
comic_path_for story.comics.last
|
147
|
+
end
|
148
|
+
|
149
|
+
def story_path_for(object)
|
150
|
+
story = if object.is_a? Story
|
151
|
+
object
|
152
|
+
else # it's a comic... right?
|
153
|
+
data.webcomic.stories.detect {|s| s.title == object.story }
|
154
|
+
end
|
155
|
+
"/#{settings.webcomic_story_uri}/#{story.slug}"
|
156
|
+
end
|
157
|
+
|
158
|
+
# Feed Helpers
|
159
|
+
|
160
|
+
def webcomic_feed_data
|
161
|
+
data.webcomic.strips[0...10]
|
162
|
+
end
|
163
|
+
|
164
|
+
def feed_absolute_paths(source, path=settings.webcomic_domain)
|
165
|
+
source.gsub( /src=(["']*)\//) do |match|
|
166
|
+
"#{match[0...-1]}#{path}/"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'middleman'
|
2
|
+
require 'slim'
|
3
|
+
require 'tilt'
|
4
|
+
|
5
|
+
module Middleman
|
6
|
+
module Webcomic
|
7
|
+
class MockApp
|
8
|
+
|
9
|
+
attr_reader :settings
|
10
|
+
|
11
|
+
def initialize(settings={})
|
12
|
+
@settings= ::Thor::CoreExt::HashWithIndifferentAccess.new(settings)
|
13
|
+
end
|
14
|
+
|
15
|
+
def method_missing(key, value=nil)
|
16
|
+
if @settings.has_key? key
|
17
|
+
@settings[key]
|
18
|
+
elsif @settings.has_key? key.to_s
|
19
|
+
@settings[key.to_s]
|
20
|
+
else
|
21
|
+
#super Should it throw an error?
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse_front_matter(content)
|
27
|
+
Middleman::CoreExtensions::FrontMatter.parse_front_matter(content)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Middleman
|
2
|
+
module Webcomic
|
3
|
+
class Pager
|
4
|
+
attr_reader :all, :pages, :base_url, :current_page, :page_sets
|
5
|
+
|
6
|
+
def initialize(articles, base_path="/page", page_size=5)
|
7
|
+
@all= articles
|
8
|
+
@page_size= page_size
|
9
|
+
@base_path= base_path
|
10
|
+
@page_sets= @all.in_groups_of(page_size, false)
|
11
|
+
@pages= []
|
12
|
+
@current_page=1
|
13
|
+
@page_sets.each do |art_ary|
|
14
|
+
@pages << Thor::CoreExt::HashWithIndifferentAccess.new({
|
15
|
+
'articles' => art_ary,
|
16
|
+
'page' => @current_page,
|
17
|
+
'uri' => "#{base_path}/#{current_page}",
|
18
|
+
'pager' => self
|
19
|
+
})
|
20
|
+
@current_page += 1
|
21
|
+
end
|
22
|
+
@current_page= nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def length
|
26
|
+
@pages.length
|
27
|
+
end
|
28
|
+
|
29
|
+
def first
|
30
|
+
@pages.first
|
31
|
+
end
|
32
|
+
|
33
|
+
def last
|
34
|
+
@pages.last
|
35
|
+
end
|
36
|
+
|
37
|
+
def each
|
38
|
+
@current_page=1
|
39
|
+
@pages.each do |page_set|
|
40
|
+
yield page_set
|
41
|
+
@current_page += 1
|
42
|
+
end
|
43
|
+
@current_page= nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def [](key)
|
47
|
+
@pages[key]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Rake tasks
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
def ask message
|
5
|
+
print message
|
6
|
+
STDIN.gets.chomp
|
7
|
+
end
|
8
|
+
|
9
|
+
NOTES_PATH= File.expand_path "./comics/notes" unless defined?(NOTES_PATH)
|
10
|
+
IMAGE_PATH= File.expand_path "./comics/images" unless defined?(IMAGE_PATH)
|
11
|
+
|
12
|
+
namespace :webcomic do
|
13
|
+
|
14
|
+
desc "Creates a new Comic notes entry from image"
|
15
|
+
task :create do
|
16
|
+
|
17
|
+
require 'yaml'
|
18
|
+
require 'date'
|
19
|
+
Dir["#{IMAGE_PATH}/*.{jpg,jpe,jpeg,gif,png}"].each do |img_file|
|
20
|
+
img_filename = File.basename( img_file )
|
21
|
+
basename= img_filename.gsub( File.extname(img_filename), '' )
|
22
|
+
note_filename = "#{basename}.comic.markdown"
|
23
|
+
path= File.join NOTES_PATH, note_filename
|
24
|
+
|
25
|
+
unless File.exists? path
|
26
|
+
create_notes = ask("Notes for '#{img_filename}' are missing, create? [Yn] ")
|
27
|
+
if create_notes.upcase[0] != 'N'
|
28
|
+
meta= {
|
29
|
+
'title' => basename,
|
30
|
+
'slug' => basename,
|
31
|
+
'publish_date' => Date.today,
|
32
|
+
'filename' => img_filename
|
33
|
+
}.to_yaml
|
34
|
+
|
35
|
+
meta << "---\n\n"
|
36
|
+
meta << "\n\n"
|
37
|
+
|
38
|
+
File.open(path, "w") do |file|
|
39
|
+
file.write meta
|
40
|
+
end
|
41
|
+
puts "Created #{path}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
# desc "Validates that there are notes for each image"
|
49
|
+
# task :validate do
|
50
|
+
# ptus "Coming Soon!"
|
51
|
+
# end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Settings:
|
2
|
+
NOTES_PATH= File.expand_path("./comics/notes")
|
3
|
+
IMAGE_PATH= File.expand_path("./comics/images")
|
4
|
+
|
5
|
+
# For the SYNC task
|
6
|
+
SERVER='USERNAME@YOURSITE.COM'
|
7
|
+
FOLDER="~/YOURSITE.COM"
|
8
|
+
|
9
|
+
require 'middleman-webcomic/tasks'
|
10
|
+
|
11
|
+
desc "Runs server"
|
12
|
+
task :server do
|
13
|
+
system "middleman server"
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Runs build"
|
17
|
+
task :build do
|
18
|
+
system "middleman build"
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Syncs with public server using rsync (if configured)"
|
22
|
+
task :sync=>:build do
|
23
|
+
cmd= "rsync -avz --delete build/ #{SERVER}:#{FOLDER}"
|
24
|
+
puts "Running:\n#{cmd}\n"
|
25
|
+
system(cmd)
|
26
|
+
puts "Done."
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'middleman'
|
5
|
+
|
6
|
+
run Middleman.server
|
7
|
+
|
8
|
+
# Rack config
|
9
|
+
|
10
|
+
# Look for index files in folders like Apache
|
11
|
+
# require "rack/contrib/try_static"
|
12
|
+
# use Rack::TryStatic, :root => "build", :urls => %w[/], :try => ['.html', 'index.html', '/index.html']
|
13
|
+
|
14
|
+
# Cache static assets
|
15
|
+
# require "rack/contrib/static_cache"
|
16
|
+
# use Rack::StaticCache, :urls => ['/'], :root => 'build'
|