Redcarpet / Bluecloth не позволяет заголовки? - PullRequest
3 голосов
/ 24 сентября 2011

Есть ли способ использовать Redcarpet или Bluecloth, чтобы при интерполяции уценки он не создавал заголовков?

Например:

#header 1

выход:

заголовок 1

заголовок 1 (предпочтительно)

А:

##header 2

выход:

заголовок 2

заголовок 2 (предпочтительно)

Ответы [ 4 ]

5 голосов
/ 24 сентября 2011

Ну, вы можете экранировать символы в Markdown:

# header 1
\# header 1

## header 2
\## header 2

... дает:

заголовок 1

# заголовок 1

заголовок 2

## header 2

Если вы не хотите этого делать, или вы анализируете уценку других людей и у вас нет выбора, я бы порекомендовал предварительно обработать входящую уценку, чтобы выполнить вышеуказанное для вас:

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

Используя Redcarpet, вы можете убедиться, что он работает:

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>

Конечно, поскольку разрыв строки в HTML фактически не отображается как таковой - он будет выглядеть как одна строка:

# Hello ## World "

... вы можете увеличить это:

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>

Этот последний будет выглядеть как:

# Привет

## World

К сожалению, вы в конечном итоге попадаете в странную территорию, подобную этой, где заголовок находится внутри цитаты:

> ## Heading

... но я оставляю это как упражнение для читателя.

1 голос
/ 25 октября 2015

Увидел подобное решение здесь , которое выглядело так:

class RenderWithoutWrap < Redcarpet::Render::HTML
  def postprocess(full_document)
    Regexp.new(/\A<p>(.*)<\/p>\Z/m).match(full_document)[1] rescue full_document
  end
end

Удаляет все теги <p> & </p>. Я использовал это так, и это сработало. Я поместил этот класс в новый файл с именем /config/initializers/render_without_wrap.rb. Вы можете сделать что-то подобное для всех тегов <h1> - <h6>

class RenderWithoutHeaders < Redcarpet::Render::HTML
  def postprocess(full_document)
    Regexp.new(/\A<h1>(.*)<\/h1>\Z/m).match(full_document)[1] rescue full_document
    Regexp.new(/\A<h2>(.*)<\/h2>\Z/m).match(full_document)[1] rescue full_document
    Regexp.new(/\A<h3>(.*)<\/h3>\Z/m).match(full_document)[1] rescue full_document
    ...(you get the idea)
  end
end

Затем вы можете использовать его так

def custom_markdown_parse(text)
  markdown = Redcarpet::Markdown.new(RenderWithoutHeaders.new(
    filter_html: true,
    hard_wrap: true,
    other_options: its_your_call
  ))
  markdown.render(text).html_safe
end

Я не проверял, но это идея.

1 голос
/ 24 сентября 2011

1. Вы должны иметь возможность избежать исходного текста уценки с помощью обратной косой черты:

\# not a header

2. Вы также можете сделать это:

module RedCloth::Formatters::HTML

  [:h1, :h2, :h3, :h4, :h5, :h6].each do |m|
    define_method(m) do |opts|
      "#{opts[:text]}\n"
    end
  end

end
0 голосов
/ 24 сентября 2011

Учитывая, что сложный предварительный разбор Markdown сложен, а Markdown позволяет вставлять HTML, как насчет удаления элементов заголовка из полученного HTML вместо этого?

...