1. Vastly improved backtick code blocks and added support for Textile
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
This commit is contained in:
parent
b25db54f93
commit
3d2d1a8be4
@ -5,7 +5,7 @@
|
|||||||
<nav role=navigation>{% include navigation.html %}</nav>
|
<nav role=navigation>{% include navigation.html %}</nav>
|
||||||
<div id="main">
|
<div id="main">
|
||||||
<div id="content">
|
<div id="content">
|
||||||
{{ content | expand_urls: root_url | backtick_codeblock | smart_quotes }}
|
{{ content | expand_urls: root_url }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>{% include footer.html %}</footer>
|
<footer>{% include footer.html %}</footer>
|
||||||
|
42
plugins/backtick_code_block.rb
Normal file
42
plugins/backtick_code_block.rb
Normal file
@ -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('<','<').gsub('>','>'))
|
||||||
|
"<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
|
@ -42,11 +42,13 @@
|
|||||||
# </figure>
|
# </figure>
|
||||||
#
|
#
|
||||||
require './plugins/pygments_code'
|
require './plugins/pygments_code'
|
||||||
|
require './plugins/raw'
|
||||||
|
|
||||||
module Jekyll
|
module Jekyll
|
||||||
|
|
||||||
class CodeBlock < Liquid::Block
|
class CodeBlock < Liquid::Block
|
||||||
include HighlightCode
|
include HighlightCode
|
||||||
|
include TemplateWrapper
|
||||||
CaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)\s+(.+)/i
|
CaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)\s+(.+)/i
|
||||||
CaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)/i
|
CaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)/i
|
||||||
Caption = /(\S[\S\s]*)/
|
Caption = /(\S[\S\s]*)/
|
||||||
@ -78,14 +80,15 @@ module Jekyll
|
|||||||
def render(context)
|
def render(context)
|
||||||
output = super
|
output = super
|
||||||
code = super.join
|
code = super.join
|
||||||
source = "<div><figure role=code>"
|
source = "<figure role=code>"
|
||||||
source += @caption if @caption
|
source += @caption if @caption
|
||||||
source = context['pygments_prefix'] + source if context['pygments_prefix']
|
|
||||||
if @filetype
|
if @filetype
|
||||||
source += " #{highlight(code, @filetype)}</figure></div>"
|
source += " #{highlight(code, @filetype)}</figure>"
|
||||||
else
|
else
|
||||||
source += "#{tableize_code(code.lstrip.rstrip.gsub(/</,'<'))}</figure></div>"
|
source += "#{tableize_code(code.lstrip.rstrip.gsub(/</,'<'))}</figure>"
|
||||||
end
|
end
|
||||||
|
source = safe_wrap(source)
|
||||||
|
source = context['pygments_prefix'] + source if context['pygments_prefix']
|
||||||
source = source + context['pygments_suffix'] if context['pygments_suffix']
|
source = source + context['pygments_suffix'] if context['pygments_suffix']
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -21,12 +21,14 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
require './plugins/pygments_code'
|
require './plugins/pygments_code'
|
||||||
|
require './plugins/raw'
|
||||||
require 'pathname'
|
require 'pathname'
|
||||||
|
|
||||||
module Jekyll
|
module Jekyll
|
||||||
|
|
||||||
class IncludeCodeTag < Liquid::Tag
|
class IncludeCodeTag < Liquid::Tag
|
||||||
include HighlightCode
|
include HighlightCode
|
||||||
|
include TemplateWrapper
|
||||||
def initialize(tag_name, markup, tokens)
|
def initialize(tag_name, markup, tokens)
|
||||||
@title = nil
|
@title = nil
|
||||||
@file = nil
|
@file = nil
|
||||||
@ -59,8 +61,9 @@ module Jekyll
|
|||||||
@filetype = file.extname.sub('.','') if @filetype.nil?
|
@filetype = file.extname.sub('.','') if @filetype.nil?
|
||||||
title = @title ? "#{@title} (#{file.basename})" : file.basename
|
title = @title ? "#{@title} (#{file.basename})" : file.basename
|
||||||
url = "/#{code_dir}/#{@file}"
|
url = "/#{code_dir}/#{@file}"
|
||||||
source = "<div><figure role=code><figcaption><span>#{title}</span> <a href='#{url}'>download</a></figcaption>\n"
|
source = "<figure role=code><figcaption><span>#{title}</span> <a href='#{url}'>download</a></figcaption>\n"
|
||||||
source += " #{highlight(code, @filetype)}</figure></div>"
|
source += " #{highlight(code, @filetype)}</figure>"
|
||||||
|
safe_wrap(source)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,8 +1,38 @@
|
|||||||
#custom filters for Octopress
|
#custom filters for Octopress
|
||||||
require './plugins/pygments_code'
|
require './plugins/backtick_code_block'
|
||||||
|
require './plugins/post_filters'
|
||||||
|
require './plugins/raw'
|
||||||
|
require 'rubypants'
|
||||||
|
|
||||||
module OctopressFilters
|
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
|
# Used on the blog index to split posts on the <!--more--> marker
|
||||||
def excerpt(input)
|
def excerpt(input)
|
||||||
if input.index(/<!--\s*more\s*-->/i)
|
if input.index(/<!--\s*more\s*-->/i)
|
||||||
@ -26,45 +56,6 @@ module OctopressFilters
|
|||||||
end
|
end
|
||||||
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('<','<').gsub('>','>').gsub('&','&')
|
|
||||||
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('<','<').gsub('>','>'))
|
|
||||||
"<figure role=code>#{code}</figure>"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Replaces relative urls with full urls
|
# Replaces relative urls with full urls
|
||||||
def expand_urls(input, url='')
|
def expand_urls(input, url='')
|
||||||
url ||= '/'
|
url ||= '/'
|
||||||
@ -88,12 +79,6 @@ module OctopressFilters
|
|||||||
end
|
end
|
||||||
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
|
# Returns a title cased string based on John Gruber's title case http://daringfireball.net/2008/08/title_case_update
|
||||||
def titlecase(input)
|
def titlecase(input)
|
||||||
input.titlecase
|
input.titlecase
|
||||||
@ -127,5 +112,5 @@ module OctopressFilters
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Liquid::Template.register_filter OctopressFilters
|
Liquid::Template.register_filter OctopressLiquidFilters
|
||||||
|
|
||||||
|
@ -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
|
# Author: phaer, https://github.com/phaer
|
||||||
# Source: https://gist.github.com/1020852
|
# Source: https://gist.github.com/1020852
|
||||||
# Description: Raw tag for jekyll. Keeps liquid from parsing text betweeen {% raw %} and {% endraw %}
|
# Description: Raw tag for jekyll. Keeps liquid from parsing text betweeen {% raw %} and {% endraw %}
|
||||||
|
@ -22,10 +22,12 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
require 'pathname'
|
require 'pathname'
|
||||||
|
require './plugins/octopress_filters'
|
||||||
|
|
||||||
module Jekyll
|
module Jekyll
|
||||||
|
|
||||||
class RenderPartialTag < Liquid::Tag
|
class RenderPartialTag < Liquid::Tag
|
||||||
|
include OctopressFilters
|
||||||
def initialize(tag_name, markup, tokens)
|
def initialize(tag_name, markup, tokens)
|
||||||
@file = nil
|
@file = nil
|
||||||
@raw = false
|
@raw = false
|
||||||
@ -50,6 +52,7 @@ module Jekyll
|
|||||||
if contents =~ /\A-{3}.+[^\A]-{3}\n(.+)/m
|
if contents =~ /\A-{3}.+[^\A]-{3}\n(.+)/m
|
||||||
contents = $1.lstrip
|
contents = $1.lstrip
|
||||||
end
|
end
|
||||||
|
contents = pre_filter(contents)
|
||||||
if @raw
|
if @raw
|
||||||
contents
|
contents
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user