ruhoh 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +13 -0
- data/README.md +5 -53
- data/Rakefile +56 -0
- data/bin/ruhoh +23 -14
- data/lib/ruhoh/client/client.rb +310 -0
- data/lib/ruhoh/client/help.yml +56 -0
- data/lib/ruhoh/compiler.rb +16 -19
- data/lib/ruhoh/converters/converter.rb +30 -3
- data/lib/ruhoh/db.rb +7 -17
- data/lib/ruhoh/deployers/s3.rb +71 -0
- data/lib/ruhoh/friend.rb +71 -0
- data/lib/ruhoh/page.rb +41 -11
- data/lib/ruhoh/parsers/drafts.rb +54 -0
- data/lib/ruhoh/parsers/layouts.rb +14 -9
- data/lib/ruhoh/parsers/pages.rb +47 -35
- data/lib/ruhoh/parsers/partials.rb +14 -2
- data/lib/ruhoh/parsers/posts.rb +139 -88
- data/lib/ruhoh/parsers/routes.rb +4 -8
- data/lib/ruhoh/parsers/site.rb +2 -8
- data/lib/ruhoh/previewer.rb +48 -0
- data/lib/ruhoh/templaters/base.rb +53 -0
- data/lib/ruhoh/templaters/helpers.rb +159 -0
- data/lib/ruhoh/templaters/rmustache.rb +29 -0
- data/lib/ruhoh/utils.rb +25 -7
- data/lib/ruhoh/version.rb +1 -1
- data/lib/ruhoh/watch.rb +22 -9
- data/lib/ruhoh.rb +74 -29
- data/ruhoh.gemspec +70 -9
- data/scaffolds/blog/_config.yml +33 -0
- data/scaffolds/blog/_drafts/.gitkeep +0 -0
- data/scaffolds/blog/_posts/.gitkeep +0 -0
- data/scaffolds/blog/_site.yml +16 -0
- data/scaffolds/blog/_templates/partials/categories_list +3 -0
- data/scaffolds/blog/_templates/partials/pages_list +7 -0
- data/scaffolds/blog/_templates/partials/posts_collate +9 -0
- data/scaffolds/blog/_templates/partials/posts_list +1 -0
- data/scaffolds/blog/_templates/partials/tags_list +3 -0
- data/scaffolds/blog/_templates/syntax/google_prettify/default.css +52 -0
- data/scaffolds/blog/_templates/syntax/google_prettify/desert.css +34 -0
- data/scaffolds/blog/_templates/syntax/google_prettify/sons-of-obsidian.css +117 -0
- data/scaffolds/blog/_templates/syntax/google_prettify/sunburst.css +51 -0
- data/scaffolds/blog/_templates/syntax/google_prettify/twitter-bootstrap.css +30 -0
- data/scaffolds/blog/_templates/themes/twitter/bootstrap/css/bootstrap.min.css +689 -0
- data/scaffolds/blog/_templates/themes/twitter/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/scaffolds/blog/_templates/themes/twitter/bootstrap/img/glyphicons-halflings.png +0 -0
- data/scaffolds/blog/_templates/themes/twitter/css/style.css +68 -0
- data/scaffolds/blog/_templates/themes/twitter/layouts/default.html +64 -0
- data/scaffolds/blog/_templates/themes/twitter/layouts/page.html +13 -0
- data/scaffolds/blog/_templates/themes/twitter/layouts/post.html +55 -0
- data/scaffolds/blog/_templates/themes/twitter/manifest.yml +11 -0
- data/scaffolds/blog/about.md +5 -0
- data/scaffolds/blog/archive.html +11 -0
- data/scaffolds/blog/categories.html +21 -0
- data/scaffolds/blog/config.ru +9 -0
- data/scaffolds/blog/index.html +13 -0
- data/scaffolds/blog/pages.html +14 -0
- data/scaffolds/blog/tags.html +21 -0
- data/scaffolds/layout.html +3 -0
- data/scaffolds/page.html +6 -0
- data/scaffolds/post.html +8 -0
- data/scaffolds/theme/css/style.css +0 -0
- data/scaffolds/theme/images/.gitkeep +0 -0
- data/scaffolds/theme/layouts/default.html +17 -0
- data/scaffolds/theme/layouts/page.html +7 -0
- data/scaffolds/theme/layouts/post.html +8 -0
- data/scaffolds/theme/partials/.gitkeep +0 -0
- data/spec/db_spec.rb +88 -0
- data/spec/page_spec.rb +200 -0
- data/spec/parsers/layouts_spec.rb +32 -0
- data/spec/parsers/pages_spec.rb +97 -0
- data/spec/parsers/posts_spec.rb +301 -0
- data/spec/parsers/routes_spec.rb +45 -0
- data/spec/parsers/site_spec.rb +32 -0
- data/spec/setup_spec.rb +72 -0
- data/spec/spec_helper.rb +23 -0
- data/system_partials/analytics/getclicky +12 -0
- data/system_partials/analytics/google +11 -0
- data/system_partials/comments/disqus +13 -0
- data/system_partials/comments/facebook +9 -0
- data/system_partials/comments/intensedebate +6 -0
- data/system_partials/comments/livefyre +6 -0
- data/system_partials/syntax/google_prettify +11 -0
- metadata +84 -23
- data/lib/ruhoh/client.rb +0 -28
- data/lib/ruhoh/preview.rb +0 -36
- data/lib/ruhoh/templaters/helper_mustache.rb +0 -109
- data/lib/ruhoh/templaters/templater.rb +0 -39
data/Gemfile
ADDED
data/README.md
CHANGED
@@ -1,57 +1,9 @@
|
|
1
|
-
=)
|
2
|
-
|
3
|
-
|
4
|
-
## Setup/Config
|
5
|
-
|
6
|
-
Ruhoh.setup is responsible for building the configuration data.
|
7
|
-
The config takes a given source directory, parses its \_config.yml
|
8
|
-
and builds absolute paths to all the Filesystem API endpoints relative to the source directory.
|
9
|
-
|
10
|
-
## Parsers
|
11
|
-
|
12
|
-
Parsers are small, atomic, functional methods used to process data.
|
13
|
-
Parsers follow the Ruhoh interface specification, to locate, extract, and process data relative to the source directory.
|
14
|
-
|
15
|
-
|
16
|
-
## DB
|
17
|
-
|
18
|
-
The database is responsible for holding website's main data.
|
19
|
-
The database depends on Ruhoh.config.
|
20
|
-
It depends on the parsers to parse the source directory in order to return the data.
|
21
|
-
|
22
|
-
|
23
|
-
## Page
|
24
|
-
|
25
|
-
The page class models a page in the ruhoh system.
|
26
|
-
A page is technically a post object or a page object.
|
27
|
-
|
28
|
-
- content
|
29
|
-
- data (includes yaml front matter + url, id etc.)
|
30
|
-
- sub\_layout
|
31
|
-
- master\_layout
|
32
|
-
|
33
|
-
## Converter
|
34
|
-
|
35
|
-
The converter is responsible for converting a pages 'content' into HTML.
|
36
|
-
A page can be written in various markup formats specified by the page's extension.
|
37
|
-
|
38
|
-
## Templater
|
39
|
-
|
40
|
-
The templater is responsible for building the finished page by
|
41
|
-
utilizing the layouts, content, and any embedded templating language expressions.
|
42
|
-
|
43
|
-
|
44
|
-
# Compiler
|
45
|
-
|
46
|
-
Compiles the full website
|
47
|
-
|
48
|
-
# Preview
|
49
|
-
|
50
|
-
Serves a singular page view to a web-server identified by its url.
|
51
|
-
|
52
|
-
|
53
|
-
|
54
1
|
|
2
|
+
## Ruhoh is the Universal Static Blog API
|
55
3
|
|
4
|
+
<http://ruhoh.com>
|
56
5
|
|
6
|
+
### Usage
|
57
7
|
|
8
|
+
$ gem install ruhoh
|
9
|
+
$ ruhoh help
|
data/Rakefile
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), *%w[lib]))
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rake'
|
4
|
+
require 'bundler'
|
5
|
+
require 'ruhoh/version'
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
|
8
|
+
name = Dir['*.gemspec'].first.split('.').first
|
9
|
+
gemspec_file = "#{name}.gemspec"
|
10
|
+
gem_file = "#{name}-#{Ruhoh::VERSION}.gem"
|
11
|
+
|
12
|
+
task :release => :build do
|
13
|
+
#unless `git branch` =~ /^\* master$/
|
14
|
+
# puts "You must be on the master branch to release!"
|
15
|
+
# exit!
|
16
|
+
#end
|
17
|
+
sh "git commit --allow-empty -m 'Release #{Ruhoh::VERSION}'"
|
18
|
+
sh "git tag v#{Ruhoh::VERSION}"
|
19
|
+
sh "git push origin master"
|
20
|
+
sh "git push origin v#{Ruhoh::VERSION}"
|
21
|
+
sh "gem push pkg/#{name}-#{Ruhoh::VERSION}.gem"
|
22
|
+
end
|
23
|
+
|
24
|
+
task :build => :gemspec do
|
25
|
+
sh "mkdir -p pkg"
|
26
|
+
sh "gem build #{gemspec_file}"
|
27
|
+
sh "mv #{gem_file} pkg"
|
28
|
+
end
|
29
|
+
|
30
|
+
task :gemspec do
|
31
|
+
# read spec file and split out manifest section
|
32
|
+
spec = File.read(gemspec_file)
|
33
|
+
head, manifest, tail = spec.split(" # = MANIFEST =\n")
|
34
|
+
|
35
|
+
# determine file list from git ls-files
|
36
|
+
files = `git ls-files`.
|
37
|
+
split("\n").
|
38
|
+
sort.
|
39
|
+
reject { |file| file =~ /^\./ }.
|
40
|
+
reject { |file| file =~ /^(rdoc|pkg|coverage)/ }.
|
41
|
+
map { |file| " #{file}" }.
|
42
|
+
join("\n")
|
43
|
+
|
44
|
+
# piece file back together and write
|
45
|
+
manifest = " s.files = %w[\n#{files}\n ]\n"
|
46
|
+
spec = [head, manifest, tail].join(" # = MANIFEST =\n")
|
47
|
+
File.open(gemspec_file, 'w') { |io| io.write(spec) }
|
48
|
+
puts "Updated #{gemspec_file}"
|
49
|
+
end
|
50
|
+
|
51
|
+
## Tests
|
52
|
+
|
53
|
+
RSpec::Core::RakeTask.new('spec')
|
54
|
+
|
55
|
+
desc "Run tests"
|
56
|
+
task :default => :spec
|
data/bin/ruhoh
CHANGED
@@ -3,20 +3,29 @@
|
|
3
3
|
$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
|
4
4
|
|
5
5
|
require 'ruhoh'
|
6
|
-
require 'ruhoh/client'
|
6
|
+
require 'ruhoh/client/client'
|
7
|
+
require 'optparse'
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
Options = Struct.new(:title, :date, :ext, :verbose)
|
10
|
+
options = Options.new
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
opt_parser = OptionParser.new do |opts|
|
13
|
+
opts.banner = 'Use `ruhoh help` for full command list.'
|
14
|
+
|
15
|
+
opts.on("-e", "--ext [EXT]", "Specify filename extension. Defaults to '.md' ") do |ext|
|
16
|
+
options.ext = ext
|
17
|
+
end
|
18
|
+
|
19
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely. For pages, shows extra title, url meta-data.") do |v|
|
20
|
+
options.verbose = v
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
opt_parser.parse!
|
25
|
+
|
26
|
+
Ruhoh::Client.new({
|
27
|
+
:args => ARGV,
|
28
|
+
:options => options,
|
29
|
+
:opt_parser => opt_parser
|
30
|
+
})
|
14
31
|
|
15
|
-
case ARGV[0]
|
16
|
-
when 'new'
|
17
|
-
Ruhoh::Client.new_blog(ARGV[1])
|
18
|
-
when 'help'
|
19
|
-
puts help
|
20
|
-
else
|
21
|
-
puts help
|
22
|
-
end
|
@@ -0,0 +1,310 @@
|
|
1
|
+
require 'ruhoh/compiler'
|
2
|
+
|
3
|
+
class Ruhoh
|
4
|
+
class Client
|
5
|
+
|
6
|
+
Paths = Struct.new(:blog_template, :page_template, :post_template, :layout_template, :theme_template)
|
7
|
+
|
8
|
+
def initialize(data)
|
9
|
+
self.setup_paths
|
10
|
+
self.setup_options(data)
|
11
|
+
|
12
|
+
cmd = (data[:args][0] == 'new') ? 'blog' : (data[:args][0] || 'help')
|
13
|
+
Ruhoh::Friend.say {
|
14
|
+
red "Command not found"
|
15
|
+
exit
|
16
|
+
} unless self.respond_to?(cmd)
|
17
|
+
|
18
|
+
Ruhoh.setup unless ['help','blog'].include?(cmd)
|
19
|
+
|
20
|
+
self.__send__(cmd)
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup_options(data)
|
24
|
+
@args = data[:args]
|
25
|
+
@options = data[:options]
|
26
|
+
@opt_parser = data[:opt_parser]
|
27
|
+
@options.ext = (@options.ext || 'md').gsub('.', '')
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup_paths
|
31
|
+
@paths = Paths.new
|
32
|
+
@paths.blog_template = File.join(Ruhoh::Root, "scaffolds", "blog")
|
33
|
+
@paths.page_template = File.join(Ruhoh::Root, "scaffolds", "page.html")
|
34
|
+
@paths.post_template = File.join(Ruhoh::Root, "scaffolds", "post.html")
|
35
|
+
@paths.layout_template = File.join(Ruhoh::Root, "scaffolds", "layout.html")
|
36
|
+
@paths.theme_template = File.join(Ruhoh::Root, "scaffolds", "theme")
|
37
|
+
end
|
38
|
+
|
39
|
+
# Internal: Show Client Utility help documentation.
|
40
|
+
def help
|
41
|
+
file = File.join(Ruhoh::Root, 'lib', 'ruhoh', 'client', 'help.yml')
|
42
|
+
content = Ruhoh::Utils.parse_file_as_yaml(file)
|
43
|
+
options = @opt_parser.help
|
44
|
+
Ruhoh::Friend.say {
|
45
|
+
plain content['description']
|
46
|
+
plain ''
|
47
|
+
plain options
|
48
|
+
plain ''
|
49
|
+
plain 'Commands:'
|
50
|
+
plain ''
|
51
|
+
content['commands'].each do |a|
|
52
|
+
green(" " + a["command"])
|
53
|
+
plain(" "+ a["desc"])
|
54
|
+
end
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
# Public: Create a new draft file.
|
59
|
+
# Requires no settings as it is meant to be fastest way to create content.
|
60
|
+
def draft
|
61
|
+
filename = File.join(Ruhoh.paths.drafts, "#{Time.now.to_i}.#{@options.ext}")
|
62
|
+
if File.exist?(filename)
|
63
|
+
sleep 1 ; self.write(args) ; exit
|
64
|
+
end
|
65
|
+
|
66
|
+
FileUtils.mkdir_p File.dirname(filename)
|
67
|
+
File.open(@paths.post_template) do |template|
|
68
|
+
File.open(filename, 'w') do |post|
|
69
|
+
post.puts template.read
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
Ruhoh::Friend.say {
|
74
|
+
green "New draft:"
|
75
|
+
green Ruhoh.relative_path(filename)
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
# Public: Publishes the last active draft file.
|
80
|
+
def publish
|
81
|
+
id = self.last('draft')
|
82
|
+
Ruhoh::Friend.say { yellow "No draft to publish." ; exit } if id.nil?
|
83
|
+
Ruhoh::Friend.say { plain "Publishing draft: #{id}" }
|
84
|
+
draft = Ruhoh::Parsers::Posts.process_file(id)
|
85
|
+
|
86
|
+
Ruhoh::Friend.say { red "Draft title cannot be blank." ; exit } unless draft['data']['title']
|
87
|
+
Ruhoh::Friend.say {
|
88
|
+
red "Invalid date format: #{draft['data']['date']}"
|
89
|
+
red "Date format must be YYYY-MM-DD."
|
90
|
+
exit
|
91
|
+
} unless draft['data']['date']
|
92
|
+
|
93
|
+
draft['data']['ext'] = @options.ext
|
94
|
+
filename = Ruhoh::Parsers::Posts.to_filename(draft['data'])
|
95
|
+
|
96
|
+
if File.exist?(filename)
|
97
|
+
abort("\e[31m Aborted! \e[0m") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n'
|
98
|
+
end
|
99
|
+
|
100
|
+
FileUtils.mkdir_p File.dirname(filename)
|
101
|
+
FileUtils.mv id, filename
|
102
|
+
|
103
|
+
Ruhoh::Friend.say {
|
104
|
+
green "Published post:"
|
105
|
+
green Ruhoh.relative_path(filename)
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
# Public: Unpublishes the last active post file.
|
110
|
+
def unpublish
|
111
|
+
post = self.last('post')
|
112
|
+
Ruhoh::Friend.say { yellow "No post to unpublish." ; exit } if post.nil?
|
113
|
+
Ruhoh::Friend.say { plain "Unpublishing post: #{post}" }
|
114
|
+
|
115
|
+
FileUtils.mv post, File.join(Ruhoh.paths.drafts, File.basename(post))
|
116
|
+
|
117
|
+
Ruhoh::Friend.say {
|
118
|
+
yellow "Unpublished post:"
|
119
|
+
yellow Ruhoh.relative_path(post)
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
# Public: Create a new page file.
|
124
|
+
def page
|
125
|
+
name = @args[1]
|
126
|
+
Ruhoh::Friend.say {
|
127
|
+
red "Please specify a path"
|
128
|
+
plain " ex: ruhoh page projects/hello-world"
|
129
|
+
exit
|
130
|
+
} if (name.nil? || name.gsub(/\s/, '').empty?)
|
131
|
+
|
132
|
+
filename = File.join(Ruhoh.paths.site_source, name.gsub(/\s/, '-'))
|
133
|
+
filename = File.join(filename, "index.#{@options.ext}") if File.extname(filename) == ""
|
134
|
+
if File.exist?(filename)
|
135
|
+
abort("Create new page: aborted!") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n'
|
136
|
+
end
|
137
|
+
|
138
|
+
FileUtils.mkdir_p File.dirname(filename)
|
139
|
+
File.open(@paths.page_template) do |template|
|
140
|
+
File.open(filename, 'w') do |page|
|
141
|
+
page.puts template.read
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
Ruhoh::Friend.say {
|
146
|
+
green "New page:"
|
147
|
+
plain Ruhoh.relative_path(filename)
|
148
|
+
}
|
149
|
+
end
|
150
|
+
|
151
|
+
# Public: Compile to static website.
|
152
|
+
def compile
|
153
|
+
Ruhoh::Compiler.new(@args[1]).compile
|
154
|
+
end
|
155
|
+
|
156
|
+
# Public: Create a new blog at the directory provided.
|
157
|
+
def blog
|
158
|
+
name = @args[1]
|
159
|
+
Ruhoh::Friend.say {
|
160
|
+
red "Please specify a directory path."
|
161
|
+
plain " ex: ruhoh new the-blogist"
|
162
|
+
exit
|
163
|
+
} if name.nil?
|
164
|
+
|
165
|
+
target_directory = File.join(Dir.pwd, name)
|
166
|
+
|
167
|
+
Ruhoh::Friend.say {
|
168
|
+
red "#{target_directory} already exists."
|
169
|
+
plain " Specify another directory or `rm -rf` this directory first."
|
170
|
+
exit
|
171
|
+
} if File.exist?(target_directory)
|
172
|
+
|
173
|
+
FileUtils.mkdir target_directory
|
174
|
+
FileUtils.cp_r "#{@paths.blog_template}/.", target_directory
|
175
|
+
|
176
|
+
Ruhoh::Friend.say {
|
177
|
+
green "Blog cloned to:"
|
178
|
+
green "#{target_directory}"
|
179
|
+
}
|
180
|
+
end
|
181
|
+
|
182
|
+
# Public: Create a new theme scaffold with the given name.
|
183
|
+
def theme
|
184
|
+
name = @args[1]
|
185
|
+
Ruhoh::Friend.say {
|
186
|
+
red "Please specify a theme name."
|
187
|
+
cyan "ex: ruhoh new theme the-rain"
|
188
|
+
exit
|
189
|
+
} if name.nil?
|
190
|
+
|
191
|
+
target_directory = File.expand_path(File.join(Ruhoh.paths.theme, '..', name.gsub(/\s/, '-').downcase))
|
192
|
+
|
193
|
+
if File.exist?(target_directory)
|
194
|
+
abort("Create new theme: \e[31mAborted!\e[0m") if ask("#{target_directory} already exists. Do you want to overwrite?", ['y', 'n']) == 'n'
|
195
|
+
end
|
196
|
+
|
197
|
+
FileUtils.mkdir target_directory unless File.exist?(target_directory)
|
198
|
+
FileUtils.cp_r "#{@paths.theme_template}/.", target_directory
|
199
|
+
|
200
|
+
Ruhoh::Friend.say {
|
201
|
+
green "New theme scaffold:"
|
202
|
+
green target_directory
|
203
|
+
}
|
204
|
+
end
|
205
|
+
|
206
|
+
# Public: Create a new layout file for the active theme.
|
207
|
+
def layout
|
208
|
+
name = @args[1]
|
209
|
+
Ruhoh::Friend.say {
|
210
|
+
red "Please specify a layout name."
|
211
|
+
cyan "ex: ruhoh new layout splash"
|
212
|
+
exit
|
213
|
+
} if name.nil?
|
214
|
+
|
215
|
+
filename = File.join(Ruhoh.paths.layouts, name.gsub(/\s/, '-').downcase) + ".html"
|
216
|
+
if File.exist?(filename)
|
217
|
+
abort("Create new layout: aborted!") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n'
|
218
|
+
end
|
219
|
+
|
220
|
+
FileUtils.mkdir_p File.dirname(filename)
|
221
|
+
File.open(@paths.layout_template) do |template|
|
222
|
+
File.open(filename, 'w') do |page|
|
223
|
+
page.puts template.read
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
Ruhoh::Friend.say {
|
228
|
+
green "New layout:"
|
229
|
+
plain Ruhoh.relative_path(filename)
|
230
|
+
}
|
231
|
+
end
|
232
|
+
|
233
|
+
# Public : List drafts
|
234
|
+
def drafts
|
235
|
+
self.list(:drafts)
|
236
|
+
end
|
237
|
+
|
238
|
+
# Public : List posts
|
239
|
+
def posts
|
240
|
+
self.list(:posts)
|
241
|
+
end
|
242
|
+
|
243
|
+
# Public : List pages
|
244
|
+
def pages
|
245
|
+
self.list(:pages)
|
246
|
+
end
|
247
|
+
|
248
|
+
# Internal: Outputs a list of the given data-type to the terminal.
|
249
|
+
def list(type)
|
250
|
+
Ruhoh::DB.update(type)
|
251
|
+
data = Ruhoh::DB.__send__(type)
|
252
|
+
data = data['dictionary'] if type == :posts
|
253
|
+
|
254
|
+
if @options.verbose
|
255
|
+
Ruhoh::Friend.say {
|
256
|
+
data.each_value do |p|
|
257
|
+
cyan("- #{p['id']}")
|
258
|
+
plain(" title: #{p['title']}")
|
259
|
+
plain(" url: #{p['url']}")
|
260
|
+
end
|
261
|
+
}
|
262
|
+
else
|
263
|
+
Ruhoh::Friend.say {
|
264
|
+
data.each_value do |p|
|
265
|
+
cyan("- #{p['id']}")
|
266
|
+
end
|
267
|
+
}
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
# Internal: Get the last active file based on data-type.
|
272
|
+
# Note File.ctime is the last time the file was changed as opposed to created.
|
273
|
+
# Returns: String file id, where id is the relative path to the file.
|
274
|
+
def last(type)
|
275
|
+
self.get_files(type).sort_by { |f| File.ctime(f) }.last || nil
|
276
|
+
end
|
277
|
+
|
278
|
+
# Internal: Get an Array list of file ids based on the data-type.
|
279
|
+
# Returns: Array of file ids (ids are relative paths to the file.)
|
280
|
+
def get_files(type)
|
281
|
+
case type
|
282
|
+
when 'post'
|
283
|
+
Ruhoh::Parsers::Posts.files
|
284
|
+
when 'draft'
|
285
|
+
Ruhoh::Parsers::Drafts.files
|
286
|
+
when 'page'
|
287
|
+
Ruhoh::Parsers::Pages.files
|
288
|
+
else
|
289
|
+
Ruhoh::Friend.say { red "Type: '#{type}' not supported." }
|
290
|
+
exit
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def ask(message, valid_options)
|
295
|
+
if valid_options
|
296
|
+
answer = get_stdin("#{message} #{valid_options.to_s.gsub(/"/, '').gsub(/, /,'/')} ") while !valid_options.include?(answer)
|
297
|
+
else
|
298
|
+
answer = get_stdin(message)
|
299
|
+
end
|
300
|
+
answer
|
301
|
+
end
|
302
|
+
|
303
|
+
def get_stdin(message)
|
304
|
+
print message
|
305
|
+
STDIN.gets.chomp
|
306
|
+
end
|
307
|
+
|
308
|
+
|
309
|
+
end #Client
|
310
|
+
end #Ruhoh
|
@@ -0,0 +1,56 @@
|
|
1
|
+
---
|
2
|
+
description: |
|
3
|
+
|
4
|
+
Ruhoh is a nifty, modular static blog generator.
|
5
|
+
It is the Universal Static Blog API.
|
6
|
+
Visit http://www.ruhoh.com for complete usage and documentation.
|
7
|
+
|
8
|
+
commands:
|
9
|
+
-
|
10
|
+
"command" : "new <directory_path>"
|
11
|
+
"desc" : |
|
12
|
+
Create a new blog directory based on the Ruhoh specification.
|
13
|
+
-
|
14
|
+
"command" : "compile"
|
15
|
+
"desc" : |
|
16
|
+
Compile to static website.
|
17
|
+
-
|
18
|
+
"command" : "draft"
|
19
|
+
"desc" : |
|
20
|
+
Create a new draft.
|
21
|
+
-
|
22
|
+
"command" : "publish"
|
23
|
+
"desc" : |
|
24
|
+
Publish the last active draft file.
|
25
|
+
-
|
26
|
+
"command" : "unpublish"
|
27
|
+
"desc" : |
|
28
|
+
UnPublish the last active post file.
|
29
|
+
-
|
30
|
+
"command" : "page <path>"
|
31
|
+
"desc" : |
|
32
|
+
Create a new page at the given path.
|
33
|
+
-
|
34
|
+
"command" : "drafts"
|
35
|
+
"desc" : |
|
36
|
+
List all drafts.
|
37
|
+
-
|
38
|
+
"command" : "posts"
|
39
|
+
"desc" : |
|
40
|
+
List all posts.
|
41
|
+
-
|
42
|
+
"command" : "pages"
|
43
|
+
"desc" : |
|
44
|
+
List all pages.
|
45
|
+
-
|
46
|
+
"command" : "layout <name>"
|
47
|
+
"desc" : |
|
48
|
+
Create a new layout for the currently active theme.
|
49
|
+
-
|
50
|
+
"command" : "theme <name>"
|
51
|
+
"desc" : |
|
52
|
+
Create a new theme scaffold.
|
53
|
+
-
|
54
|
+
"command" : "help"
|
55
|
+
"desc" : |
|
56
|
+
Show this menu.
|
data/lib/ruhoh/compiler.rb
CHANGED
@@ -2,17 +2,19 @@ class Ruhoh
|
|
2
2
|
|
3
3
|
class Compiler
|
4
4
|
|
5
|
-
def initialize(target_directory
|
6
|
-
Ruhoh::DB.
|
7
|
-
@target = target_directory
|
5
|
+
def initialize(target_directory)
|
6
|
+
Ruhoh::DB.update!
|
7
|
+
@target = target_directory || "./#{Ruhoh.folders.compiled}"
|
8
8
|
@page = Ruhoh::Page.new
|
9
9
|
end
|
10
10
|
|
11
11
|
def compile
|
12
|
-
FileUtils.
|
12
|
+
FileUtils.rm_r @target if File.exist?(@target)
|
13
|
+
FileUtils.mkdir @target
|
13
14
|
self.theme
|
14
15
|
self.pages
|
15
16
|
self.media
|
17
|
+
self.syntax
|
16
18
|
end
|
17
19
|
|
18
20
|
def pages
|
@@ -21,38 +23,33 @@ class Ruhoh
|
|
21
23
|
FileUtils.cd(@target) {
|
22
24
|
Ruhoh::DB.posts['dictionary'].merge(Ruhoh::DB.pages).each_value do |p|
|
23
25
|
@page.change(p['id'])
|
24
|
-
|
26
|
+
|
25
27
|
FileUtils.mkdir_p File.dirname(@page.compiled_path)
|
26
28
|
File.open(@page.compiled_path, 'w') { |p| p.puts @page.render }
|
27
29
|
|
28
|
-
processed <<
|
30
|
+
processed << p
|
31
|
+
Ruhoh::Friend.say { green "processed: #{p['id']}" }
|
29
32
|
end
|
30
33
|
}
|
31
34
|
|
32
|
-
puts "=> Posts Processed:"
|
33
|
-
puts processed
|
34
35
|
end
|
35
36
|
|
36
37
|
def theme
|
37
|
-
FileUtils.mkdir_p File.join(@target, Ruhoh.config.
|
38
|
+
FileUtils.mkdir_p File.join(@target, Ruhoh.config.theme_path)
|
38
39
|
FileUtils.cp_r Ruhoh.paths.theme, File.join(@target, Ruhoh.folders.templates, Ruhoh.folders.themes)
|
39
40
|
end
|
40
41
|
|
41
42
|
def media
|
42
43
|
FileUtils.mkdir_p File.join(@target, Ruhoh.folders.media)
|
43
|
-
FileUtils.cp_r Ruhoh.paths.media,
|
44
|
+
FileUtils.cp_r Ruhoh.paths.media, @target
|
44
45
|
end
|
45
46
|
|
46
|
-
def
|
47
|
-
File.
|
48
|
-
|
49
|
-
}
|
50
|
-
|
51
|
-
File.open(Ruhoh.paths.database + '/pages_dictionary.yml', 'w') { |page|
|
52
|
-
page.puts Ruhoh::DB.pages.to_yaml
|
53
|
-
}
|
47
|
+
def syntax
|
48
|
+
syntax_path = File.join(@target, Ruhoh.folders.templates, Ruhoh.folders.syntax)
|
49
|
+
FileUtils.mkdir_p syntax_path
|
50
|
+
FileUtils.cp_r "#{Ruhoh.paths.syntax}/.", syntax_path
|
54
51
|
end
|
55
|
-
|
52
|
+
|
56
53
|
end #Compiler
|
57
54
|
|
58
55
|
end #Ruhoh
|
@@ -4,14 +4,41 @@ class Ruhoh
|
|
4
4
|
|
5
5
|
module Converter
|
6
6
|
|
7
|
+
MarkdownExtensions = ['.md', '.markdown']
|
8
|
+
TextileExtensions = ['.textile']
|
9
|
+
|
7
10
|
def self.convert(page)
|
8
|
-
|
9
|
-
|
11
|
+
self.__send__ self.which_converter(page.data['id']), page
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.which_converter(filename)
|
15
|
+
extension = File.extname(filename).downcase
|
16
|
+
|
17
|
+
if MarkdownExtensions.include? extension
|
18
|
+
:markdown
|
19
|
+
elsif TextileExtensions.include? extension
|
20
|
+
:textile
|
10
21
|
else
|
11
|
-
|
22
|
+
:none
|
12
23
|
end
|
13
24
|
end
|
14
25
|
|
26
|
+
# Markdown
|
27
|
+
def self.markdown(page)
|
28
|
+
Maruku.new(page.content).to_html
|
29
|
+
end
|
30
|
+
|
31
|
+
# Textile
|
32
|
+
# sample implementation
|
33
|
+
def self.textile(page)
|
34
|
+
'textile not supported yet =('
|
35
|
+
end
|
36
|
+
|
37
|
+
# No converter
|
38
|
+
def self.none(page)
|
39
|
+
page.content
|
40
|
+
end
|
41
|
+
|
15
42
|
end #Converter
|
16
43
|
|
17
44
|
end #Ruhoh
|