ruby-on-railsrubyredcarpet

How to make Redcarpet optionally filter HTML tags?


I would like to whitelist some HTML tags, for example <kbd></kbd> so that I can show pretty keyboard icon for all keyboard shortcuts. How can I do this?

The code snippet below is the function I currently used to convert Markdown string into HTML.

  def markdown_to_html(markdown_str)
    options = {
      filter_html: true,
      link_attributes: { rel: 'nofollow', target: '_blank' },
      no_styles: true
    }

    extensions = {
      autolink: true,
      fenced_code_blocks: true,
      footnotes: true,
      highlight: true,
      no_intra_emphasis: true,
      quote: true,
      space_after_headers: true,
      strikethrough: true,
      superscript: true,
      tables: true
    }

    renderer = Redcarpet::Render::HTML.new(options)
    markdown = Redcarpet::Markdown.new(renderer, extensions)

    markdown.render(markdown_str).html_safe
  end

Solution

  • Use sanitize and your own custom scrubber class.

    This class can go in the same file as your controller class.

    class MarkdownScrubber < Rails::Html::PermitScrubber
      def initialize
        super
        self.tags = %w( kbd )
        self.attributes = []
      end
    
      def skip_node?(node)
        node.text?
      end
    end
    

    Then use that when you call render:

    renderer = Redcarpet::Render::HTML.new(options)
    markdown = Redcarpet::Markdown.new(renderer, extensions)
    sanitize(markdown.render(markdown_str), scrubber: MarkdownScrubber.new)