mook 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +98 -0
- data/Rakefile +3 -0
- data/bin/mook +12 -0
- data/lib/mook.rb +15 -0
- data/lib/mook/html.rb +62 -0
- data/lib/mook/model.rb +21 -0
- data/lib/mook/page.rb +33 -0
- data/lib/mook/renderer.rb +30 -0
- data/lib/mook/site.rb +38 -0
- data/lib/mook/version.rb +3 -0
- data/mook.gemspec +23 -0
- metadata +111 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# Mook
|
2
|
+
|
3
|
+
Mook is a simple static site generator.
|
4
|
+
|
5
|
+
## Getting Started
|
6
|
+
|
7
|
+
gem install mook
|
8
|
+
|
9
|
+
And you're off.
|
10
|
+
|
11
|
+
|
12
|
+
## Site Layout
|
13
|
+
|
14
|
+
```
|
15
|
+
+ my-site
|
16
|
+
+ pages
|
17
|
+
- index.md
|
18
|
+
- about.md
|
19
|
+
- contact.md
|
20
|
+
+ static
|
21
|
+
+ css
|
22
|
+
- mypage.css
|
23
|
+
+ templates
|
24
|
+
- _toolbar.erb
|
25
|
+
- default.html.erb
|
26
|
+
```
|
27
|
+
|
28
|
+
Pages go in a directory called `pages`, static content goes in a directory called `static`, templates go in `templates`.
|
29
|
+
|
30
|
+
|
31
|
+
## Pages
|
32
|
+
|
33
|
+
[blah](#bloo)
|
34
|
+
|
35
|
+
A page is a Markdown document with some leading metadata:
|
36
|
+
|
37
|
+
Title: About Me
|
38
|
+
Template: default.html.erb
|
39
|
+
Order: 2
|
40
|
+
* * *
|
41
|
+
|
42
|
+
I'm just a simple country [hyperchicken](#more).
|
43
|
+
|
44
|
+
Here's some Ruby code:
|
45
|
+
|
46
|
+
``` ruby
|
47
|
+
Poop.new(:yay => "whee")
|
48
|
+
```
|
49
|
+
|
50
|
+
## Perhaps Some More Stuff. #more
|
51
|
+
|
52
|
+
Also, some other stuff.
|
53
|
+
|
54
|
+
A few things of note:
|
55
|
+
|
56
|
+
* `Title` and `Template` are mandatory, `Order` is optional.
|
57
|
+
* Fenced (i.e., ` ``` `-surrounded) code blocks are OK, and if you add the
|
58
|
+
language name, Mook will syntax highlight the code for you.
|
59
|
+
* Adding a name to a header (i.e., `#more`) created a named anchor above that
|
60
|
+
header with that name so's you can link to it.
|
61
|
+
* Strike-through (`~struckthrough~`) is supported.
|
62
|
+
* Superscript (`2^128` or `this is the 2^(nd) time`) is supported.
|
63
|
+
* URLs are automatically linkified.
|
64
|
+
* Smart quotes, dashes, ellipses, etc. are all supported.
|
65
|
+
|
66
|
+
|
67
|
+
## Templates
|
68
|
+
|
69
|
+
Templates are ERB templates. They've got all the usual features, plus the
|
70
|
+
following stuff in scope:
|
71
|
+
|
72
|
+
* `site`, which wraps the idea of the site you're generating. Has a `#pages`
|
73
|
+
method, which returns an array of all the pages in the site.
|
74
|
+
* `page`, which wraps the idea of the current page being rendered. Has the
|
75
|
+
following methods:
|
76
|
+
* `#name`: the page's name, as defined by the filename
|
77
|
+
* `#title`: the page's title
|
78
|
+
* `#content`: the page's Markdown content, rendered as HTML
|
79
|
+
* `#toc`: a nested `<ul>` list of all the page's headers, with links
|
80
|
+
|
81
|
+
|
82
|
+
## Running
|
83
|
+
|
84
|
+
Run this:
|
85
|
+
|
86
|
+
mook
|
87
|
+
|
88
|
+
Then look in the `target` directory for an awesome surprise.
|
89
|
+
|
90
|
+
|
91
|
+
## But this doesn't do what I want
|
92
|
+
|
93
|
+
Sorry.
|
94
|
+
|
95
|
+
## Licensing
|
96
|
+
|
97
|
+
Copyright 2011 Coda Hale. Licensed to you under the MIT license. Don't screw
|
98
|
+
this up for anyone.
|
data/Rakefile
ADDED
data/bin/mook
ADDED
data/lib/mook.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "redcarpet"
|
2
|
+
require "pygments.rb"
|
3
|
+
require "fileutils"
|
4
|
+
require "yaml"
|
5
|
+
require "erb"
|
6
|
+
|
7
|
+
module Mook
|
8
|
+
MARKDOWN_EXTENSIONS = %w{ .md .mdown .markdown }
|
9
|
+
end
|
10
|
+
|
11
|
+
require "mook/site"
|
12
|
+
require "mook/page"
|
13
|
+
require "mook/html"
|
14
|
+
require "mook/renderer"
|
15
|
+
require "mook/model"
|
data/lib/mook/html.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
module Mook
|
2
|
+
# Renders Markdown as HTML, Pygmentizing any named code blocks and generating
|
3
|
+
# TOC blocks.
|
4
|
+
class HtmlRenderer < Redcarpet::Render::HTML
|
5
|
+
include Redcarpet::Render::SmartyPants
|
6
|
+
|
7
|
+
def initialize(opts)
|
8
|
+
super(opts)
|
9
|
+
@toc = ""
|
10
|
+
@toc_id = 0
|
11
|
+
@toc_last_level = 0
|
12
|
+
@toc_closed = false
|
13
|
+
end
|
14
|
+
|
15
|
+
def block_code(code, language)
|
16
|
+
if language
|
17
|
+
Pygments.highlight(code, :lexer => language, :options => {:encoding => 'utf-8'})
|
18
|
+
else
|
19
|
+
"<pre>#{code}</pre>"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def header(text, header_level)
|
24
|
+
tag = if text =~ / #(.+)$/ then
|
25
|
+
text = text.gsub(/ #(.+)$/, "")
|
26
|
+
$1
|
27
|
+
else
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
@toc_id += 1
|
32
|
+
|
33
|
+
id = if tag then tag else "toc_#{@toc_id}" end
|
34
|
+
|
35
|
+
link = "<a href=\"##{id}\">#{text}</a>"
|
36
|
+
|
37
|
+
if @toc_last_level <= 0
|
38
|
+
@toc << "<li>#{link}"
|
39
|
+
else
|
40
|
+
if @toc_last_level == header_level
|
41
|
+
@toc << "</li><li>#{link}"
|
42
|
+
elsif @toc_last_level < header_level
|
43
|
+
@toc << "<ul><li>#{link}"
|
44
|
+
else
|
45
|
+
@toc << "</ul><li>#{link}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
@toc_last_level = header_level
|
50
|
+
|
51
|
+
"<a name=\"#{id}\"></a><h#{header_level}>#{text}</h#{header_level}>"
|
52
|
+
end
|
53
|
+
|
54
|
+
def toc
|
55
|
+
unless @toc_closed
|
56
|
+
@toc = "<ul>#{@toc}</li></ul>"
|
57
|
+
@toc_closed = true
|
58
|
+
end
|
59
|
+
@toc
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/mook/model.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Mook
|
2
|
+
class Model
|
3
|
+
def initialize(site, page)
|
4
|
+
@site = site
|
5
|
+
@page = page
|
6
|
+
end
|
7
|
+
|
8
|
+
def binding
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
attr_reader :site, :page
|
15
|
+
|
16
|
+
def partial(name)
|
17
|
+
partial = ERB.new(File.read(File.join("templates", "_#{name}.erb")))
|
18
|
+
partial.result(self.binding)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/mook/page.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
class Page
|
2
|
+
METADATA = %w{ title template order }
|
3
|
+
|
4
|
+
def self.load(filename)
|
5
|
+
lines = File.read(filename)
|
6
|
+
m, markdown = lines.split("* * *\n", 2)
|
7
|
+
metadata = Hash[*m.split("\n").map { |s| s.split(": ", 2) }.map { |k, v| [k.downcase, v] }.flatten]
|
8
|
+
|
9
|
+
raise "#{filename} has no title" unless metadata["title"]
|
10
|
+
raise "#{filename} has no template" unless metadata["template"]
|
11
|
+
|
12
|
+
order = (metadata["order"] || 1000).to_i
|
13
|
+
|
14
|
+
Page.new(File.basename(filename), metadata["title"],
|
15
|
+
metadata["template"], order,
|
16
|
+
markdown.strip)
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :name, :title, :template, :order, :markdown
|
20
|
+
attr_accessor :content, :output, :toc
|
21
|
+
|
22
|
+
def initialize(name, title, template, order, markdown)
|
23
|
+
@name = name.gsub(/\.[^\.]+$/, "")
|
24
|
+
@title = title
|
25
|
+
@template = template
|
26
|
+
@order = order
|
27
|
+
@markdown = markdown
|
28
|
+
end
|
29
|
+
|
30
|
+
def url
|
31
|
+
"#{@name}.html"
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Mook
|
2
|
+
class Renderer
|
3
|
+
MARKDOWN_OPTIONS = {
|
4
|
+
:strikethrough => true,
|
5
|
+
:fenced_code_blocks => true,
|
6
|
+
:space_after_headers => true,
|
7
|
+
:superscript => true,
|
8
|
+
:autolink => true
|
9
|
+
}
|
10
|
+
HTML_OPTIONS = {
|
11
|
+
|
12
|
+
}
|
13
|
+
|
14
|
+
def initialize(site)
|
15
|
+
@site = site
|
16
|
+
end
|
17
|
+
|
18
|
+
def render!(page)
|
19
|
+
renderer = HtmlRenderer.new(HTML_OPTIONS)
|
20
|
+
md = Redcarpet::Markdown.new(renderer, MARKDOWN_OPTIONS)
|
21
|
+
|
22
|
+
page.content = md.render(page.markdown)
|
23
|
+
page.toc = renderer.toc
|
24
|
+
|
25
|
+
template = ERB.new(File.read(File.join("templates", page.template)))
|
26
|
+
model = Model.new(@site, page)
|
27
|
+
page.output = renderer.postprocess(template.result(model.binding))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/mook/site.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Mook
|
2
|
+
class Site
|
3
|
+
def self.load(dir)
|
4
|
+
pages = []
|
5
|
+
for page_file in Dir.glob(File.join(dir, "pages", "*"))
|
6
|
+
if MARKDOWN_EXTENSIONS.member?(File.extname(page_file).downcase)
|
7
|
+
pages << Page.load(page_file)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
Site.new(pages.sort_by { |p| p.order })
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :pages
|
15
|
+
|
16
|
+
def initialize(pages)
|
17
|
+
@pages = pages
|
18
|
+
end
|
19
|
+
|
20
|
+
def render!
|
21
|
+
renderer = Renderer.new(self)
|
22
|
+
for page in @pages
|
23
|
+
renderer.render!(page)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def stage!
|
28
|
+
FileUtils.mkdir_p("target")
|
29
|
+
FileUtils.rm_rf(File.join("target", "*"))
|
30
|
+
FileUtils.cp_r(Dir.glob(File.join("static", "*")), "target")
|
31
|
+
for page in @pages
|
32
|
+
File.open(File.join("target", "#{page.name}.html"), "w+") do |f|
|
33
|
+
f << page.output
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/mook/version.rb
ADDED
data/mook.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "mook/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "mook"
|
7
|
+
s.version = Mook::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Coda Hale"]
|
10
|
+
s.email = ["coda.hale@gmail.com"]
|
11
|
+
s.homepage = "https://github.com/codahale/mook"
|
12
|
+
s.summary = %q{Yet another damn site generator thing.}
|
13
|
+
s.description = %q{Generates static HTML files from Markdown. But, like, well.}
|
14
|
+
s.add_dependency('redcarpet', '>= 2.1.0')
|
15
|
+
s.add_dependency('pygments.rb', '>= 0.2.4')
|
16
|
+
|
17
|
+
s.rubyforge_project = "mook"
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mook
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Coda Hale
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-02-04 00:00:00 -08:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: redcarpet
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 11
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 1
|
33
|
+
- 0
|
34
|
+
version: 2.1.0
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: pygments.rb
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 31
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 2
|
49
|
+
- 4
|
50
|
+
version: 0.2.4
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
description: Generates static HTML files from Markdown. But, like, well.
|
54
|
+
email:
|
55
|
+
- coda.hale@gmail.com
|
56
|
+
executables:
|
57
|
+
- mook
|
58
|
+
extensions: []
|
59
|
+
|
60
|
+
extra_rdoc_files: []
|
61
|
+
|
62
|
+
files:
|
63
|
+
- .gitignore
|
64
|
+
- Gemfile
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- bin/mook
|
68
|
+
- lib/mook.rb
|
69
|
+
- lib/mook/html.rb
|
70
|
+
- lib/mook/model.rb
|
71
|
+
- lib/mook/page.rb
|
72
|
+
- lib/mook/renderer.rb
|
73
|
+
- lib/mook/site.rb
|
74
|
+
- lib/mook/version.rb
|
75
|
+
- mook.gemspec
|
76
|
+
has_rdoc: true
|
77
|
+
homepage: https://github.com/codahale/mook
|
78
|
+
licenses: []
|
79
|
+
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
hash: 3
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
version: "0"
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
requirements: []
|
104
|
+
|
105
|
+
rubyforge_project: mook
|
106
|
+
rubygems_version: 1.3.7
|
107
|
+
signing_key:
|
108
|
+
specification_version: 3
|
109
|
+
summary: Yet another damn site generator thing.
|
110
|
+
test_files: []
|
111
|
+
|