Merge branch 'code-cleanup' of git://github.com/tombell/jekyll into code-cleanup

Module Cleanup

* 'code-cleanup' of git://github.com/tombell/jekyll:
  Remove new lines between module and class
  Update tag classes moving into a module
  Update pagination classes moving into a module
  Update converter classes moving into a module
  Strip extra newlines
  Update command classes moving into a module

Conflicts:
	lib/jekyll/commands/serve.rb
This commit is contained in:
Parker Moore 2013-01-27 23:13:16 +01:00
commit b4bea4a586
28 changed files with 510 additions and 533 deletions

View File

@ -27,7 +27,7 @@ command :build do |c|
c.action do |args, options| c.action do |args, options|
options.defaults :serving => false options.defaults :serving => false
options = Jekyll.configuration(options.__hash__) options = Jekyll.configuration(options.__hash__)
Jekyll::BuildCommand.process(options) Jekyll::Commands::Build.process(options)
end end
end end
@ -49,8 +49,8 @@ command :serve do |c|
:serving => true :serving => true
options = Jekyll.configuration(options.__hash__) options = Jekyll.configuration(options.__hash__)
Jekyll::BuildCommand.process(options) Jekyll::Commands::Build.process(options)
Jekyll::ServeCommand.process(options) Jekyll::Commands::Serve.process(options)
end end
end end
@ -65,6 +65,6 @@ command :import do |c|
c.option '--host', 'Host address to use when migrating' c.option '--host', 'Host address to use when migrating'
c.action do |args, options| c.action do |args, options|
Jekyll::MigrateCommand.process(args.first, options) Jekyll::Commands::Migrate.process(args.first, options)
end end
end end

View File

@ -1,5 +1,4 @@
module Jekyll module Jekyll
class Command class Command
def self.globs(source) def self.globs(source)
Dir.chdir(source) do Dir.chdir(source) do
@ -10,5 +9,4 @@ module Jekyll
end end
end end
end end
end end

View File

@ -1,76 +1,76 @@
module Jekyll module Jekyll
module Commands
class Build < Command
def self.process(options)
site = Jekyll::Site.new(options)
class BuildCommand < Command source = options['source']
def self.process(options) destination = options['destination']
site = Jekyll::Site.new(options)
source = options['source'] if options['watch']
destination = options['destination'] self.watch(site, options)
else
if options['watch'] self.build(site, options)
self.watch(site, options) end
else
self.build(site, options)
end
end
# Private: Build the site from source into destination.
#
# site - A Jekyll::Site instance
# options - A Hash of options passed to the command
#
# Returns nothing.
def self.build(site, options)
source = options['source']
destination = options['destination']
puts "Building site: #{source} -> #{destination}"
begin
site.process
rescue Jekyll::FatalException => e
puts
puts "ERROR: YOUR SITE COULD NOT BE BUILT:"
puts "------------------------------------"
puts e.message
exit(1)
end
puts "Successfully generated site: #{source} -> #{destination}"
end
# Private: Watch for file changes and rebuild the site.
#
# site - A Jekyll::Site instance
# options - A Hash of options passed to the command
#
# Returns nothing.
def self.watch(site, options)
require 'directory_watcher'
source = options['source']
destination = options['destination']
puts "Auto-Regenerating enabled: #{source} -> #{destination}"
dw = DirectoryWatcher.new(source)
dw.interval = 1
dw.glob = self.globs(source)
dw.add_observer do |*args|
t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
puts "[#{t}] regeneration: #{args.size} files changed"
site.process
end end
dw.start # Private: Build the site from source into destination.
#
# site - A Jekyll::Site instance
# options - A Hash of options passed to the command
#
# Returns nothing.
def self.build(site, options)
source = options['source']
destination = options['destination']
puts "Building site: #{source} -> #{destination}"
begin
site.process
rescue Jekyll::FatalException => e
puts
puts "ERROR: YOUR SITE COULD NOT BE BUILT:"
puts "------------------------------------"
puts e.message
exit(1)
end
puts "Successfully generated site: #{source} -> #{destination}"
end
unless options['serving'] # Private: Watch for file changes and rebuild the site.
trap("INT") do #
puts "Stopping auto-regeneration..." # site - A Jekyll::Site instance
exit 0 # options - A Hash of options passed to the command
#
# Returns nothing.
def self.watch(site, options)
require 'directory_watcher'
source = options['source']
destination = options['destination']
puts "Auto-Regenerating enabled: #{source} -> #{destination}"
dw = DirectoryWatcher.new(source)
dw.interval = 1
dw.glob = self.globs(source)
dw.add_observer do |*args|
t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
puts "[#{t}] regeneration: #{args.size} files changed"
site.process
end end
loop { sleep 1000 } dw.start
unless options['serving']
trap("INT") do
puts "Stopping auto-regeneration..."
exit 0
end
loop { sleep 1000 }
end
end end
end end
end end
end end

View File

@ -1,47 +1,47 @@
module Jekyll module Jekyll
module Commands
class Migrate < Command
MIGRATORS = {
:csv => 'CSV',
:drupal => 'Drupal',
:enki => 'Enki',
:mephisto => 'Mephisto',
:mt => 'MT',
:posterous => 'Posterous',
:textpattern => 'TextPattern',
:tumblr => 'Tumblr',
:typo => 'Typo',
:wordpressdotcom => 'WordpressDotCom',
:wordpress => 'WordPress'
}
class MigrateCommand < Command def self.process(migrator, options)
MIGRATORS = { abort 'missing argument. Please specify a migrator' if migrator.nil?
:csv => 'CSV', migrator = migrator.downcase
:drupal => 'Drupal',
:enki => 'Enki',
:mephisto => 'Mephisto',
:mt => 'MT',
:posterous => 'Posterous',
:textpattern => 'TextPattern',
:tumblr => 'Tumblr',
:typo => 'Typo',
:wordpressdotcom => 'WordpressDotCom',
:wordpress => 'WordPress'
}
def self.process(migrator, options) cmd_options = []
abort 'missing argument. Please specify a migrator' if migrator.nil? [ :file, :dbname, :user, :pass, :host, :site ].each do |p|
migrator = migrator.downcase cmd_options << "\"#{options[p]}\"" unless options[p].nil?
cmd_options = []
[ :file, :dbname, :user, :pass, :host, :site ].each do |p|
cmd_options << "\"#{options[p]}\"" unless options[p].nil?
end
if MIGRATORS.keys.include?(migrator)
app_root = File.expand_path(
File.join(File.dirname(__FILE__), '..', '..', '..')
)
require "#{app_root}/lib/jekyll/migrators/#{migrator}"
if Jekyll.const_defiend?(MIGRATORS[migrator.to_sym])
puts 'Importing...'
migrator_class = Jekyll.const_get(MIGRATORS[migrator.to_sym])
migrator_class.process(*cmd_options)
exit 0
end end
end
abort 'invalid migrator. Please specify a valid migrator'
if MIGRATORS.keys.include?(migrator)
app_root = File.expand_path(
File.join(File.dirname(__FILE__), '..', '..', '..')
)
require "#{app_root}/lib/jekyll/migrators/#{migrator}"
if Jekyll.const_defiend?(MIGRATORS[migrator.to_sym])
puts 'Importing...'
migrator_class = Jekyll.const_get(MIGRATORS[migrator.to_sym])
migrator_class.process(*cmd_options)
exit 0
end
end
abort 'invalid migrator. Please specify a valid migrator'
end
end end
end end
end end

View File

@ -1,29 +1,29 @@
module Jekyll module Jekyll
module Commands
class Serve < Command
def self.process(options)
require 'webrick'
include WEBrick
class ServeCommand < Command destination = options['destination']
def self.process(options)
require 'webrick'
include WEBrick
destination = options['destination'] FileUtils.mkdir_p(destination)
FileUtils.mkdir_p(destination) mime_types = WEBrick::HTTPUtils::DefaultMimeTypes
mime_types.store 'js', 'application/javascript'
mime_types.store 'svg', 'image/svg+xml'
mime_types = WEBrick::HTTPUtils::DefaultMimeTypes s = HTTPServer.new(
mime_types.store 'js', 'application/javascript' :Port => options['port'],
mime_types.store 'svg', 'image/svg+xml' :BindAddress => options['host'],
:MimeTypes => mime_types
)
s = HTTPServer.new( s.mount(options['baseurl'], HTTPServlet::FileHandler, destination)
:Port => options['port'], t = Thread.new { s.start }
:BindAddress => options['host'], trap("INT") { s.shutdown }
:MimeTypes => mime_types t.join()
) end
s.mount(options['baseurl'], HTTPServlet::FileHandler, destination)
t = Thread.new { s.start }
trap("INT") { s.shutdown }
t.join()
end end
end end
end end

View File

@ -1,5 +1,4 @@
module Jekyll module Jekyll
class Converter < Plugin class Converter < Plugin
# Public: Get or set the pygments prefix. When an argument is specified, # Public: Get or set the pygments prefix. When an argument is specified,
# the prefix will be set. If no argument is specified, the current prefix # the prefix will be set. If no argument is specified, the current prefix
@ -46,5 +45,4 @@ module Jekyll
self.class.pygments_suffix self.class.pygments_suffix
end end
end end
end
end

View File

@ -1,22 +1,21 @@
module Jekyll module Jekyll
module Converters
class Identity < Converter
safe true
class IdentityConverter < Converter priority :lowest
safe true
priority :lowest def matches(ext)
true
end
def matches(ext) def output_ext(ext)
true ext
end
def convert(content)
content
end
end end
def output_ext(ext)
ext
end
def convert(content)
content
end
end end
end end

View File

@ -1,149 +1,149 @@
module Jekyll module Jekyll
module Converters
class Markdown < Converter
safe true
class MarkdownConverter < Converter pygments_prefix "\n"
safe true pygments_suffix "\n"
pygments_prefix "\n" def setup
pygments_suffix "\n" return if @setup
case @config['markdown']
when 'redcarpet'
begin
require 'redcarpet'
def setup @renderer ||= Class.new(Redcarpet::Render::HTML) do
return if @setup def block_code(code, lang)
case @config['markdown'] lang = lang && lang.split.first || "text"
when 'redcarpet' output = add_code_tags(
begin Pygments.highlight(code, :lexer => lang, :options => { :encoding => 'utf-8' }),
require 'redcarpet' lang
)
end
@renderer ||= Class.new(Redcarpet::Render::HTML) do def add_code_tags(code, lang)
def block_code(code, lang) code = code.sub(/<pre>/,'<pre><code class="' + lang + '">')
lang = lang && lang.split.first || "text" code = code.sub(/<\/pre>/,"</code></pre>")
output = add_code_tags( end
Pygments.highlight(code, :lexer => lang, :options => { :encoding => 'utf-8' }),
lang
)
end end
def add_code_tags(code, lang) @redcarpet_extensions = {}
code = code.sub(/<pre>/,'<pre><code class="' + lang + '">') @config['redcarpet']['extensions'].each { |e| @redcarpet_extensions[e.to_sym] = true }
code = code.sub(/<\/pre>/,"</code></pre>") rescue LoadError
STDERR.puts 'You are missing a library required for Markdown. Please run:'
STDERR.puts ' $ [sudo] gem install redcarpet'
raise FatalException.new("Missing dependency: redcarpet")
end
when 'kramdown'
begin
require 'kramdown'
rescue LoadError
STDERR.puts 'You are missing a library required for Markdown. Please run:'
STDERR.puts ' $ [sudo] gem install kramdown'
raise FatalException.new("Missing dependency: kramdown")
end
when 'rdiscount'
begin
require 'rdiscount'
@rdiscount_extensions = @config['rdiscount']['extensions'].map { |e| e.to_sym }
rescue LoadError
STDERR.puts 'You are missing a library required for Markdown. Please run:'
STDERR.puts ' $ [sudo] gem install rdiscount'
raise FatalException.new("Missing dependency: rdiscount")
end
when 'maruku'
begin
require 'maruku'
if @config['maruku']['use_divs']
require 'maruku/ext/div'
STDERR.puts 'Maruku: Using extended syntax for div elements.'
end end
if @config['maruku']['use_tex']
require 'maruku/ext/math'
STDERR.puts "Maruku: Using LaTeX extension. Images in `#{@config['maruku']['png_dir']}`."
# Switch off MathML output
MaRuKu::Globals[:html_math_output_mathml] = false
MaRuKu::Globals[:html_math_engine] = 'none'
# Turn on math to PNG support with blahtex
# Resulting PNGs stored in `images/latex`
MaRuKu::Globals[:html_math_output_png] = true
MaRuKu::Globals[:html_png_engine] = @config['maruku']['png_engine']
MaRuKu::Globals[:html_png_dir] = @config['maruku']['png_dir']
MaRuKu::Globals[:html_png_url] = @config['maruku']['png_url']
end
rescue LoadError
STDERR.puts 'You are missing a library required for Markdown. Please run:'
STDERR.puts ' $ [sudo] gem install maruku'
raise FatalException.new("Missing dependency: maruku")
end end
@redcarpet_extensions = {}
@config['redcarpet']['extensions'].each { |e| @redcarpet_extensions[e.to_sym] = true }
rescue LoadError
STDERR.puts 'You are missing a library required for Markdown. Please run:'
STDERR.puts ' $ [sudo] gem install redcarpet'
raise FatalException.new("Missing dependency: redcarpet")
end
when 'kramdown'
begin
require 'kramdown'
rescue LoadError
STDERR.puts 'You are missing a library required for Markdown. Please run:'
STDERR.puts ' $ [sudo] gem install kramdown'
raise FatalException.new("Missing dependency: kramdown")
end
when 'rdiscount'
begin
require 'rdiscount'
@rdiscount_extensions = @config['rdiscount']['extensions'].map { |e| e.to_sym }
rescue LoadError
STDERR.puts 'You are missing a library required for Markdown. Please run:'
STDERR.puts ' $ [sudo] gem install rdiscount'
raise FatalException.new("Missing dependency: rdiscount")
end
when 'maruku'
begin
require 'maruku'
if @config['maruku']['use_divs']
require 'maruku/ext/div'
STDERR.puts 'Maruku: Using extended syntax for div elements.'
end
if @config['maruku']['use_tex']
require 'maruku/ext/math'
STDERR.puts "Maruku: Using LaTeX extension. Images in `#{@config['maruku']['png_dir']}`."
# Switch off MathML output
MaRuKu::Globals[:html_math_output_mathml] = false
MaRuKu::Globals[:html_math_engine] = 'none'
# Turn on math to PNG support with blahtex
# Resulting PNGs stored in `images/latex`
MaRuKu::Globals[:html_math_output_png] = true
MaRuKu::Globals[:html_png_engine] = @config['maruku']['png_engine']
MaRuKu::Globals[:html_png_dir] = @config['maruku']['png_dir']
MaRuKu::Globals[:html_png_url] = @config['maruku']['png_url']
end
rescue LoadError
STDERR.puts 'You are missing a library required for Markdown. Please run:'
STDERR.puts ' $ [sudo] gem install maruku'
raise FatalException.new("Missing dependency: maruku")
end
else
STDERR.puts "Invalid Markdown processor: #{@config['markdown']}"
STDERR.puts " Valid options are [ maruku | rdiscount | kramdown ]"
raise FatalException.new("Invalid Markdown process: #{@config['markdown']}")
end
@setup = true
end
def matches(ext)
rgx = '(' + @config['markdown_ext'].gsub(',','|') +')'
ext =~ Regexp.new(rgx, Regexp::IGNORECASE)
end
def output_ext(ext)
".html"
end
def convert(content)
setup
case @config['markdown']
when 'redcarpet'
@redcarpet_extensions[:fenced_code_blocks] = !@redcarpet_extensions[:no_fenced_code_blocks]
@renderer.send :include, Redcarpet::Render::SmartyPants if @redcarpet_extensions[:smart]
markdown = Redcarpet::Markdown.new(@renderer.new(@redcarpet_extensions), @redcarpet_extensions)
markdown.render(content)
when 'kramdown'
# Check for use of coderay
if @config['kramdown']['use_coderay']
Kramdown::Document.new(content, {
:auto_ids => @config['kramdown']['auto_ids'],
:footnote_nr => @config['kramdown']['footnote_nr'],
:entity_output => @config['kramdown']['entity_output'],
:toc_levels => @config['kramdown']['toc_levels'],
:smart_quotes => @config['kramdown']['smart_quotes'],
:coderay_wrap => @config['kramdown']['coderay']['coderay_wrap'],
:coderay_line_numbers => @config['kramdown']['coderay']['coderay_line_numbers'],
:coderay_line_number_start => @config['kramdown']['coderay']['coderay_line_number_start'],
:coderay_tab_width => @config['kramdown']['coderay']['coderay_tab_width'],
:coderay_bold_every => @config['kramdown']['coderay']['coderay_bold_every'],
:coderay_css => @config['kramdown']['coderay']['coderay_css']
}).to_html
else else
# not using coderay STDERR.puts "Invalid Markdown processor: #{@config['markdown']}"
Kramdown::Document.new(content, { STDERR.puts " Valid options are [ maruku | rdiscount | kramdown ]"
:auto_ids => @config['kramdown']['auto_ids'], raise FatalException.new("Invalid Markdown process: #{@config['markdown']}")
:footnote_nr => @config['kramdown']['footnote_nr'], end
:entity_output => @config['kramdown']['entity_output'], @setup = true
:toc_levels => @config['kramdown']['toc_levels'], end
:smart_quotes => @config['kramdown']['smart_quotes']
}).to_html def matches(ext)
end rgx = '(' + @config['markdown_ext'].gsub(',','|') +')'
when 'rdiscount' ext =~ Regexp.new(rgx, Regexp::IGNORECASE)
rd = RDiscount.new(content, *@rdiscount_extensions) end
html = rd.to_html
if rd.generate_toc and html.include?(@config['rdiscount']['toc_token']) def output_ext(ext)
html.gsub!(@config['rdiscount']['toc_token'], rd.toc_content) ".html"
end end
html
when 'maruku' def convert(content)
Maruku.new(content).to_html setup
case @config['markdown']
when 'redcarpet'
@redcarpet_extensions[:fenced_code_blocks] = !@redcarpet_extensions[:no_fenced_code_blocks]
@renderer.send :include, Redcarpet::Render::SmartyPants if @redcarpet_extensions[:smart]
markdown = Redcarpet::Markdown.new(@renderer.new(@redcarpet_extensions), @redcarpet_extensions)
markdown.render(content)
when 'kramdown'
# Check for use of coderay
if @config['kramdown']['use_coderay']
Kramdown::Document.new(content, {
:auto_ids => @config['kramdown']['auto_ids'],
:footnote_nr => @config['kramdown']['footnote_nr'],
:entity_output => @config['kramdown']['entity_output'],
:toc_levels => @config['kramdown']['toc_levels'],
:smart_quotes => @config['kramdown']['smart_quotes'],
:coderay_wrap => @config['kramdown']['coderay']['coderay_wrap'],
:coderay_line_numbers => @config['kramdown']['coderay']['coderay_line_numbers'],
:coderay_line_number_start => @config['kramdown']['coderay']['coderay_line_number_start'],
:coderay_tab_width => @config['kramdown']['coderay']['coderay_tab_width'],
:coderay_bold_every => @config['kramdown']['coderay']['coderay_bold_every'],
:coderay_css => @config['kramdown']['coderay']['coderay_css']
}).to_html
else
# not using coderay
Kramdown::Document.new(content, {
:auto_ids => @config['kramdown']['auto_ids'],
:footnote_nr => @config['kramdown']['footnote_nr'],
:entity_output => @config['kramdown']['entity_output'],
:toc_levels => @config['kramdown']['toc_levels'],
:smart_quotes => @config['kramdown']['smart_quotes']
}).to_html
end
when 'rdiscount'
rd = RDiscount.new(content, *@rdiscount_extensions)
html = rd.to_html
if rd.generate_toc and html.include?(@config['rdiscount']['toc_token'])
html.gsub!(@config['rdiscount']['toc_token'], rd.toc_content)
end
html
when 'maruku'
Maruku.new(content).to_html
end
end end
end end
end end
end end

View File

@ -1,50 +1,50 @@
module Jekyll module Jekyll
module Converters
class Textile < Converter
safe true
class TextileConverter < Converter pygments_prefix '<notextile>'
safe true pygments_suffix '</notextile>'
pygments_prefix '<notextile>' def setup
pygments_suffix '</notextile>' return if @setup
require 'redcloth'
def setup @setup = true
return if @setup rescue LoadError
require 'redcloth' STDERR.puts 'You are missing a library required for Textile. Please run:'
@setup = true STDERR.puts ' $ [sudo] gem install RedCloth'
rescue LoadError raise FatalException.new("Missing dependency: RedCloth")
STDERR.puts 'You are missing a library required for Textile. Please run:'
STDERR.puts ' $ [sudo] gem install RedCloth'
raise FatalException.new("Missing dependency: RedCloth")
end
def matches(ext)
rgx = '(' + @config['textile_ext'].gsub(',','|') +')'
ext =~ Regexp.new(rgx, Regexp::IGNORECASE)
end
def output_ext(ext)
".html"
end
def convert(content)
setup
# Shortcut if config doesn't contain RedCloth section
return RedCloth.new(content).to_html if @config['redcloth'].nil?
# List of attributes defined on RedCloth
# (from http://redcloth.rubyforge.org/classes/RedCloth/TextileDoc.html)
attrs = ['filter_classes', 'filter_html', 'filter_ids', 'filter_styles',
'hard_breaks', 'lite_mode', 'no_span_caps', 'sanitize_html']
r = RedCloth.new(content)
# Set attributes in r if they are NOT nil in the config
attrs.each do |attr|
r.instance_variable_set("@#{attr}".to_sym, @config['redcloth'][attr]) unless @config['redcloth'][attr].nil?
end end
r.to_html def matches(ext)
rgx = '(' + @config['textile_ext'].gsub(',','|') +')'
ext =~ Regexp.new(rgx, Regexp::IGNORECASE)
end
def output_ext(ext)
".html"
end
def convert(content)
setup
# Shortcut if config doesn't contain RedCloth section
return RedCloth.new(content).to_html if @config['redcloth'].nil?
# List of attributes defined on RedCloth
# (from http://redcloth.rubyforge.org/classes/RedCloth/TextileDoc.html)
attrs = ['filter_classes', 'filter_html', 'filter_ids', 'filter_styles',
'hard_breaks', 'lite_mode', 'no_span_caps', 'sanitize_html']
r = RedCloth.new(content)
# Set attributes in r if they are NOT nil in the config
attrs.each do |attr|
r.instance_variable_set("@#{attr}".to_sym, @config['redcloth'][attr]) unless @config['redcloth'][attr].nil?
end
r.to_html
end
end end
end end
end end

View File

@ -1,6 +1,4 @@
module Jekyll module Jekyll
class FatalException < StandardError class FatalException < StandardError
end end
end
end

View File

@ -1,7 +1,6 @@
require 'uri' require 'uri'
module Jekyll module Jekyll
module Filters module Filters
# Convert a Textile string into HTML output. # Convert a Textile string into HTML output.
# #
@ -10,7 +9,7 @@ module Jekyll
# Returns the HTML formatted String. # Returns the HTML formatted String.
def textilize(input) def textilize(input)
site = @context.registers[:site] site = @context.registers[:site]
converter = site.getConverterImpl(Jekyll::TextileConverter) converter = site.getConverterImpl(Jekyll::Converters::Textile)
converter.convert(input) converter.convert(input)
end end
@ -21,7 +20,7 @@ module Jekyll
# Returns the HTML formatted String. # Returns the HTML formatted String.
def markdownify(input) def markdownify(input)
site = @context.registers[:site] site = @context.registers[:site]
converter = site.getConverterImpl(Jekyll::MarkdownConverter) converter = site.getConverterImpl(Jekyll::Converters::Markdown)
converter.convert(input) converter.convert(input)
end end
@ -124,6 +123,5 @@ module Jekyll
"#{array[0...-1].join(', ')}, #{connector} #{array[-1]}" "#{array[0...-1].join(', ')}, #{connector} #{array[-1]}"
end end
end end
end end
end end

View File

@ -1,7 +1,4 @@
module Jekyll module Jekyll
class Generator < Plugin class Generator < Plugin
end end
end
end

View File

@ -1,55 +1,56 @@
module Jekyll module Jekyll
module Generators
class Pagination < Generator
# This generator is safe from arbitrary code execution.
safe true
class Pagination < Generator # Generate paginated pages if necessary.
# This generator is safe from arbitrary code execution. #
safe true # site - The Site.
#
# Generate paginated pages if necessary. # Returns nothing.
# def generate(site)
# site - The Site. site.pages.dup.each do |page|
# paginate(site, page) if Pager.pagination_enabled?(site.config, page.name)
# Returns nothing.
def generate(site)
site.pages.dup.each do |page|
paginate(site, page) if Pager.pagination_enabled?(site.config, page.name)
end
end
# Paginates the blog's posts. Renders the index.html file into paginated
# directories, e.g.: page2/index.html, page3/index.html, etc and adds more
# site-wide data.
#
# site - The Site.
# page - The index.html Page that requires pagination.
#
# {"paginator" => { "page" => <Number>,
# "per_page" => <Number>,
# "posts" => [<Post>],
# "total_posts" => <Number>,
# "total_pages" => <Number>,
# "previous_page" => <Number>,
# "next_page" => <Number> }}
def paginate(site, page)
all_posts = site.site_payload['site']['posts']
pages = Pager.calculate_pages(all_posts, site.config['paginate'].to_i)
(1..pages).each do |num_page|
pager = Pager.new(site.config, num_page, all_posts, pages)
if num_page > 1
newpage = Page.new(site, site.source, page.dir, page.name)
newpage.pager = pager
newpage.dir = File.join(page.dir, paginate_path(site, num_page))
site.pages << newpage
else
page.pager = pager
end end
end end
end
private # Paginates the blog's posts. Renders the index.html file into paginated
def paginate_path(site, num_page) # directories, e.g.: page2/index.html, page3/index.html, etc and adds more
format = site.config['paginate_path'] # site-wide data.
format.sub(':num', num_page.to_s) #
# site - The Site.
# page - The index.html Page that requires pagination.
#
# {"paginator" => { "page" => <Number>,
# "per_page" => <Number>,
# "posts" => [<Post>],
# "total_posts" => <Number>,
# "total_pages" => <Number>,
# "previous_page" => <Number>,
# "next_page" => <Number> }}
def paginate(site, page)
all_posts = site.site_payload['site']['posts']
pages = Pager.calculate_pages(all_posts, site.config['paginate'].to_i)
(1..pages).each do |num_page|
pager = Pager.new(site.config, num_page, all_posts, pages)
if num_page > 1
newpage = Page.new(site, site.source, page.dir, page.name)
newpage.pager = pager
newpage.dir = File.join(page.dir, paginate_path(site, num_page))
site.pages << newpage
else
page.pager = pager
end
end
end end
private
def paginate_path(site, num_page)
format = site.config['paginate_path']
format.sub(':num', num_page.to_s)
end
end
end end
class Pager class Pager
@ -115,5 +116,4 @@ module Jekyll
} }
end end
end end
end end

View File

@ -1,5 +1,4 @@
module Jekyll module Jekyll
class Layout class Layout
include Convertible include Convertible
@ -40,5 +39,4 @@ module Jekyll
self.ext = File.extname(name) self.ext = File.extname(name)
end end
end end
end end

View File

@ -1,5 +1,4 @@
module Jekyll module Jekyll
class Page class Page
include Convertible include Convertible
@ -161,7 +160,5 @@ module Jekyll
def index? def index?
basename == 'index' basename == 'index'
end end
end end
end end

View File

@ -1,5 +1,4 @@
module Jekyll module Jekyll
class Plugin class Plugin
PRIORITIES = { :lowest => -100, PRIORITIES = { :lowest => -100,
:low => -10, :low => -10,
@ -73,5 +72,4 @@ module Jekyll
# no-op for default # no-op for default
end end
end end
end end

View File

@ -1,5 +1,4 @@
module Jekyll module Jekyll
class Post class Post
include Comparable include Comparable
include Convertible include Convertible
@ -281,5 +280,4 @@ module Jekyll
end end
end end
end end
end end

View File

@ -1,7 +1,6 @@
require 'set' require 'set'
module Jekyll module Jekyll
class Site class Site
attr_accessor :config, :layouts, :posts, :pages, :static_files, attr_accessor :config, :layouts, :posts, :pages, :static_files,
:categories, :exclude, :include, :source, :dest, :lsi, :pygments, :categories, :exclude, :include, :source, :dest, :lsi, :pygments,

View File

@ -1,5 +1,4 @@
module Jekyll module Jekyll
class StaticFile class StaticFile
# The cache of last modification times [path] -> mtime. # The cache of last modification times [path] -> mtime.
@@mtimes = Hash.new @@mtimes = Hash.new
@ -68,5 +67,4 @@ module Jekyll
nil nil
end end
end end
end end

View File

@ -1,77 +1,77 @@
module Jekyll module Jekyll
module Tags
class HighlightBlock < Liquid::Block
include Liquid::StandardFilters
class HighlightBlock < Liquid::Block # The regular expression syntax checker. Start with the language specifier.
include Liquid::StandardFilters # Follow that by zero or more space separated options that take one of two
# forms:
#
# 1. name
# 2. name=value
SYNTAX = /^([a-zA-Z0-9.+#-]+)((\s+\w+(=\w+)?)*)$/
# The regular expression syntax checker. Start with the language specifier. def initialize(tag_name, markup, tokens)
# Follow that by zero or more space separated options that take one of two super
# forms: if markup.strip =~ SYNTAX
# @lang = $1
# 1. name @options = {}
# 2. name=value if defined?($2) && $2 != ''
SYNTAX = /^([a-zA-Z0-9.+#-]+)((\s+\w+(=\w+)?)*)$/ $2.split.each do |opt|
key, value = opt.split('=')
def initialize(tag_name, markup, tokens) if value.nil?
super if key == 'linenos'
if markup.strip =~ SYNTAX value = 'inline'
@lang = $1 else
@options = {} value = true
if defined?($2) && $2 != '' end
$2.split.each do |opt|
key, value = opt.split('=')
if value.nil?
if key == 'linenos'
value = 'inline'
else
value = true
end end
@options[key] = value
end end
@options[key] = value
end end
else
raise SyntaxError.new("Syntax Error in 'highlight' - Valid syntax: highlight <lang> [linenos]")
end end
else
raise SyntaxError.new("Syntax Error in 'highlight' - Valid syntax: highlight <lang> [linenos]")
end end
end
def render(context) def render(context)
if context.registers[:site].pygments if context.registers[:site].pygments
render_pygments(context, super) render_pygments(context, super)
else else
render_codehighlighter(context, super) render_codehighlighter(context, super)
end
end end
def render_pygments(context, code)
@options[:encoding] = 'utf-8'
output = add_code_tags(
Pygments.highlight(code, :lexer => @lang, :options => @options),
@lang
)
output = context["pygments_prefix"] + output if context["pygments_prefix"]
output = output + context["pygments_suffix"] if context["pygments_suffix"]
output
end
def render_codehighlighter(context, code)
#The div is required because RDiscount blows ass
<<-HTML
<div>
<pre><code class='#{@lang}'>#{h(code).strip}</code></pre>
</div>
HTML
end
def add_code_tags(code, lang)
# Add nested <code> tags to code blocks
code = code.sub(/<pre>/,'<pre><code class="' + lang + '">')
code = code.sub(/<\/pre>/,"</code></pre>")
end
end end
def render_pygments(context, code)
@options[:encoding] = 'utf-8'
output = add_code_tags(
Pygments.highlight(code, :lexer => @lang, :options => @options),
@lang
)
output = context["pygments_prefix"] + output if context["pygments_prefix"]
output = output + context["pygments_suffix"] if context["pygments_suffix"]
output
end
def render_codehighlighter(context, code)
#The div is required because RDiscount blows ass
<<-HTML
<div>
<pre><code class='#{@lang}'>#{h(code).strip}</code></pre>
</div>
HTML
end
def add_code_tags(code, lang)
# Add nested <code> tags to code blocks
code = code.sub(/<pre>/,'<pre><code class="' + lang + '">')
code = code.sub(/<\/pre>/,"</code></pre>")
end
end end
end end
Liquid::Template.register_tag('highlight', Jekyll::HighlightBlock) Liquid::Template.register_tag('highlight', Jekyll::Tags::HighlightBlock)

View File

@ -1,37 +1,37 @@
module Jekyll module Jekyll
module Tags
class IncludeTag < Liquid::Tag class IncludeTag < Liquid::Tag
def initialize(tag_name, file, tokens) def initialize(tag_name, file, tokens)
super super
@file = file.strip @file = file.strip
end
def render(context)
includes_dir = File.join(context.registers[:site].source, '_includes')
if File.symlink?(includes_dir)
return "Includes directory '#{includes_dir}' cannot be a symlink"
end end
if @file !~ /^[a-zA-Z0-9_\/\.-]+$/ || @file =~ /\.\// || @file =~ /\/\./ def render(context)
return "Include file '#{@file}' contains invalid characters or sequences" includes_dir = File.join(context.registers[:site].source, '_includes')
end
Dir.chdir(includes_dir) do if File.symlink?(includes_dir)
choices = Dir['**/*'].reject { |x| File.symlink?(x) } return "Includes directory '#{includes_dir}' cannot be a symlink"
if choices.include?(@file) end
source = File.read(@file)
partial = Liquid::Template.parse(source) if @file !~ /^[a-zA-Z0-9_\/\.-]+$/ || @file =~ /\.\// || @file =~ /\/\./
context.stack do return "Include file '#{@file}' contains invalid characters or sequences"
partial.render(context) end
Dir.chdir(includes_dir) do
choices = Dir['**/*'].reject { |x| File.symlink?(x) }
if choices.include?(@file)
source = File.read(@file)
partial = Liquid::Template.parse(source)
context.stack do
partial.render(context)
end
else
"Included file '#{@file}' not found in _includes directory"
end end
else
"Included file '#{@file}' not found in _includes directory"
end end
end end
end end
end end
end end
Liquid::Template.register_tag('include', Jekyll::IncludeTag) Liquid::Template.register_tag('include', Jekyll::Tags::IncludeTag)

View File

@ -1,38 +1,39 @@
module Jekyll module Jekyll
module Tags
class PostComparer
MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)$/
class PostComparer attr_accessor :date, :slug
MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)$/
attr_accessor :date, :slug def initialize(name)
who, cares, date, slug = *name.match(MATCHER)
def initialize(name) @slug = slug
who, cares, date, slug = *name.match(MATCHER) @date = Time.parse(date)
@slug = slug end
@date = Time.parse(date)
end
end
class PostUrl < Liquid::Tag
def initialize(tag_name, post, tokens)
super
@orig_post = post.strip
@post = PostComparer.new(@orig_post)
end end
def render(context) class PostUrl < Liquid::Tag
site = context.registers[:site] def initialize(tag_name, post, tokens)
super
site.posts.each do |p| @orig_post = post.strip
if p == @post @post = PostComparer.new(@orig_post)
return p.url
end
end end
puts "ERROR: post_url: \"#{@orig_post}\" could not be found" def render(context)
site = context.registers[:site]
return "#" site.posts.each do |p|
if p == @post
return p.url
end
end
puts "ERROR: post_url: \"#{@orig_post}\" could not be found"
return "#"
end
end end
end end
end end
Liquid::Template.register_tag('post_url', Jekyll::PostUrl) Liquid::Template.register_tag('post_url', Jekyll::Tags::PostUrl)

View File

@ -17,16 +17,16 @@ class TestKramdown < Test::Unit::TestCase
# http://kramdown.rubyforge.org/converter/html.html#options # http://kramdown.rubyforge.org/converter/html.html#options
should "pass kramdown options" do should "pass kramdown options" do
markdown = MarkdownConverter.new(@config) markdown = Converters::Markdown.new(@config)
assert_equal "<h1>Some Header</h1>", markdown.convert('# Some Header #').strip assert_equal "<h1>Some Header</h1>", markdown.convert('# Some Header #').strip
end end
should "convert quotes to smart quotes" do should "convert quotes to smart quotes" do
markdown = MarkdownConverter.new(@config) markdown = Converters::Markdown.new(@config)
assert_equal "<p>&ldquo;Pit&rsquo;hy&rdquo;</p>", markdown.convert(%{"Pit'hy"}).strip assert_equal "<p>&ldquo;Pit&rsquo;hy&rdquo;</p>", markdown.convert(%{"Pit'hy"}).strip
override = { 'kramdown' => { 'smart_quotes' => 'lsaquo,rsaquo,laquo,raquo' } } override = { 'kramdown' => { 'smart_quotes' => 'lsaquo,rsaquo,laquo,raquo' } }
markdown = MarkdownConverter.new(@config.deep_merge(override)) markdown = Converters::Markdown.new(@config.deep_merge(override))
assert_equal "<p>&laquo;Pit&rsaquo;hy&raquo;</p>", markdown.convert(%{"Pit'hy"}).strip assert_equal "<p>&laquo;Pit&rsaquo;hy&raquo;</p>", markdown.convert(%{"Pit'hy"}).strip
end end
end end

View File

@ -457,34 +457,34 @@ class TestPost < Test::Unit::TestCase
should "process .md as markdown under default configuration" do should "process .md as markdown under default configuration" do
post = setup_post '2011-04-12-md-extension.md' post = setup_post '2011-04-12-md-extension.md'
conv = post.converter conv = post.converter
assert conv.kind_of? Jekyll::MarkdownConverter assert conv.kind_of? Jekyll::Converters::Markdown
end end
should "process .text as indentity under default configuration" do should "process .text as indentity under default configuration" do
post = setup_post '2011-04-12-text-extension.text' post = setup_post '2011-04-12-text-extension.text'
conv = post.converter conv = post.converter
assert conv.kind_of? Jekyll::IdentityConverter assert conv.kind_of? Jekyll::Converters::Identity
end end
should "process .text as markdown under alternate configuration" do should "process .text as markdown under alternate configuration" do
@site.config['markdown_ext'] = 'markdown,mdw,mdwn,md,text' @site.config['markdown_ext'] = 'markdown,mdw,mdwn,md,text'
post = setup_post '2011-04-12-text-extension.text' post = setup_post '2011-04-12-text-extension.text'
conv = post.converter conv = post.converter
assert conv.kind_of? Jekyll::MarkdownConverter assert conv.kind_of? Jekyll::Converters::Markdown
end end
should "process .md as markdown under alternate configuration" do should "process .md as markdown under alternate configuration" do
@site.config['markdown_ext'] = 'markdown,mkd,mkdn,md,text' @site.config['markdown_ext'] = 'markdown,mkd,mkdn,md,text'
post = setup_post '2011-04-12-text-extension.text' post = setup_post '2011-04-12-text-extension.text'
conv = post.converter conv = post.converter
assert conv.kind_of? Jekyll::MarkdownConverter assert conv.kind_of? Jekyll::Converters::Markdown
end end
should "process .text as textile under alternate configuration" do should "process .text as textile under alternate configuration" do
@site.config['textile_ext'] = 'textile,text' @site.config['textile_ext'] = 'textile,text'
post = setup_post '2011-04-12-text-extension.text' post = setup_post '2011-04-12-text-extension.text'
conv = post.converter conv = post.converter
assert conv.kind_of? Jekyll::TextileConverter assert conv.kind_of? Jekyll::Converters::Textile
end end
end end

View File

@ -8,7 +8,7 @@ class TestRdiscount < Test::Unit::TestCase
'markdown' => 'rdiscount', 'markdown' => 'rdiscount',
'rdiscount' => { 'extensions' => ['smart', 'generate_toc'], 'toc_token' => '{:toc}' } 'rdiscount' => { 'extensions' => ['smart', 'generate_toc'], 'toc_token' => '{:toc}' }
} }
@markdown = MarkdownConverter.new config @markdown = Converters::Markdown.new config
end end
should "pass rdiscount extensions" do should "pass rdiscount extensions" do

View File

@ -7,7 +7,7 @@ class TestRedcarpet < Test::Unit::TestCase
'redcarpet' => { 'extensions' => ['smart', 'strikethrough', 'filter_html'] }, 'redcarpet' => { 'extensions' => ['smart', 'strikethrough', 'filter_html'] },
'markdown' => 'redcarpet' 'markdown' => 'redcarpet'
} }
@markdown = MarkdownConverter.new config @markdown = Converters::Markdown.new config
end end
should "pass redcarpet options" do should "pass redcarpet options" do

View File

@ -4,7 +4,7 @@ class TestRedCloth < Test::Unit::TestCase
context "RedCloth default (no explicit config) hard_breaks enabled" do context "RedCloth default (no explicit config) hard_breaks enabled" do
setup do setup do
@textile = TextileConverter.new @textile = Converters::Textile.new
end end
should "preserve single line breaks in HTML output" do should "preserve single line breaks in HTML output" do
@ -17,7 +17,7 @@ class TestRedCloth < Test::Unit::TestCase
config = { config = {
'redcloth' => {} 'redcloth' => {}
} }
@textile = TextileConverter.new config @textile = Converters::Textile.new config
end end
should "preserve single line breaks in HTML output" do should "preserve single line breaks in HTML output" do
@ -32,7 +32,7 @@ class TestRedCloth < Test::Unit::TestCase
'hard_breaks' => true # default 'hard_breaks' => true # default
} }
} }
@textile = TextileConverter.new config @textile = Converters::Textile.new config
end end
should "preserve single line breaks in HTML output" do should "preserve single line breaks in HTML output" do
@ -47,7 +47,7 @@ class TestRedCloth < Test::Unit::TestCase
'hard_breaks' => false 'hard_breaks' => false
} }
} }
@textile = TextileConverter.new config @textile = Converters::Textile.new config
end end
should "not generate break tags in HTML output" do should "not generate break tags in HTML output" do
@ -62,7 +62,7 @@ class TestRedCloth < Test::Unit::TestCase
'no_span_caps' => false 'no_span_caps' => false
} }
} }
@textile = TextileConverter.new config @textile = Converters::Textile.new config
end end
should "generate span tags around capitalized words" do should "generate span tags around capitalized words" do
assert_equal "<p><span class=\"caps\">NSC</span></p>", @textile.convert("NSC").strip assert_equal "<p><span class=\"caps\">NSC</span></p>", @textile.convert("NSC").strip
@ -76,7 +76,7 @@ class TestRedCloth < Test::Unit::TestCase
'no_span_caps' => true 'no_span_caps' => true
} }
} }
@textile = TextileConverter.new config @textile = Converters::Textile.new config
end end
should "not generate span tags around capitalized words" do should "not generate span tags around capitalized words" do

View File

@ -4,7 +4,7 @@ require 'helper'
class TestTags < Test::Unit::TestCase class TestTags < Test::Unit::TestCase
def create_post(content, override = {}, converter_class = Jekyll::MarkdownConverter) def create_post(content, override = {}, converter_class = Jekyll::Converters::Markdown)
stub(Jekyll).configuration do stub(Jekyll).configuration do
Jekyll::DEFAULTS.deep_merge({'pygments' => true}).deep_merge(override) Jekyll::DEFAULTS.deep_merge({'pygments' => true}).deep_merge(override)
end end
@ -39,7 +39,7 @@ CONTENT
context "language name" do context "language name" do
should "match only the required set of chars" do should "match only the required set of chars" do
r = Jekyll::HighlightBlock::SYNTAX r = Jekyll::Tags::HighlightBlock::SYNTAX
assert_match r, "ruby" assert_match r, "ruby"
assert_match r, "c#" assert_match r, "c#"
assert_match r, "xml+cheetah" assert_match r, "xml+cheetah"
@ -55,19 +55,19 @@ CONTENT
context "initialized tag" do context "initialized tag" do
should "work" do should "work" do
tag = Jekyll::HighlightBlock.new('highlight', 'ruby ', ["test", "{% endhighlight %}", "\n"]) tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby ', ["test", "{% endhighlight %}", "\n"])
assert_equal({}, tag.instance_variable_get(:@options)) assert_equal({}, tag.instance_variable_get(:@options))
tag = Jekyll::HighlightBlock.new('highlight', 'ruby linenos ', ["test", "{% endhighlight %}", "\n"]) tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos ', ["test", "{% endhighlight %}", "\n"])
assert_equal({ 'linenos' => 'inline' }, tag.instance_variable_get(:@options)) assert_equal({ 'linenos' => 'inline' }, tag.instance_variable_get(:@options))
tag = Jekyll::HighlightBlock.new('highlight', 'ruby linenos=table ', ["test", "{% endhighlight %}", "\n"]) tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos=table ', ["test", "{% endhighlight %}", "\n"])
assert_equal({ 'linenos' => 'table' }, tag.instance_variable_get(:@options)) assert_equal({ 'linenos' => 'table' }, tag.instance_variable_get(:@options))
tag = Jekyll::HighlightBlock.new('highlight', 'ruby linenos=table nowrap', ["test", "{% endhighlight %}", "\n"]) tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos=table nowrap', ["test", "{% endhighlight %}", "\n"])
assert_equal({ 'linenos' => 'table', 'nowrap' => true }, tag.instance_variable_get(:@options)) assert_equal({ 'linenos' => 'table', 'nowrap' => true }, tag.instance_variable_get(:@options))
tag = Jekyll::HighlightBlock.new('highlight', 'ruby linenos=table cssclass=hl', ["test", "{% endhighlight %}", "\n"]) tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos=table cssclass=hl', ["test", "{% endhighlight %}", "\n"])
assert_equal({ 'cssclass' => 'hl', 'linenos' => 'table' }, tag.instance_variable_get(:@options)) assert_equal({ 'cssclass' => 'hl', 'linenos' => 'table' }, tag.instance_variable_get(:@options))
end end
end end
@ -129,7 +129,7 @@ CONTENT
context "using Textile" do context "using Textile" do
setup do setup do
create_post(@content, {}, Jekyll::TextileConverter) create_post(@content, {}, Jekyll::Converters::Textile)
end end
# Broken in RedCloth 4.1.9 # Broken in RedCloth 4.1.9