require 'redcarpet.so' module Redcarpet VERSION = '2.2.1' class Markdown attr_reader :renderer end module Render # XHTML Renderer class XHTML < HTML def initialize(extensions={}) super(extensions.merge(:xhtml => true)) end end # HTML + SmartyPants renderer class SmartyHTML < HTML include SmartyPants end # SmartyPants Mixin module # # Implements SmartyPants.postprocess, which # performs smartypants replacements on the HTML file, # once it has been fully rendered. # # To add SmartyPants postprocessing to your custom # renderers, just mixin the module `include SmartyPants` # # You can also use this as a standalone SmartyPants # implementation. # # Example: # # # Mixin # class CoolRenderer < HTML # include SmartyPants # # more code here # end # # # Standalone # Redcarpet::Render::SmartyPants.render("you're") # module SmartyPants extend self def self.render(text) postprocess text end end end end # Compatibility class; # Creates an instance of Redcarpet with the RedCloth API. class RedcarpetCompat attr_accessor :text def initialize(text, *exts) exts_hash, render_hash = *parse_extensions_and_renderer_options(exts) @text = text renderer = Redcarpet::Render::HTML.new(render_hash) @markdown = Redcarpet::Markdown.new(renderer, exts_hash) end def to_html(*_dummy) @markdown.render(@text) end private EXTENSION_MAP = { # old name => new name :autolink => :autolink, :fenced_code => :fenced_code_blocks, :filter_html => :filter_html, :hard_wrap => :hard_wrap, :lax_htmlblock => :lax_spacing, :no_image => :no_images, :no_intraemphasis => :no_intra_emphasis, :no_links => :no_links, :filter_styles => :no_styles, :safelink => :safe_links_only, :space_header => :space_after_headers, :strikethrough => :strikethrough, :tables => :tables, :generate_toc => :with_toc_data, :xhtml => :xhtml, # old names with no new mapping :gh_blockcode => nil, :no_tables => nil, :smart => nil, :strict => nil } RENDERER_OPTIONS = [:filter_html, :no_images, :no_links, :no_styles, :safe_links_only, :with_toc_data, :hard_wrap, :xhtml] def rename_extensions(exts) exts.map do |old_name| if new_name = EXTENSION_MAP[old_name] new_name else old_name end end.compact end # Returns two hashes, the extensions and renderer options # given the extension list def parse_extensions_and_renderer_options(exts) exts = rename_extensions(exts) exts.partition {|ext| !RENDERER_OPTIONS.include?(ext) }. map {|list| list_to_truthy_hash(list) } end # Turns a list of symbols into a hash of symbol => true. def list_to_truthy_hash(list) list.inject({}) {|h, k| h[k] = true; h } end end