Created
November 1, 2013 21:53
-
-
Save 2called-chaos/7272548 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "shellwords" | |
class ContentRenderer | |
def initialize str, opts | |
@str = str.dup | |
@opts = opts.reverse_merge markdown: true, youtube: true | |
end | |
def to_str | |
@_rendered ||= @opts.inject(@str) do |text, (opt, perform)| | |
perform ? try("render_#{opt}", text) || text : text | |
end | |
end | |
alias_method :to_s, :to_str | |
def render_markdown str | |
renderer = HTMLwithPygments.new(hard_wrap: true, with_toc_data: true) | |
Redcarpet::Markdown.new(renderer, { | |
autolink: true, | |
fenced_code_blocks: true, | |
highlight: true, | |
lax_spacing: true, | |
no_intra_emphasis: false, | |
strikethrough: true, | |
superscript: true, | |
tables: true, | |
}).render(str) | |
end | |
def render_youtube str | |
process_tags(str, :youtube) do |args| | |
defaults = { | |
ratio: 16/9.0, # ratio to calculate width/height | |
autohide: 2, # [YT] controls behaviour 2 = fade progress, 1 = fade controls, 0 = fade nothing | |
autoplay: false, # [YT] autoplay on load | |
color: "red", # [YT] progress color (red or white) | |
disablekb: false, # [YT] disable player keyboard controls | |
enablejsapi: false, # [YT] enable JS API | |
end: nil, # [YT] end position in seconds (from 0:00) | |
iv_load_policy: 1, # [YT] annotations 1 = load, 2 = ?, 3 = don't load | |
loop: false, # [YT] loop video | |
modestbranding: false, # [YT] Hide YT logo in controls | |
origin: nil, # [YT] origin for JS API | |
playlist: nil, # [YT] list of video IDs to play (after if ID given) | |
rel: false, # [YT] show related videos at the end | |
showinfo: true, # [YT] Show video info (title bar) | |
start: nil, # [YT] start position in seconds | |
theme: "dark", # [YT] theme (dark or light) | |
vq: "large", # [YT] video quality (small, medium, large, hd720, hd1080) | |
} | |
args.reverse_merge!(defaults) | |
params = youtube_params(args.slice(*defaults.keys - [:ratio])) | |
# calculate dimensions if only one is given | |
args[:width] = 420 if !args[:width] && !args[:height] | |
args[:height] = args[:width] / args[:ratio] if args[:width] && !args[:height] | |
args[:width] = args[:height] * args[:ratio] if args[:height] && !args[:width] | |
%{ | |
<iframe | |
frameborder="0" | |
allowfullscreen="allowfullscreen" | |
width="#{args[:width]}" | |
height="#{args[:height]}" | |
src="//www.youtube.com/embed/#{args[:id]}?#{params.to_query}" | |
></iframe> | |
}.gsub("\n", "").squeeze(" ") | |
end | |
str | |
end | |
protected | |
# Searches for occurences of tags <tag> and | |
# replaces them with the result of &block. | |
def process_tags str, tag, &block | |
str.gsub!(/<#{tag}\s(.*?)>/im) do | |
args = {}.with_indifferent_access | |
Shellwords.shellsplit($1).each do |key_val| | |
key, val = *key_val.split("=", 2) | |
val = false if val.in? %w[false no] | |
val = true if val.in? %w[true yes] | |
val = parse_number(val) | |
args[key] = val | |
end | |
block.call(args) | |
end | |
str | |
end | |
# parse numbers from text value | |
def parse_number str | |
return str.to_i if str =~ /\A\d+\z/ | |
return Float(str) if Float(str) rescue nil | |
str | |
end | |
# youtubeify params (true = 1, false = 0) | |
def youtube_params params | |
params.each_with_object({}) do |(k, v), r| | |
r[k] = case v | |
when FalseClass then "0" | |
when TrueClass then "1" | |
else v | |
end | |
end | |
end | |
end | |
# create a custom renderer that allows highlighting of code blocks | |
class HTMLwithPygments < Redcarpet::Render::HTML | |
def block_code(code, language) | |
Pygments.highlight(code, lexer: language, options: { linespans: Digest::SHA1.base64digest(code) }) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Post < ActiveRecord::Base | |
def content opts = {} | |
ContentRenderer.new(body, opts) | |
end | |
end | |
# <youtube id="foobar"> | |
# <youtube id="foobar" autostart="yes" start="30" end="60"> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment