class Middleman::HashiCorp::RedcarpetHTML

Our custom Markdown parser - extends middleman's customer parser so we pick up all the magic.

Constants

REDCARPET_OPTIONS

Custom RedCarpet options.

Public Class Methods

new(options = {}) click to toggle source
Calls superclass method
# File lib/middleman-hashicorp/redcarpet.rb, line 21
def initialize(options = {})
  super(options.merge(REDCARPET_OPTIONS))
end

Public Instance Methods

block_html(raw) click to toggle source

Override block_html to support parsing nested markdown blocks.

@param [String] raw

# File lib/middleman-hashicorp/redcarpet.rb, line 67
def block_html(raw)
  raw = unindent(raw)

  if md = raw.match(/\<(.+?)\>(.*)\<(\/.+?)\>/m)
    open_tag, content, close_tag = md.captures
    rendered_content = recursive_render(content)
    # If the recursive render did more than simply wrap
    # the content within a paragraph, assume this is valid
    # markdown content and return the result
    if rendered_content != paragraph(content)
      return "<#{open_tag}>\n#{rendered_content}<#{close_tag}>"
    end
  end
  raw
end
header(title, level) click to toggle source

Override headers to add custom links.

# File lib/middleman-hashicorp/redcarpet.rb, line 28
  def header(title, level)
    anchor = anchor_link(title)

    return <<-EOH.gsub(/^ {6}/, "")
      <h#{level} id="#{anchor}">
        <a name="#{anchor}" class="anchor" href="##{anchor}">&raquo;</a>
        #{title}
      </h#{level}>
    EOH
  end
list_item(text, list_type) click to toggle source

Override list_item to automatically add links for documentation

@param [String] text @param [String] list_type

# File lib/middleman-hashicorp/redcarpet.rb, line 45
def list_item(text, list_type)
  @anchors ||= {}

  md = text.match(/\A(?:<p>)?(<code>(.+?)<\/code>)/)
  linked = !text.match(/\A(<p>)?<a(.+?)>(.+?)<\/a>\s*?[-:]?/).nil?

  if !md.nil? && !linked
    container, name = md.captures
    anchor = anchor_link(name)

    replace = %|<a name="#{anchor}" /><a href="##{anchor}">#{container}</a>|
    text.sub!(container, replace)
  end

  "<li>#{text}</li>\n"
end
paragraph(text) click to toggle source

Override paragraph to support custom alerts.

@param [String] text @return [String]

# File lib/middleman-hashicorp/redcarpet.rb, line 89
def paragraph(text)
  add_alerts("<p>#{text.strip}</p>\n")
end

Private Instance Methods

add_alerts(text) click to toggle source

Add alert text to the given markdown.

@param [String] text @return [String]

# File lib/middleman-hashicorp/redcarpet.rb, line 139
  def add_alerts(text)
    map = {
      "=&gt;" => "success",
      "-&gt;" => "info",
      "~&gt;" => "warning",
      "!&gt;" => "danger",
    }

    regexp = map.map { |k, _| Regexp.escape(k) }.join("|")

    if md = text.match(/^<p>(#{regexp})/)
      key = md.captures[0]
      klass = map[key]
      text.gsub!(/#{Regexp.escape(key)}\s+?/, "")

      return <<-EOH.gsub(/^ {8}/, "")
        <div class="alert alert-#{klass}" role="alert">
        #{text}</div>
      EOH
    else
      return text
    end
  end
recursive_render(markdown) click to toggle source

This is jank, but Redcarpet does not provide a way to access the renderer from inside Redcarpet::Markdown. Since we know who we are, we can cheat a bit.

@param [String] markdown @return [String]

# File lib/middleman-hashicorp/redcarpet.rb, line 129
def recursive_render(markdown)
  Redcarpet::Markdown.new(self.class, REDCARPET_OPTIONS).render(markdown)
end
unindent(string) click to toggle source
# File lib/middleman-hashicorp/redcarpet.rb, line 163
def unindent(string)
  string.gsub(/^#{string.scan(/^[[:blank:]]+/).min_by { |l| l.length }}/, "")
end