... | ... |
@@ -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 |