Skip to content

Instantly share code, notes, and snippets.

@inopinatus
Created September 7, 2019 08:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inopinatus/80ee6fa99ac6db3d02a1b40122173edd to your computer and use it in GitHub Desktop.
Save inopinatus/80ee6fa99ac6db3d02a1b40122173edd to your computer and use it in GitHub Desktop.
Simple renderer for Markdown -> Liquid templates
# frozen_string_literal: true
require 'action_view/template'
module LiquidMarkdown
class Handler
cattr_accessor :markdown_options, default: { autolink: true, tables: true, no_intra_emphasis: true }
cattr_accessor :strict_liquid, default: true
def self.call(template, source = nil)
source ||= template.source
"__lmd_source=begin;#{source.inspect};end.freeze; LiquidMarkdown::Handler.new(self, __lmd_source, local_assigns).render;"
end
def initialize(view, source, local_assigns)
@view = view
@source = source
@local_assigns = local_assigns
end
def render
_render
end
private
attr_reader :source, :view, :local_assigns
def _render
if html?
wrapped_sanitized_body
else
body
end
end
def controller
view.controller
end
def html?
view.formats.include?(:html)
end
def wrapped_sanitized_body
'<div class="lmd-rendered">%s</div>' % sanitizer.sanitize(body)
end
def sanitizer
Rails::Html::WhiteListSanitizer.new
end
def body
liquid_renderer.render!(liquid_assigns, liquid_render_options)
end
def liquid_renderer
Liquid::Template.parse(liquid_template, liquid_parse_options)
end
def liquid_render_options
{
filters: liquid_filters,
registers: liquid_registers,
strict_variables: strict_liquid,
strict_filters: strict_liquid
}
end
def liquid_parse_options
{
error_mode: strict_liquid ? :strict : :lax
}
end
def liquid_template
if html?
markdown_renderer.render(source)
else
source
end
end
def liquid_assigns
if controller.respond_to?(:liquid_assigns, true)
controller.send(:liquid_assigns).stringify_keys
else
{}
end.merge!(local_assigns.stringify_keys)
end
def liquid_filters
if controller.respond_to?(:liquid_filters, true)
controller.send(:liquid_filters)
else
[]
end
end
def liquid_registers
{
view: view,
controller: controller
}
end
def markdown_renderer
Redcarpet::Markdown.new(Redcarpet::Render::HTML, markdown_options)
end
end
end
ActionView::Template.register_template_handler :lmd, LiquidMarkdown::Handler
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment