mook 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in mook.gemspec
4
+ gemspec
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
@@ -0,0 +1,3 @@
1
+ require 'bundler'
2
+ include Rake::DSL
3
+ Bundler::GemHelper.install_tasks
data/bin/mook ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ require "fileutils"
3
+ require "rubygems"
4
+ require "mook"
5
+
6
+ puts "> Loading"
7
+ site = Mook::Site.load(FileUtils.pwd)
8
+ puts "> Rendering"
9
+ site.render!
10
+ puts "> Staging"
11
+ site.stage!
12
+ puts "> Done"
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
@@ -0,0 +1,3 @@
1
+ module Mook
2
+ VERSION = "0.0.1"
3
+ end
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
+