ruby-on-railsmarkdownblueclothredcarpet

Redcarpet/Bluecloth not allowing headers?


Is there a way to use either Redcarpet or Bluecloth such that when it interpolates the markdown it won't make any headers?

For example:

#header 1

yields:

header 1

header 1 (preferred)

And:

##header 2

yields:

header 2

header 2 (preferred)


Solution

  • Well, you can escape characters in Markdown:

    # header 1
    \# header 1
    
    ## header 2
    \## header 2
    

    ...gives:

    header 1

    # header 1

    header 2

    ## header 2

    If you don't want to have to do this, or you're parsing other people's Markdown and don't have a choice, I would recommend pre-processing the incoming Markdown to do the above for you:

    def pound_filter text
      text.gsub /^#/, '\#'
    end
    

    Using Redcarpet you can verify that it works:

    text = <<-END
      # Hello
      ## World
    END
    
    Markdown.new(text.to_html)
    # =>  <h1>Hello</h1>
    #
    #     <h2>World</h2>
    
    Markdown.new(pound_filter text).to_html
    # =>  <p># Hello
    #     ## World</p>
    

    Of course since a line break in HTML doesn't actually render as such--it will appear as one line:

    # Hello ## World"

    ...you might want to augment that:

    def pound_filter text
      text.gsub( /((\A^)|([^\A]^))#/ ) {|match| "\n" == match[0] ? "\n\n\\#" : '\#' }
    end
    
    pound_filter text
    # =>  \# Hello
    #
    #     \## World
    
    Markdown.new(pound_filter text).to_html
    # =>  <p>\# Hello</p>
    #
    #     <p>\## World</p>
    

    This last would appear as:

    # Hello

    ## World

    Unfortunately you eventually get into weird territory like this, where a heading is inside a quote:

    > ## Heading
    

    ...but I leave that as an exercise to the reader.