Redcarpet/Bluecloth не позволяет заголовки?
Есть ли способ использовать Redcarpet или Bluecloth, чтобы при интерполяции уценки он не создавал заголовки?
Например:
#header 1
выходы:
заголовок 1
заголовок 1 (предпочтительно)
А также:
##header 2
выходы:
заголовок 2
заголовок 2 (предпочтительно)
4 ответа
Ну, вы можете избежать символов в Markdown:
# header 1
\# header 1
## header 2
\## header 2
... дает:
заголовок 1
# заголовок 1
заголовок 2
## заголовок 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 фактически не отображается как таковой - он будет выглядеть как одна строка:
# Привет, мир"
... вы можете увеличить это:
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>
Этот последний будет выглядеть как:
# Привет
## Мир
К сожалению, вы в конечном итоге попадаете в странную территорию, подобную этой, где заголовок находится внутри цитаты:
> ## Heading
... но я оставляю это как упражнение для читателя.
Увидел подобное решение здесь, которое прошло так:
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. Вы должны иметь возможность избежать исходного текста уценки с помощью обратной косой черты:
\# 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
Принимая во внимание, что сложный предварительный разбор Markdown сложен, и Markdown позволяет вставлять HTML, как насчет удаления элементов заголовка из полученного HTML вместо этого?