blogdoor 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +50 -0
- data/Rakefile +1 -0
- data/bin/blogdoor +8 -0
- data/blogdoor.gemspec +28 -0
- data/lib/blogdoor/builder.rb +56 -0
- data/lib/blogdoor/client.rb +13 -0
- data/lib/blogdoor/command.rb +16 -0
- data/lib/blogdoor/server.rb +34 -0
- data/lib/blogdoor/version.rb +3 -0
- data/lib/blogdoor/watcher.rb +26 -0
- data/lib/blogdoor.rb +5 -0
- data/lib/javascripts/jquery.js +8755 -0
- data/lib/javascripts/livereload.js +9 -0
- data/spec/blogdoor/builder_spec.rb +35 -0
- data/spec/fixtures/layout.erb +16 -0
- data/spec/fixtures/sample.md +16 -0
- data/spec/spec_helper.rb +8 -0
- metadata +181 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1246ba1b4f15176dcf8b895f7acc8c0acb54a835
|
4
|
+
data.tar.gz: 6b4c91d02ecade650c6e444c6a6daa91ceb2e1ba
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cb29181337e45a63b6aedeb79b2cb1ff0ddc400041071d4ac19f3d2dbb1847e9f6a186f113b3922676e5e60724943a37c97ccb3ecd9897d0c4fe17ad86e2d16b
|
7
|
+
data.tar.gz: 1ecb83114f0a699f28e2ee9aedb25caf6302565fb9fd05f8660d004d4d9cf0de806110bea09755c7ff5a730a447cc2b667e1d8a7c6ea62f33140e38127acda88
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Naoto Kaneko
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# Blogdoor
|
2
|
+
|
3
|
+
Blogdoor is a toolkit for easily publishing posts from local to your blog.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
```sh
|
8
|
+
$ gem install blogdoor
|
9
|
+
```
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
At your workspace, run `blogdoor start`.
|
14
|
+
|
15
|
+
```sh
|
16
|
+
$ cd path/to/workspace
|
17
|
+
$ blogdoor start
|
18
|
+
```
|
19
|
+
|
20
|
+
This command builds HTML files from your posts written by markdown and `layout.erb`. There are built HTML files under `builds/` at current directory. If you want to preview them, open them by browser.
|
21
|
+
|
22
|
+
Additionally, the command starts websocket server on `localhost:5678` for livereload. When a file has changed, browser will automatically reload the page.
|
23
|
+
|
24
|
+
## Example
|
25
|
+
|
26
|
+
Below is the example of `layout.erb`. Feel free to customize it so that it looks like your blog.
|
27
|
+
|
28
|
+
```erb
|
29
|
+
<!DOCTYPE html>
|
30
|
+
<html>
|
31
|
+
<head>
|
32
|
+
<meta charset="UTF-8">
|
33
|
+
<title><%= @title %></title>
|
34
|
+
</head>
|
35
|
+
<body>
|
36
|
+
<article>
|
37
|
+
<p class="when"><%= @created_at %></p>
|
38
|
+
<h1><%= @title %>
|
39
|
+
<div class="article-body">
|
40
|
+
<%= @content %>
|
41
|
+
</div>
|
42
|
+
</article>
|
43
|
+
</body>
|
44
|
+
</html>
|
45
|
+
```
|
46
|
+
|
47
|
+
- `@title`: is injected the name of changed file.
|
48
|
+
- `@created_at`: is injected the last update date of changed file.
|
49
|
+
- `@content`: is injected the content of changed file.
|
50
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/blogdoor
ADDED
data/blogdoor.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "blogdoor/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "blogdoor"
|
7
|
+
spec.version = Blogdoor::VERSION
|
8
|
+
spec.authors = ["Naoto Kaneko"]
|
9
|
+
spec.email = ["naoty.k@gmail.com"]
|
10
|
+
spec.summary = %q{Blogdoor is a toolkit for easily publishing posts from local to your blog.}
|
11
|
+
spec.homepage = "https://github.com/naoty/blogdoor"
|
12
|
+
spec.license = "MIT"
|
13
|
+
|
14
|
+
spec.files = `git ls-files`.split($/)
|
15
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_dependency "thor"
|
20
|
+
spec.add_dependency "redcarpet"
|
21
|
+
spec.add_dependency "listen"
|
22
|
+
spec.add_dependency "sinatra"
|
23
|
+
spec.add_dependency "sinatra-websocket"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
spec.add_development_dependency "rspec"
|
28
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require "pathname"
|
2
|
+
require "erb"
|
3
|
+
require "redcarpet"
|
4
|
+
|
5
|
+
module Blogdoor
|
6
|
+
class Builder
|
7
|
+
def initialize(args = {})
|
8
|
+
@root_path = Pathname.new(args[:root_path] || ".")
|
9
|
+
@builds_path = @root_path.join("builds")
|
10
|
+
|
11
|
+
layout_path = Pathname.new(args[:layout_path] || "./layout.erb")
|
12
|
+
@layout = ERB.new(layout_path.read)
|
13
|
+
@renderer = Redcarpet::Markdown.new(Redcarpet::Render::HTML, fenced_code_blocks: true)
|
14
|
+
@client = Client.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def build_all
|
18
|
+
@builds_path.mkdir unless @builds_path.exist?
|
19
|
+
Pathname.glob("#{@root_path.to_s}/**/*.md") do |post_path|
|
20
|
+
build(post_path)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def build(post_path)
|
25
|
+
filename = post_path.basename(".md")
|
26
|
+
html_path = @builds_path.join("#{filename}.html")
|
27
|
+
|
28
|
+
content = @renderer.render(post_path.read)
|
29
|
+
context = Context.new({ title: filename, created_at: post_path.mtime, content: content })
|
30
|
+
html = @layout.result(context.to_binding)
|
31
|
+
html = insert_script_tags(html)
|
32
|
+
html_path.open("wb") { |file| file.write(html) }
|
33
|
+
@client.send(content)
|
34
|
+
end
|
35
|
+
|
36
|
+
def insert_script_tags(html)
|
37
|
+
javascripts_path = Pathname.new("../javascripts").expand_path(File.dirname(__FILE__))
|
38
|
+
script_tags = []
|
39
|
+
script_tags << %(<script src="#{javascripts_path.join("jquery.js")}"></script>)
|
40
|
+
script_tags << %(<script src="#{javascripts_path.join("livereload.js")}"></script>)
|
41
|
+
html.gsub(/<\/head>/) { "#{script_tags.join("\n")}\n</head>"}
|
42
|
+
end
|
43
|
+
|
44
|
+
class Context
|
45
|
+
def initialize(args = {})
|
46
|
+
@title = args[:title] || "Preview"
|
47
|
+
@created_at = (args[:created_at] || Time.now).strftime("%Y-%m-%d")
|
48
|
+
@content = args[:content] || ""
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_binding
|
52
|
+
binding
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "rack"
|
3
|
+
|
4
|
+
module Blogdoor
|
5
|
+
class Command < Thor
|
6
|
+
desc "start", "Start blogdoor"
|
7
|
+
def start
|
8
|
+
builder = Builder.new
|
9
|
+
builder.build_all
|
10
|
+
watcher = Watcher.new
|
11
|
+
watcher.builder = builder
|
12
|
+
watcher.start
|
13
|
+
Rack::Handler::Thin.run Server.new, Port: 5678
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "sinatra"
|
2
|
+
require "sinatra-websocket"
|
3
|
+
|
4
|
+
module Blogdoor
|
5
|
+
class Server < Sinatra::Base
|
6
|
+
set :sockets, []
|
7
|
+
|
8
|
+
get "/websocket" do
|
9
|
+
if !request.websocket?
|
10
|
+
return [400, {}, []]
|
11
|
+
end
|
12
|
+
|
13
|
+
request.websocket do |socket|
|
14
|
+
socket.onopen do
|
15
|
+
settings.sockets << socket
|
16
|
+
end
|
17
|
+
|
18
|
+
socket.onclose do
|
19
|
+
settings.sockets.delete(socket)
|
20
|
+
end
|
21
|
+
|
22
|
+
socket.onerror do
|
23
|
+
puts "connection error"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
post "/" do
|
29
|
+
EM.next_tick do
|
30
|
+
settings.sockets.each { |socket| socket.send("") }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "listen"
|
2
|
+
require "pathname"
|
3
|
+
require "forwardable"
|
4
|
+
|
5
|
+
module Blogdoor
|
6
|
+
class Watcher
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
attr_accessor :builder
|
10
|
+
delegate build: :builder
|
11
|
+
|
12
|
+
def initialize(args = {})
|
13
|
+
@root_path = Pathname.new(args[:root_path] || ".")
|
14
|
+
end
|
15
|
+
|
16
|
+
def start
|
17
|
+
listener = Listen.to(@root_path.to_s, only: /\.md$/) do |modified, added|
|
18
|
+
[modified, added].flatten.each do |file_path|
|
19
|
+
build(Pathname.new(file_path))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
trap(:INT) { listener.stop }
|
23
|
+
listener.start
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|