| ... | ... |
@@ -5,7 +5,7 @@ |
| 5 | 5 |
<nav role=navigation>{% include navigation.html %}</nav>
|
| 6 | 6 |
<div id="main"> |
| 7 | 7 |
<div id="content"> |
| 8 |
- {{ content | expand_urls: root_url | backtick_codeblock | smart_quotes }}
|
|
| 8 |
+ {{ content | expand_urls: root_url }}
|
|
| 9 | 9 |
</div> |
| 10 | 10 |
</div> |
| 11 | 11 |
<footer>{% include footer.html %}</footer>
|
| 12 | 12 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,42 @@ |
| 0 |
+require './plugins/pygments_code' |
|
| 1 |
+ |
|
| 2 |
+module BacktickCodeBlock |
|
| 3 |
+ include HighlightCode |
|
| 4 |
+ AllOptions = /([^\s]+)\s+(.+?)(https?:\/\/\S+)\s*(.+)?/i |
|
| 5 |
+ LangCaption = /([^\s]+)\s*(.+)?/i |
|
| 6 |
+ def render_code_block(input) |
|
| 7 |
+ @caption = nil |
|
| 8 |
+ @lang = nil |
|
| 9 |
+ @url = nil |
|
| 10 |
+ @title = nil |
|
| 11 |
+ input.gsub /^`{3} *([^\n]+)?\n(.+?)\n`{3}/m do
|
|
| 12 |
+ options = $1 |
|
| 13 |
+ str = $2 |
|
| 14 |
+ |
|
| 15 |
+ if options =~ AllOptions |
|
| 16 |
+ @lang = $1 |
|
| 17 |
+ @caption = "<figcaption><span>#{$2}</span><a href='#{$3}'>#{$4 || 'link'}</a></figcaption>"
|
|
| 18 |
+ elsif options =~ LangCaption |
|
| 19 |
+ @lang = $1 |
|
| 20 |
+ @caption = "<figcaption><span>#{$2}</span></figcaption>"
|
|
| 21 |
+ end |
|
| 22 |
+ |
|
| 23 |
+ if str.match(/\A {4}/)
|
|
| 24 |
+ str = str.gsub /^ {4}/, ''
|
|
| 25 |
+ end |
|
| 26 |
+ if @lang.nil? || @lang == 'plain' |
|
| 27 |
+ code = tableize_code(str.gsub('<','<').gsub('>','>'))
|
|
| 28 |
+ "<figure role=code>#{@caption}#{code}</figure>"
|
|
| 29 |
+ else |
|
| 30 |
+ if @lang.include? "-raw" |
|
| 31 |
+ raw = "``` #{@lang.sub('-raw', '')}\n"
|
|
| 32 |
+ raw += str |
|
| 33 |
+ raw += "\n```\n" |
|
| 34 |
+ else |
|
| 35 |
+ code = highlight(str, @lang) |
|
| 36 |
+ "<figure role=code>#{@caption}#{code}</figure>"
|
|
| 37 |
+ end |
|
| 38 |
+ end |
|
| 39 |
+ end |
|
| 40 |
+ end |
|
| 41 |
+end |
| ... | ... |
@@ -42,11 +42,13 @@ |
| 42 | 42 |
# </figure> |
| 43 | 43 |
# |
| 44 | 44 |
require './plugins/pygments_code' |
| 45 |
+require './plugins/raw' |
|
| 45 | 46 |
|
| 46 | 47 |
module Jekyll |
| 47 | 48 |
|
| 48 | 49 |
class CodeBlock < Liquid::Block |
| 49 | 50 |
include HighlightCode |
| 51 |
+ include TemplateWrapper |
|
| 50 | 52 |
CaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)\s+(.+)/i |
| 51 | 53 |
CaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)/i |
| 52 | 54 |
Caption = /(\S[\S\s]*)/ |
| ... | ... |
@@ -78,14 +80,15 @@ module Jekyll |
| 78 | 78 |
def render(context) |
| 79 | 79 |
output = super |
| 80 | 80 |
code = super.join |
| 81 |
- source = "<div><figure role=code>" |
|
| 81 |
+ source = "<figure role=code>" |
|
| 82 | 82 |
source += @caption if @caption |
| 83 |
- source = context['pygments_prefix'] + source if context['pygments_prefix'] |
|
| 84 | 83 |
if @filetype |
| 85 |
- source += " #{highlight(code, @filetype)}</figure></div>"
|
|
| 84 |
+ source += " #{highlight(code, @filetype)}</figure>"
|
|
| 86 | 85 |
else |
| 87 |
- source += "#{tableize_code(code.lstrip.rstrip.gsub(/</,'<'))}</figure></div>"
|
|
| 86 |
+ source += "#{tableize_code(code.lstrip.rstrip.gsub(/</,'<'))}</figure>"
|
|
| 88 | 87 |
end |
| 88 |
+ source = safe_wrap(source) |
|
| 89 |
+ source = context['pygments_prefix'] + source if context['pygments_prefix'] |
|
| 89 | 90 |
source = source + context['pygments_suffix'] if context['pygments_suffix'] |
| 90 | 91 |
end |
| 91 | 92 |
end |
| ... | ... |
@@ -21,12 +21,14 @@ |
| 21 | 21 |
# |
| 22 | 22 |
|
| 23 | 23 |
require './plugins/pygments_code' |
| 24 |
+require './plugins/raw' |
|
| 24 | 25 |
require 'pathname' |
| 25 | 26 |
|
| 26 | 27 |
module Jekyll |
| 27 | 28 |
|
| 28 | 29 |
class IncludeCodeTag < Liquid::Tag |
| 29 | 30 |
include HighlightCode |
| 31 |
+ include TemplateWrapper |
|
| 30 | 32 |
def initialize(tag_name, markup, tokens) |
| 31 | 33 |
@title = nil |
| 32 | 34 |
@file = nil |
| ... | ... |
@@ -59,8 +61,9 @@ module Jekyll |
| 59 | 59 |
@filetype = file.extname.sub('.','') if @filetype.nil?
|
| 60 | 60 |
title = @title ? "#{@title} (#{file.basename})" : file.basename
|
| 61 | 61 |
url = "/#{code_dir}/#{@file}"
|
| 62 |
- source = "<div><figure role=code><figcaption><span>#{title}</span> <a href='#{url}'>download</a></figcaption>\n"
|
|
| 63 |
- source += " #{highlight(code, @filetype)}</figure></div>"
|
|
| 62 |
+ source = "<figure role=code><figcaption><span>#{title}</span> <a href='#{url}'>download</a></figcaption>\n"
|
|
| 63 |
+ source += " #{highlight(code, @filetype)}</figure>"
|
|
| 64 |
+ safe_wrap(source) |
|
| 64 | 65 |
end |
| 65 | 66 |
end |
| 66 | 67 |
end |
| ... | ... |
@@ -1,8 +1,38 @@ |
| 1 | 1 |
#custom filters for Octopress |
| 2 |
-require './plugins/pygments_code' |
|
| 2 |
+require './plugins/backtick_code_block' |
|
| 3 |
+require './plugins/post_filters' |
|
| 4 |
+require './plugins/raw' |
|
| 5 |
+require 'rubypants' |
|
| 3 | 6 |
|
| 4 | 7 |
module OctopressFilters |
| 5 |
- include HighlightCode |
|
| 8 |
+ include BacktickCodeBlock |
|
| 9 |
+ include TemplateWrapper |
|
| 10 |
+ def pre_filter(input) |
|
| 11 |
+ input = render_code_block(input) |
|
| 12 |
+ input.gsub /(<figure.+?>.+?<\/figure>)/m do |
|
| 13 |
+ safe_wrap($1) |
|
| 14 |
+ end |
|
| 15 |
+ end |
|
| 16 |
+ def post_filter(input) |
|
| 17 |
+ input = unwrap(input) |
|
| 18 |
+ RubyPants.new(input).to_html |
|
| 19 |
+ end |
|
| 20 |
+end |
|
| 21 |
+ |
|
| 22 |
+module Jekyll |
|
| 23 |
+ class ContentFilters < PostFilter |
|
| 24 |
+ include OctopressFilters |
|
| 25 |
+ def pre_render(post) |
|
| 26 |
+ post.content = pre_filter(post.content) |
|
| 27 |
+ end |
|
| 28 |
+ def post_render(post) |
|
| 29 |
+ post.content = post_filter(post.content) |
|
| 30 |
+ end |
|
| 31 |
+ end |
|
| 32 |
+end |
|
| 33 |
+ |
|
| 34 |
+ |
|
| 35 |
+module OctopressLiquidFilters |
|
| 6 | 36 |
# Used on the blog index to split posts on the <!--more--> marker |
| 7 | 37 |
def excerpt(input) |
| 8 | 38 |
if input.index(/<!--\s*more\s*-->/i) |
| ... | ... |
@@ -26,45 +56,6 @@ module OctopressFilters |
| 26 | 26 |
end |
| 27 | 27 |
end |
| 28 | 28 |
|
| 29 |
- # for Github style codeblocks eg. |
|
| 30 |
- # ``` ruby |
|
| 31 |
- # code snippet |
|
| 32 |
- # ``` |
|
| 33 |
- def backtick_codeblock(input) |
|
| 34 |
- code = nil |
|
| 35 |
- # Markdown support |
|
| 36 |
- input = input.gsub /<p>`{3}\s*(\w+)?<\/p>\s*<pre><code>\s*(.+?)\s*<\/code><\/pre>\s*<p>`{3}<\/p>/m do
|
|
| 37 |
- lang = $1 |
|
| 38 |
- if lang != '' |
|
| 39 |
- str = $2.gsub('<','<').gsub('>','>').gsub('&','&')
|
|
| 40 |
- code = highlight(str, lang) |
|
| 41 |
- "<figure role=code>#{code}</figure>"
|
|
| 42 |
- else |
|
| 43 |
- code = tableize_code($2) |
|
| 44 |
- "<figure role=code>#{code}</figure>"
|
|
| 45 |
- end |
|
| 46 |
- end |
|
| 47 |
- |
|
| 48 |
- # Textile warning |
|
| 49 |
- input = input.gsub /<p>`{3}\s*(\w+)?<br\s*\/>\n(.+?)`{3}<\/p>/m do
|
|
| 50 |
- lang = $1 |
|
| 51 |
- "<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>"
|
|
| 52 |
- end |
|
| 53 |
- |
|
| 54 |
- # Regular HTML support |
|
| 55 |
- input.gsub /^`{3}\s*(\w+)?\n(.+?)\n`{3}/m do
|
|
| 56 |
- lang = $1 |
|
| 57 |
- str = $2.gsub(/^\s{4}/, '')
|
|
| 58 |
- if lang != '' |
|
| 59 |
- code = highlight(str, lang) |
|
| 60 |
- "<figure role=code>#{code}</figure>"
|
|
| 61 |
- else |
|
| 62 |
- code = tableize_code($2.gsub('<','<').gsub('>','>'))
|
|
| 63 |
- "<figure role=code>#{code}</figure>"
|
|
| 64 |
- end |
|
| 65 |
- end |
|
| 66 |
- end |
|
| 67 |
- |
|
| 68 | 29 |
# Replaces relative urls with full urls |
| 69 | 30 |
def expand_urls(input, url='') |
| 70 | 31 |
url ||= '/' |
| ... | ... |
@@ -88,12 +79,6 @@ module OctopressFilters |
| 88 | 88 |
end |
| 89 | 89 |
end |
| 90 | 90 |
|
| 91 |
- # replaces primes with smartquotes using RubyPants |
|
| 92 |
- def smart_quotes(input) |
|
| 93 |
- require 'rubypants' |
|
| 94 |
- RubyPants.new(input).to_html |
|
| 95 |
- end |
|
| 96 |
- |
|
| 97 | 91 |
# Returns a title cased string based on John Gruber's title case http://daringfireball.net/2008/08/title_case_update |
| 98 | 92 |
def titlecase(input) |
| 99 | 93 |
input.titlecase |
| ... | ... |
@@ -127,5 +112,5 @@ module OctopressFilters |
| 127 | 127 |
end |
| 128 | 128 |
end |
| 129 | 129 |
end |
| 130 |
-Liquid::Template.register_filter OctopressFilters |
|
| 130 |
+Liquid::Template.register_filter OctopressLiquidFilters |
|
| 131 | 131 |
|
| ... | ... |
@@ -1,3 +1,19 @@ |
| 1 |
+# Author: Brandon Mathis |
|
| 2 |
+# Description: Provides plugins with a method for wrapping and unwrapping input to prevent Markdown and Textile from parsing it. |
|
| 3 |
+# Purpose: This is useful for preventing Markdown and Textile from being too aggressive and incorrectly parsing in-line HTML. |
|
| 4 |
+module TemplateWrapper |
|
| 5 |
+ # Wrap input with a <div> |
|
| 6 |
+ def safe_wrap(input) |
|
| 7 |
+ "<div class='bogus-wrapper'><notextile>#{input}</notextile></div>"
|
|
| 8 |
+ end |
|
| 9 |
+ # This must be applied after the |
|
| 10 |
+ def unwrap(input) |
|
| 11 |
+ input.gsub /<div class='bogus-wrapper'><notextile>(.+?)<\/notextile><\/div>/m do |
|
| 12 |
+ $1 |
|
| 13 |
+ end |
|
| 14 |
+ end |
|
| 15 |
+end |
|
| 16 |
+ |
|
| 1 | 17 |
# Author: phaer, https://github.com/phaer |
| 2 | 18 |
# Source: https://gist.github.com/1020852 |
| 3 | 19 |
# Description: Raw tag for jekyll. Keeps liquid from parsing text betweeen {% raw %} and {% endraw %}
|
| ... | ... |
@@ -22,10 +22,12 @@ |
| 22 | 22 |
# |
| 23 | 23 |
|
| 24 | 24 |
require 'pathname' |
| 25 |
+require './plugins/octopress_filters' |
|
| 25 | 26 |
|
| 26 | 27 |
module Jekyll |
| 27 | 28 |
|
| 28 | 29 |
class RenderPartialTag < Liquid::Tag |
| 30 |
+ include OctopressFilters |
|
| 29 | 31 |
def initialize(tag_name, markup, tokens) |
| 30 | 32 |
@file = nil |
| 31 | 33 |
@raw = false |
| ... | ... |
@@ -50,6 +52,7 @@ module Jekyll |
| 50 | 50 |
if contents =~ /\A-{3}.+[^\A]-{3}\n(.+)/m
|
| 51 | 51 |
contents = $1.lstrip |
| 52 | 52 |
end |
| 53 |
+ contents = pre_filter(contents) |
|
| 53 | 54 |
if @raw |
| 54 | 55 |
contents |
| 55 | 56 |
else |