Skip to content

Commit

Permalink
1. Vastly improved backtick code blocks and added support for Textile
Browse files Browse the repository at this point in the history
2. Refactored Octopress filters into Liquid filters and pre/post render filters (using post_filters plugin)
3. Added methods to raw plugin to prevent Markdown and Textile from parsing blocks
4. Updated render partial to invoke the pre_render method of post_filters
5. Moved Rubypants filter out of default.html into Octopress post_render filters
6. Added raw's safe_wrapper method to codeblock and include_code filters
  • Loading branch information
imathis committed Sep 7, 2011
1 parent b25db54 commit 3d2d1a8
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 55 deletions.
2 changes: 1 addition & 1 deletion .themes/classic/source/_layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<nav role=navigation>{% include navigation.html %}</nav>
<div id="main">
<div id="content">
{{ content | expand_urls: root_url | backtick_codeblock | smart_quotes }}
{{ content | expand_urls: root_url }}
</div>
</div>
<footer>{% include footer.html %}</footer>
Expand Down
42 changes: 42 additions & 0 deletions plugins/backtick_code_block.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
require './plugins/pygments_code'

module BacktickCodeBlock
include HighlightCode
AllOptions = /([^\s]+)\s+(.+?)(https?:\/\/\S+)\s*(.+)?/i
LangCaption = /([^\s]+)\s*(.+)?/i
def render_code_block(input)
@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 = "``` #{@lang.sub('-raw', '')}\n"
raw += str
raw += "\n```\n"
else
code = highlight(str, @lang)
"<figure role=code>#{@caption}#{code}</figure>"
end
end
end
end
end
11 changes: 7 additions & 4 deletions plugins/code_block.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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]*)/
Expand Down Expand Up @@ -78,14 +80,15 @@ def initialize(tag_name, markup, tokens)
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
Expand Down
7 changes: 5 additions & 2 deletions plugins/include_code.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -59,8 +61,9 @@ def render(context)
@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
Expand Down
81 changes: 33 additions & 48 deletions plugins/octopress_filters.rb
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -26,45 +56,6 @@ def summary(input)
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 ||= '/'
Expand All @@ -88,12 +79,6 @@ def shorthand_url(input)
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
Expand Down Expand Up @@ -127,5 +112,5 @@ def ordinal(number)
end
end
end
Liquid::Template.register_filter OctopressFilters
Liquid::Template.register_filter OctopressLiquidFilters

16 changes: 16 additions & 0 deletions plugins/raw.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# 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 %}
Expand Down
3 changes: 3 additions & 0 deletions plugins/render_partial.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -50,6 +52,7 @@ def render(context)
if contents =~ /\A-{3}.+[^\A]-{3}\n(.+)/m
contents = $1.lstrip
end
contents = pre_filter(contents)
if @raw
contents
else
Expand Down

0 comments on commit 3d2d1a8

Please sign in to comment.