zarchitect 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/bin/zarchitect +3 -0
- data/data/_zarchitect.yaml +22 -0
- data/data/post.md.erb +16 -0
- data/lib/zarchitect.rb +179 -0
- data/lib/zarchitect/assets.rb +50 -0
- data/lib/zarchitect/audio.rb +31 -0
- data/lib/zarchitect/category.rb +62 -0
- data/lib/zarchitect/cmd_misc.rb +34 -0
- data/lib/zarchitect/cmd_new.rb +75 -0
- data/lib/zarchitect/cmd_update.rb +34 -0
- data/lib/zarchitect/config.rb +285 -0
- data/lib/zarchitect/content.rb +286 -0
- data/lib/zarchitect/file_manager.rb +64 -0
- data/lib/zarchitect/html.rb +54 -0
- data/lib/zarchitect/htmltable.rb +154 -0
- data/lib/zarchitect/image.rb +162 -0
- data/lib/zarchitect/image_set.rb +46 -0
- data/lib/zarchitect/index.rb +224 -0
- data/lib/zarchitect/misc_file.rb +19 -0
- data/lib/zarchitect/paginator.rb +73 -0
- data/lib/zarchitect/post.rb +202 -0
- data/lib/zarchitect/rouge_html.rb +34 -0
- data/lib/zarchitect/rss.rb +60 -0
- data/lib/zarchitect/scss.rb +32 -0
- data/lib/zarchitect/section.rb +126 -0
- data/lib/zarchitect/tag.rb +46 -0
- data/lib/zarchitect/util.rb +41 -0
- data/lib/zarchitect/video.rb +37 -0
- data/lib/zarchitect/zerb.rb +120 -0
- metadata +73 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
class Index < Zarchitect
|
|
2
|
+
|
|
3
|
+
def initialize(parent)
|
|
4
|
+
@parent = parent
|
|
5
|
+
@ptype = @parent.class.to_s
|
|
6
|
+
# index owns paginator
|
|
7
|
+
# owns the index files which share its paginator
|
|
8
|
+
setup_paginator
|
|
9
|
+
setup_html
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def build_html
|
|
13
|
+
@html.each do |h|
|
|
14
|
+
h.compose
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def write_html
|
|
19
|
+
@html.each do |h|
|
|
20
|
+
GPI.print "Writing index HTML.", GPI::CLU.check_option('v')
|
|
21
|
+
h.write
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def setup_paginator
|
|
28
|
+
ppp = 0
|
|
29
|
+
if section.conf.has_option? "paginate"
|
|
30
|
+
ppp = section.conf.paginate # post per page
|
|
31
|
+
end
|
|
32
|
+
if ppp > 0 && section.conf.collection
|
|
33
|
+
pbu = base_url # url used by pagination
|
|
34
|
+
pnm = (posts.count.to_f / ppp.to_f).ceil # numbers of index pages
|
|
35
|
+
@paginator = Paginator.new(pbu, pnm, ppp)
|
|
36
|
+
else
|
|
37
|
+
@paginator = Paginator.new(0,0,0) # no pagination for this index file
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def setup_html
|
|
42
|
+
@html = Array.new
|
|
43
|
+
if @paginator.posts_per_page == 0
|
|
44
|
+
html = HTML.new(File.join(Dir.getwd,HTMLDIR,base_url,"index.html"))
|
|
45
|
+
html.set_templates(layout, view)
|
|
46
|
+
html.set_data("section", section)
|
|
47
|
+
html.set_data("category", category)
|
|
48
|
+
html.set_data("tag", tag)
|
|
49
|
+
html.set_data("posts", posts)
|
|
50
|
+
html.set_data("index", true)
|
|
51
|
+
html.set_meta("title", meta_title)
|
|
52
|
+
html.set_meta("keywords", meta_keywords)
|
|
53
|
+
html.set_meta("author", meta_author)
|
|
54
|
+
html.set_meta("description", meta_description)
|
|
55
|
+
@html.push html
|
|
56
|
+
return
|
|
57
|
+
end
|
|
58
|
+
max = 0
|
|
59
|
+
if section.conf.has_option?("maxpages")
|
|
60
|
+
max = section.conf.maxpages
|
|
61
|
+
end
|
|
62
|
+
n = 1 # number of index.html files we need to create
|
|
63
|
+
if @paginator.posts_per_page > 0
|
|
64
|
+
if max > 0
|
|
65
|
+
n = max
|
|
66
|
+
else
|
|
67
|
+
n = @paginator.page_number
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
i = 0
|
|
71
|
+
while i < n
|
|
72
|
+
rposts = posts.slice(i * @paginator.posts_per_page,
|
|
73
|
+
@paginator.posts_per_page)
|
|
74
|
+
if i == 0
|
|
75
|
+
path = File.join(Dir.getwd,HTMLDIR,base_url, "index.html")
|
|
76
|
+
else
|
|
77
|
+
path = File.join(Dir.getwd,HTMLDIR,base_url, "index-#{i+1}.html")
|
|
78
|
+
end
|
|
79
|
+
html = HTML.new(path)
|
|
80
|
+
html.set_templates(layout, view)
|
|
81
|
+
html.set_data("section", section)
|
|
82
|
+
html.set_data("category", category)
|
|
83
|
+
html.set_data("tag", tag)
|
|
84
|
+
html.set_data("posts", rposts)
|
|
85
|
+
html.set_data("paginator", @paginator.clone)
|
|
86
|
+
html.set_data("index", true)
|
|
87
|
+
html.set_meta("title", meta_title)
|
|
88
|
+
html.set_meta("keywords", meta_keywords)
|
|
89
|
+
html.set_meta("author", meta_author)
|
|
90
|
+
html.set_meta("description", meta_description)
|
|
91
|
+
@html.push html
|
|
92
|
+
i += 1
|
|
93
|
+
@paginator.next
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def base_url
|
|
98
|
+
case @ptype
|
|
99
|
+
when "Section"
|
|
100
|
+
if section.conf.index
|
|
101
|
+
""
|
|
102
|
+
else
|
|
103
|
+
"/#{section.key}"
|
|
104
|
+
end
|
|
105
|
+
when "Category"
|
|
106
|
+
"/#{section.key}/#{@parent.key}"
|
|
107
|
+
when "Tag"
|
|
108
|
+
"/#{section.key}/#{@parent.category.key}/#{@parent.key}"
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def section
|
|
113
|
+
case @ptype
|
|
114
|
+
when "Section"
|
|
115
|
+
@parent
|
|
116
|
+
when "Category"
|
|
117
|
+
@parent.section
|
|
118
|
+
when "Tag"
|
|
119
|
+
@parent.category.section
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def category
|
|
124
|
+
case @ptype
|
|
125
|
+
when "Section"
|
|
126
|
+
nil
|
|
127
|
+
when "Category"
|
|
128
|
+
@parent
|
|
129
|
+
when "Tag"
|
|
130
|
+
@parent.category
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def tag
|
|
135
|
+
case @ptype
|
|
136
|
+
when "Section",
|
|
137
|
+
nil
|
|
138
|
+
when "Category"
|
|
139
|
+
nil
|
|
140
|
+
when "Tag"
|
|
141
|
+
@parent
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def posts
|
|
146
|
+
@parent.posts
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def layout
|
|
150
|
+
case @ptype
|
|
151
|
+
when "Section"
|
|
152
|
+
section.conf.index_layout
|
|
153
|
+
when "Category"
|
|
154
|
+
if section.conf.has_option?("category_index_layout")
|
|
155
|
+
section.conf.category_index_layout
|
|
156
|
+
else
|
|
157
|
+
section.conf.index_layout
|
|
158
|
+
end
|
|
159
|
+
when "Tag"
|
|
160
|
+
if section.conf.has_option?("tag_index_layout")
|
|
161
|
+
section.conf.tag_index_layout
|
|
162
|
+
else
|
|
163
|
+
if section.conf.has_option?("category_index_layout")
|
|
164
|
+
section.conf.category_index_layout
|
|
165
|
+
else
|
|
166
|
+
section.conf.index_layout
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def view
|
|
173
|
+
case @ptype
|
|
174
|
+
when "Section"
|
|
175
|
+
section.conf.index_view
|
|
176
|
+
when "Category"
|
|
177
|
+
if section.conf.has_option?("category_index_view")
|
|
178
|
+
section.conf.category_index_view
|
|
179
|
+
else
|
|
180
|
+
section.conf.index_view
|
|
181
|
+
end
|
|
182
|
+
when "Tag"
|
|
183
|
+
if section.conf.has_option?("tag_index_view")
|
|
184
|
+
section.conf.tag_index_view
|
|
185
|
+
else
|
|
186
|
+
if section.conf.has_option?("category_index_view")
|
|
187
|
+
section.conf.category_index_view
|
|
188
|
+
else
|
|
189
|
+
section.conf.index_view
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
##############################################
|
|
196
|
+
# meta data
|
|
197
|
+
#
|
|
198
|
+
|
|
199
|
+
def meta_title
|
|
200
|
+
if category
|
|
201
|
+
Zarchitect.conf.site_name + Zarchitect.conf.title_sep + section.name +
|
|
202
|
+
Zarchitect.conf.title_sep + category.name
|
|
203
|
+
else
|
|
204
|
+
Zarchitect.conf.site_name + Zarchitect.conf.title_sep + section.name
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def meta_keywords
|
|
209
|
+
Zarchitect.conf.site_keywords.clone
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def meta_author
|
|
213
|
+
Zarchitect.conf.admin
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def meta_description
|
|
217
|
+
if category
|
|
218
|
+
section.name + " " + category.name
|
|
219
|
+
else
|
|
220
|
+
section.name
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class MiscFile < Zarchitect
|
|
2
|
+
attr_reader :size, :type, :url
|
|
3
|
+
|
|
4
|
+
def initialize(path)
|
|
5
|
+
@path = path
|
|
6
|
+
@url = path.clone
|
|
7
|
+
@url[0] = "/"
|
|
8
|
+
@size = File.size(path)
|
|
9
|
+
@type = File.extname(path)[1..-1]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.find(k, v)
|
|
13
|
+
ObjectSpace.each_object(MiscFile) do |a|
|
|
14
|
+
str = a.send(k)
|
|
15
|
+
return a if str == v
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
class Paginator
|
|
2
|
+
attr_reader :page_number, :curr_page, :range, :max, :posts_per_page
|
|
3
|
+
|
|
4
|
+
MAX = 15
|
|
5
|
+
|
|
6
|
+
def initialize(base_url, page_number, ppp)
|
|
7
|
+
@base_url = base_url # used to construct urls to pages
|
|
8
|
+
@page_number = page_number # number of pages in total
|
|
9
|
+
@curr_page = 1 # current page
|
|
10
|
+
@range = Array.new # numbers of pages in pagination
|
|
11
|
+
@max = MAX # how many pages to be shown in pagination
|
|
12
|
+
@posts_per_page = ppp
|
|
13
|
+
update_range
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def url(n)
|
|
17
|
+
if n == 1
|
|
18
|
+
return File.join(@base_url, "index.html")
|
|
19
|
+
else
|
|
20
|
+
return File.join(@base_url, "index-#{n}.html")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def next
|
|
25
|
+
if @curr_page < @page_number
|
|
26
|
+
@curr_page += 1
|
|
27
|
+
update_range
|
|
28
|
+
else
|
|
29
|
+
GPI.print "Warning: paginator attempted to exceed total page number",
|
|
30
|
+
GPI::CLU.check_option('v')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def paginates?
|
|
35
|
+
@page_number > 1
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def update_range
|
|
41
|
+
# creates array of page numbers to use as pagination links
|
|
42
|
+
default = [ 1, 2, @curr_page, @page_number-1, @page_number ]
|
|
43
|
+
sector = (@max -1) / 2 # 7 if max 15
|
|
44
|
+
@range.clear
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
if @page_number <= @max
|
|
49
|
+
i = 1
|
|
50
|
+
while i <= @page_number
|
|
51
|
+
@range.push i
|
|
52
|
+
i += 1
|
|
53
|
+
end
|
|
54
|
+
else
|
|
55
|
+
b = @curr_page - sector # begin
|
|
56
|
+
b = 3 if b < 3
|
|
57
|
+
e = b + (@max-1)-4 # end
|
|
58
|
+
e = page_number-2 if e > @page_number-2
|
|
59
|
+
|
|
60
|
+
@range.push 1, 2
|
|
61
|
+
@range.push 0 if b > 3 # gap!
|
|
62
|
+
i = b
|
|
63
|
+
while i <= e do
|
|
64
|
+
@range.push i
|
|
65
|
+
i += 1
|
|
66
|
+
end
|
|
67
|
+
@range.push 0 if e < @page_number-2 # gap!
|
|
68
|
+
@range.push @page_number-1, @page_number
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
class Post < Zarchitect
|
|
2
|
+
attr_reader :source_path, :conf, :content, :name, :draft, :date,
|
|
3
|
+
:description, :url, :category
|
|
4
|
+
|
|
5
|
+
def initialize(path, section)
|
|
6
|
+
GPI.print "Initializing post #{path}.", GPI::CLU.check_option('v')
|
|
7
|
+
@section = section
|
|
8
|
+
@source_path = path
|
|
9
|
+
@conf = Config.new(path)
|
|
10
|
+
@conf.validate_post
|
|
11
|
+
@conf.setup
|
|
12
|
+
@id = @conf.id.clone if @conf.has_option?("id")
|
|
13
|
+
@category = nil
|
|
14
|
+
set_draft
|
|
15
|
+
set_date
|
|
16
|
+
fetch_category if @conf.has_option?("category")
|
|
17
|
+
create_dir
|
|
18
|
+
fetch_content
|
|
19
|
+
set_description
|
|
20
|
+
set_name
|
|
21
|
+
set_url
|
|
22
|
+
set_html_path
|
|
23
|
+
# construct path for html // maybe only necessray when writing html?
|
|
24
|
+
# set date
|
|
25
|
+
setup_html
|
|
26
|
+
rss.try_item(self)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def tags
|
|
30
|
+
if @conf.has_option?("tags")
|
|
31
|
+
@conf.tags
|
|
32
|
+
else
|
|
33
|
+
Array.new
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def build_html
|
|
38
|
+
GPI.print "Composing HTML for #{@source_path}.", GPI::CLU.check_option('v')
|
|
39
|
+
@html.compose
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def write_html
|
|
43
|
+
GPI.print "Writing HTML from #{@source_path}.", GPI::CLU.check_option('v')
|
|
44
|
+
@html.write
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def fetch_content
|
|
50
|
+
@content = Content.new(self)
|
|
51
|
+
@content.markup
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def fetch_category
|
|
55
|
+
@section.categories.each do |c|
|
|
56
|
+
@category = c if @conf.category == c.key
|
|
57
|
+
end
|
|
58
|
+
if @category.nil?
|
|
59
|
+
GPI.print "Unable to find category #{@conf.category}."
|
|
60
|
+
GPI.quit
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def set_name
|
|
65
|
+
if @conf.has_option?("title")
|
|
66
|
+
@name = @conf.title
|
|
67
|
+
elsif @section.conf.has_option?("default_title")
|
|
68
|
+
@name = @sectin.conf.default_title
|
|
69
|
+
else
|
|
70
|
+
@name = ""
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def set_url
|
|
75
|
+
if @section.conf.collection
|
|
76
|
+
if @section.conf.categorize
|
|
77
|
+
@url = "/#{@section.key}/#{@category.key}/#{@id}/index.html"
|
|
78
|
+
else
|
|
79
|
+
@url = "/#{@section.key}/#{@id}/index.html"
|
|
80
|
+
end
|
|
81
|
+
else
|
|
82
|
+
@url = "/#{@section.key}/index.html"
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def set_html_path
|
|
87
|
+
@html_path = @url.clone
|
|
88
|
+
@html_path = File.join(Dir.getwd, HTMLDIR, @url)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def create_dir
|
|
92
|
+
if @section.conf.collection && @section.conf.categorize
|
|
93
|
+
Util.mkdir(File.join(HTMLDIR, @section.key, @category.key, @id.to_s))
|
|
94
|
+
elsif @section.conf.collection
|
|
95
|
+
Util.mkdir(File.join(HTMLDIR, @section.key, @id.to_s))
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def set_draft
|
|
100
|
+
@draft = false
|
|
101
|
+
@draft = @conf.draft if @conf.has_option?("draft")
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def set_date
|
|
105
|
+
@date = nil
|
|
106
|
+
if @section.conf.collection
|
|
107
|
+
if @section.conf.sort_type == "date"
|
|
108
|
+
unless @conf.has_option?('date')
|
|
109
|
+
GPI.print "Error: Date missing in #{@source_path}"
|
|
110
|
+
GPI.quit
|
|
111
|
+
else
|
|
112
|
+
if @conf.date == "now"
|
|
113
|
+
@date = Time.now
|
|
114
|
+
else
|
|
115
|
+
@date = @conf.date #class Time
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
else
|
|
119
|
+
if @conf.has_option?('date')
|
|
120
|
+
@date = @conf.date
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
else
|
|
124
|
+
if @conf.has_option?('date')
|
|
125
|
+
if @conf.date == "now"
|
|
126
|
+
@date = Time.now
|
|
127
|
+
else
|
|
128
|
+
@date = @conf.date
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
if @date.nil?
|
|
133
|
+
@date = File.stat(@source_path).ctime
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def set_description
|
|
138
|
+
if @conf.has_option?('description')
|
|
139
|
+
@description = @conf.description
|
|
140
|
+
else
|
|
141
|
+
nodes = @content.nodes.select { |n| n.type == "p" }
|
|
142
|
+
if nodes.count > 0
|
|
143
|
+
@description = Sanitize.fragment(nodes[0])
|
|
144
|
+
else
|
|
145
|
+
@description = ""
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def setup_html
|
|
151
|
+
@html = HTML.new(@html_path)
|
|
152
|
+
@html.set_templates(@section.conf.layout, @section.conf.view)
|
|
153
|
+
|
|
154
|
+
@html.set_data("section", @section)
|
|
155
|
+
@html.set_data("category", @category)
|
|
156
|
+
@html.set_data("post", self)
|
|
157
|
+
@html.set_data("content", @content.html)
|
|
158
|
+
@html.set_data("index", false)
|
|
159
|
+
|
|
160
|
+
@html.set_meta("title", meta_title)
|
|
161
|
+
@html.set_meta("keywords", meta_keywords)
|
|
162
|
+
@html.set_meta("author", meta_author)
|
|
163
|
+
@html.set_meta("description", @description)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
######################################
|
|
167
|
+
# meta data
|
|
168
|
+
#
|
|
169
|
+
|
|
170
|
+
def meta_title
|
|
171
|
+
title = Zarchitect.conf.site_name.clone
|
|
172
|
+
title << Zarchitect.conf.title_sep
|
|
173
|
+
if @section.conf.collection
|
|
174
|
+
title << @section.name << Zarchitect.conf.title_sep
|
|
175
|
+
end
|
|
176
|
+
unless @category.nil?
|
|
177
|
+
title << @category.name << Zarchitect.conf.title_sep
|
|
178
|
+
end
|
|
179
|
+
title << @name
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def meta_keywords
|
|
183
|
+
keywords = Zarchitect.conf.site_keywords.clone
|
|
184
|
+
if @section.conf.has_option?("keywords")
|
|
185
|
+
keywords << ', ' << @section.conf.keywords
|
|
186
|
+
end
|
|
187
|
+
if @conf.has_option?("keywords")
|
|
188
|
+
unless @conf.keywords.nil?
|
|
189
|
+
keywords << ', ' << @conf.keywords
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def meta_author
|
|
195
|
+
if @conf.has_option?("author")
|
|
196
|
+
author = @conf.author
|
|
197
|
+
else
|
|
198
|
+
author = ""
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
end
|