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:
commit
b4bea4a586
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
module Jekyll
|
module Jekyll
|
||||||
|
|
||||||
class FatalException < StandardError
|
class FatalException < StandardError
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
|
@ -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
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
module Jekyll
|
module Jekyll
|
||||||
|
|
||||||
class Generator < Plugin
|
class Generator < Plugin
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>“Pit’hy”</p>", markdown.convert(%{"Pit'hy"}).strip
|
assert_equal "<p>“Pit’hy”</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>«Pit›hy»</p>", markdown.convert(%{"Pit'hy"}).strip
|
assert_equal "<p>«Pit›hy»</p>", markdown.convert(%{"Pit'hy"}).strip
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue