ruhoh 0.0.2 → 0.0.3
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.
- 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
|