aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--plugins/backtick_code_block.rb43
-rw-r--r--plugins/category_generator.rb8
-rw-r--r--plugins/code_block.rb11
-rw-r--r--plugins/include_code.rb7
-rw-r--r--plugins/octopress_filters.rb81
-rw-r--r--plugins/post_filters.rb176
-rw-r--r--plugins/raw.rb40
-rw-r--r--plugins/render_partial.rb3
-rw-r--r--plugins/sitemap_generator.rb4
9 files changed, 316 insertions, 57 deletions
diff --git a/plugins/backtick_code_block.rb b/plugins/backtick_code_block.rb
new file mode 100644
index 00000000..7f5076df
--- /dev/null
+++ b/plugins/backtick_code_block.rb
@@ -0,0 +1,43 @@
+require './plugins/pygments_code'
+
+module BacktickCodeBlock
+ include HighlightCode
+ AllOptions = /([^\s]+)\s+(.+?)(https?:\/\/\S+)\s*(.+)?/i
+ LangCaption = /([^\s]+)\s*(.+)?/i
+ def render_code_block(input)
+ @options = nil
+ @caption = nil
+ @lang = nil
+ @url = nil
+ @title = nil
+ input.gsub /^`{3} *([^\n]+)?\n(.+?)\n`{3}/m do
+ @options = $1 || ''
+ str = $2
+
+ if @options =~ AllOptions
+ @lang = $1
+ @caption = "<figcaption><span>#{$2}</span><a href='#{$3}'>#{$4 || 'link'}</a></figcaption>"
+ elsif @options =~ LangCaption
+ @lang = $1
+ @caption = "<figcaption><span>#{$2}</span></figcaption>"
+ end
+
+ if str.match(/\A {4}/)
+ str = str.gsub /^ {4}/, ''
+ end
+ if @lang.nil? || @lang == 'plain'
+ code = tableize_code(str.gsub('<','&lt;').gsub('>','&gt;'))
+ "<figure role=code>#{@caption}#{code}</figure>"
+ else
+ if @lang.include? "-raw"
+ raw = "``` #{@options.sub('-raw', '')}\n"
+ raw += str
+ raw += "\n```\n"
+ else
+ code = highlight(str, @lang)
+ "<figure role=code>#{@caption}#{code}</figure>"
+ end
+ end
+ end
+ end
+end
diff --git a/plugins/category_generator.rb b/plugins/category_generator.rb
index aa1180e1..d9357bc8 100644
--- a/plugins/category_generator.rb
+++ b/plugins/category_generator.rb
@@ -1,3 +1,5 @@
+# encoding: utf-8
+#
# Jekyll category page generator.
# http://recursive-design.com/projects/jekyll-plugins/
#
@@ -16,8 +18,8 @@
# - category_dir: The subfolder to build category pages in (default is 'categories').
# - category_title_prefix: The string used before the category name in the page title (default is
# 'Category: ').
-module Jekyll
+module Jekyll
# The CategoryIndex class creates a single category page for the specified category.
class CategoryIndex < Page
@@ -68,7 +70,7 @@ module Jekyll
if self.layouts.key? 'category_index'
dir = self.config['category_dir'] || 'categories'
self.categories.keys.each do |category|
- self.write_category_index(File.join(dir, category.gsub(/_|\W/, '-')), category)
+ self.write_category_index(File.join(dir, category.gsub(/_|\P{Word}/, '-').gsub(/-{2,}/, '-').downcase), category)
end
# Throw an exception if the layout couldn't be found.
@@ -105,7 +107,7 @@ module Jekyll
def category_links(categories)
dir = @context.registers[:site].config['category_dir']
categories = categories.sort!.map do |item|
- "<a class='category' href='/#{dir}/#{item.gsub(/_|\W/, '-')}/'>#{item}</a>"
+ "<a class='category' href='/#{dir}/#{item.gsub(/_|\P{Word}/, '-').gsub(/-{2,}/, '-').downcase}/'>#{item}</a>"
end
case categories.length
diff --git a/plugins/code_block.rb b/plugins/code_block.rb
index 9c971bf5..00b0b438 100644
--- a/plugins/code_block.rb
+++ b/plugins/code_block.rb
@@ -42,11 +42,13 @@
# </figure>
#
require './plugins/pygments_code'
+require './plugins/raw'
module Jekyll
class CodeBlock < Liquid::Block
include HighlightCode
+ include TemplateWrapper
CaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)\s+(.+)/i
CaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)/i
Caption = /(\S[\S\s]*)/
@@ -78,14 +80,15 @@ module Jekyll
def render(context)
output = super
code = super.join
- source = "<div><figure role=code>"
+ source = "<figure role=code>"
source += @caption if @caption
- source = context['pygments_prefix'] + source if context['pygments_prefix']
if @filetype
- source += " #{highlight(code, @filetype)}</figure></div>"
+ source += " #{highlight(code, @filetype)}</figure>"
else
- source += "#{tableize_code(code.lstrip.rstrip.gsub(/</,'&lt;'))}</figure></div>"
+ source += "#{tableize_code(code.lstrip.rstrip.gsub(/</,'&lt;'))}</figure>"
end
+ source = safe_wrap(source)
+ source = context['pygments_prefix'] + source if context['pygments_prefix']
source = source + context['pygments_suffix'] if context['pygments_suffix']
end
end
diff --git a/plugins/include_code.rb b/plugins/include_code.rb
index 70d5f138..80951cb5 100644
--- a/plugins/include_code.rb
+++ b/plugins/include_code.rb
@@ -21,12 +21,14 @@
#
require './plugins/pygments_code'
+require './plugins/raw'
require 'pathname'
module Jekyll
class IncludeCodeTag < Liquid::Tag
include HighlightCode
+ include TemplateWrapper
def initialize(tag_name, markup, tokens)
@title = nil
@file = nil
@@ -59,8 +61,9 @@ module Jekyll
@filetype = file.extname.sub('.','') if @filetype.nil?
title = @title ? "#{@title} (#{file.basename})" : file.basename
url = "/#{code_dir}/#{@file}"
- source = "<div><figure role=code><figcaption><span>#{title}</span> <a href='#{url}'>download</a></figcaption>\n"
- source += " #{highlight(code, @filetype)}</figure></div>"
+ source = "<figure role=code><figcaption><span>#{title}</span> <a href='#{url}'>download</a></figcaption>\n"
+ source += " #{highlight(code, @filetype)}</figure>"
+ safe_wrap(source)
end
end
end
diff --git a/plugins/octopress_filters.rb b/plugins/octopress_filters.rb
index a63c43ab..1a959892 100644
--- a/plugins/octopress_filters.rb
+++ b/plugins/octopress_filters.rb
@@ -1,8 +1,38 @@
#custom filters for Octopress
-require './plugins/pygments_code'
+require './plugins/backtick_code_block'
+require './plugins/post_filters'
+require './plugins/raw'
+require 'rubypants'
module OctopressFilters
- include HighlightCode
+ include BacktickCodeBlock
+ include TemplateWrapper
+ def pre_filter(input)
+ input = render_code_block(input)
+ input.gsub /(<figure.+?>.+?<\/figure>)/m do
+ safe_wrap($1)
+ end
+ end
+ def post_filter(input)
+ input = unwrap(input)
+ RubyPants.new(input).to_html
+ end
+end
+
+module Jekyll
+ class ContentFilters < PostFilter
+ include OctopressFilters
+ def pre_render(post)
+ post.content = pre_filter(post.content)
+ end
+ def post_render(post)
+ post.content = post_filter(post.content)
+ end
+ end
+end
+
+
+module OctopressLiquidFilters
# Used on the blog index to split posts on the <!--more--> marker
def excerpt(input)
if input.index(/<!--\s*more\s*-->/i)
@@ -26,45 +56,6 @@ module OctopressFilters
end
end
- # for Github style codeblocks eg.
- # ``` ruby
- # code snippet
- # ```
- def backtick_codeblock(input)
- code = nil
- # Markdown support
- input = input.gsub /<p>`{3}\s*(\w+)?<\/p>\s*<pre><code>\s*(.+?)\s*<\/code><\/pre>\s*<p>`{3}<\/p>/m do
- lang = $1
- if lang != ''
- str = $2.gsub('&lt;','<').gsub('&gt;','>').gsub('&amp;','&')
- code = highlight(str, lang)
- "<figure role=code>#{code}</figure>"
- else
- code = tableize_code($2)
- "<figure role=code>#{code}</figure>"
- end
- end
-
- # Textile warning
- input = input.gsub /<p>`{3}\s*(\w+)?<br\s*\/>\n(.+?)`{3}<\/p>/m do
- lang = $1
- "<pre><code>Back tick code blocks are not supported for Textile.\nTry HTML or Markdown instead or use the codeblock tag.\n\n{% codeblock #{lang} %}\nYour code snippet\n{% endcodeblock %}</code></pre>"
- end
-
- # Regular HTML support
- input.gsub /^`{3}\s*(\w+)?\n(.+?)\n`{3}/m do
- lang = $1
- str = $2.gsub(/^\s{4}/, '')
- if lang != ''
- code = highlight(str, lang)
- "<figure role=code>#{code}</figure>"
- else
- code = tableize_code($2.gsub('<','&lt;').gsub('>','&gt;'))
- "<figure role=code>#{code}</figure>"
- end
- end
- end
-
# Replaces relative urls with full urls
def expand_urls(input, url='')
url ||= '/'
@@ -88,12 +79,6 @@ module OctopressFilters
end
end
- # replaces primes with smartquotes using RubyPants
- def smart_quotes(input)
- require 'rubypants'
- RubyPants.new(input).to_html
- end
-
# Returns a title cased string based on John Gruber's title case http://daringfireball.net/2008/08/title_case_update
def titlecase(input)
input.titlecase
@@ -127,5 +112,5 @@ module OctopressFilters
end
end
end
-Liquid::Template.register_filter OctopressFilters
+Liquid::Template.register_filter OctopressLiquidFilters
diff --git a/plugins/post_filters.rb b/plugins/post_filters.rb
new file mode 100644
index 00000000..08626802
--- /dev/null
+++ b/plugins/post_filters.rb
@@ -0,0 +1,176 @@
+module Jekyll
+
+ # Extended plugin type that allows the plugin
+ # to be called on varous callback methods.
+ #
+ # Examples:
+ # https://github.com/tedkulp/octopress/blob/master/plugins/post_metaweblog.rb
+ # https://github.com/tedkulp/octopress/blob/master/plugins/post_twitter.rb
+ class PostFilter < Plugin
+
+ #Called before post is sent to the converter. Allows
+ #you to modify the post object before the converter
+ #does it's thing
+ def pre_render(post)
+ end
+
+ #Called after the post is rendered with the converter.
+ #Use the post object to modify it's contents before the
+ #post is inserted into the template.
+ def post_render(post)
+ end
+
+ #Called after the post is written to the disk.
+ #Use the post object to read it's contents to do something
+ #after the post is safely written.
+ def post_write(post)
+ end
+ end
+
+ # Monkey patch for the Jekyll Site class. For the original class,
+ # see: https://github.com/mojombo/jekyll/blob/master/lib/jekyll/site.rb
+ class Site
+
+ # Instance variable to store the various post_filter
+ # plugins that are loaded.
+ attr_accessor :post_filters
+
+ # Instantiates all of the post_filter plugins. This is basically
+ # a duplication of the other loaders in Site#setup.
+ def load_post_filters
+ self.post_filters = Jekyll::PostFilter.subclasses.select do |c|
+ !self.safe || c.safe
+ end.map do |c|
+ c.new(self.config)
+ end
+ end
+ end
+
+ # Monkey patch for the Jekyll Post class. For the original class,
+ # see: https://github.com/mojombo/jekyll/blob/master/lib/jekyll/post.rb
+ class Post
+
+ # Copy the #write method to #old_write, so we can redefine #write
+ # method.
+ alias_method :old_write, :write
+
+ # Write the generated post file to the destination directory. It
+ # then calls any post_write methods that may exist.
+ # +dest+ is the String path to the destination dir
+ #
+ # Returns nothing
+ def write(dest)
+ old_write(dest)
+ post_write if respond_to?(:post_write)
+ end
+ end
+
+ # Monkey patch for the Jekyll Page class. For the original class,
+ # see: https://github.com/mojombo/jekyll/blob/master/lib/jekyll/page.rb
+ class Page
+
+ # Copy the #write method to #old_write, so we can redefine #write
+ # method.
+ alias_method :old_write, :write
+
+ # Write the generated post file to the destination directory. It
+ # then calls any post_write methods that may exist.
+ # +dest+ is the String path to the destination dir
+ #
+ # Returns nothing
+ def write(dest)
+ old_write(dest)
+ post_write if respond_to?(:post_write)
+ end
+ end
+
+ # Monkey patch for the Jekyll Convertible module. For the original class,
+ # see: https://github.com/mojombo/jekyll/blob/master/lib/jekyll/convertible.rb
+ module Convertible
+
+ def is_post?
+ self.class.to_s == 'Jekyll::Post'
+ end
+
+ def is_page?
+ self.class.to_s == 'Jekyll::Page'
+ end
+
+ def is_filterable?
+ is_post? or is_page?
+ end
+
+ # Call the #pre_render methods on all of the loaded
+ # post_filter plugins.
+ #
+ # Returns nothing
+ def pre_render
+ self.site.load_post_filters unless self.site.post_filters
+
+ if self.site.post_filters and is_filterable?
+ self.site.post_filters.each do |filter|
+ filter.pre_render(self)
+ end
+ end
+ end
+
+ # Call the #post_render methods on all of the loaded
+ # post_filter plugins.
+ #
+ # Returns nothing
+ def post_render
+ if self.site.post_filters and is_filterable?
+ self.site.post_filters.each do |filter|
+ filter.post_render(self)
+ end
+ end
+ end
+
+ # Call the #post_write methods on all of the loaded
+ # post_filter plugins.
+ #
+ # Returns nothing
+ def post_write
+ if self.site.post_filters and is_filterable?
+ self.site.post_filters.each do |filter|
+ filter.post_write(self)
+ end
+ end
+ end
+
+ # Copy the #transform method to #old_transform, so we can
+ # redefine #transform method.
+ alias_method :old_transform, :transform
+
+ # Transform the contents based on the content type. Then calls the
+ # #post_render method if it exists
+ #
+ # Returns nothing.
+ def transform
+ old_transform
+ post_render if respond_to?(:post_render)
+ end
+
+ # Copy the #do_layout method to #old_do_layout, so we can
+ # redefine #do_layout method.
+ alias_method :old_do_layout, :do_layout
+
+ # Calls the pre_render method if it exists and then adds any necessary
+ # layouts to this convertible document.
+ #
+ # payload - The site payload Hash.
+ # layouts - A Hash of {"name" => "layout"}.
+ #
+ # Returns nothing.
+ def do_layout(payload, layouts)
+ pre_render if respond_to?(:pre_render)
+ old_do_layout(payload, layouts)
+ end
+
+ # Returns the full url of the post, including the
+ # configured url
+ def full_url
+ self.site.config['url'] + self.url
+ end
+ end
+end
diff --git a/plugins/raw.rb b/plugins/raw.rb
new file mode 100644
index 00000000..4b002625
--- /dev/null
+++ b/plugins/raw.rb
@@ -0,0 +1,40 @@
+# Author: Brandon Mathis
+# Description: Provides plugins with a method for wrapping and unwrapping input to prevent Markdown and Textile from parsing it.
+# Purpose: This is useful for preventing Markdown and Textile from being too aggressive and incorrectly parsing in-line HTML.
+module TemplateWrapper
+ # Wrap input with a <div>
+ def safe_wrap(input)
+ "<div class='bogus-wrapper'><notextile>#{input}</notextile></div>"
+ end
+ # This must be applied after the
+ def unwrap(input)
+ input.gsub /<div class='bogus-wrapper'><notextile>(.+?)<\/notextile><\/div>/m do
+ $1
+ end
+ end
+end
+
+# Author: phaer, https://github.com/phaer
+# Source: https://gist.github.com/1020852
+# Description: Raw tag for jekyll. Keeps liquid from parsing text betweeen {% raw %} and {% endraw %}
+
+module Jekyll
+ class RawTag < Liquid::Block
+ def parse(tokens)
+ @nodelist ||= []
+ @nodelist.clear
+
+ while token = tokens.shift
+ if token =~ FullToken
+ if block_delimiter == $1
+ end_tag
+ return
+ end
+ end
+ @nodelist << token if not token.empty?
+ end
+ end
+ end
+end
+
+Liquid::Template.register_tag('raw', Jekyll::RawTag)
diff --git a/plugins/render_partial.rb b/plugins/render_partial.rb
index 9f665644..b6ebfe8b 100644
--- a/plugins/render_partial.rb
+++ b/plugins/render_partial.rb
@@ -22,10 +22,12 @@
#
require 'pathname'
+require './plugins/octopress_filters'
module Jekyll
class RenderPartialTag < Liquid::Tag
+ include OctopressFilters
def initialize(tag_name, markup, tokens)
@file = nil
@raw = false
@@ -50,6 +52,7 @@ module Jekyll
if contents =~ /\A-{3}.+[^\A]-{3}\n(.+)/m
contents = $1.lstrip
end
+ contents = pre_filter(contents)
if @raw
contents
else
diff --git a/plugins/sitemap_generator.rb b/plugins/sitemap_generator.rb
index 8b6cf78c..b63e9423 100644
--- a/plugins/sitemap_generator.rb
+++ b/plugins/sitemap_generator.rb
@@ -37,6 +37,7 @@
# Modified for Octopress by John W. Long
#
require 'rexml/document'
+require 'fileutils'
module Jekyll
@@ -122,6 +123,9 @@ module Jekyll
sitemap.add_element(urlset)
# File I/O: create sitemap.xml file and write out pretty-printed XML
+ unless File.exists?(site.dest)
+ FileUtils.mkdir_p(site.dest)
+ end
file = File.new(File.join(site.dest, SITEMAP_FILE_NAME), "w")
formatter = REXML::Formatters::Pretty.new(4)
formatter.compact = true