Обновление: для записи, вот реализация, которую я в итоге использовал .
Вот урезанная версия парсера, над которым я работаю. Есть еще некоторый код, но должно быть довольно легко понять основные понятия этого синтаксического анализатора.
class Markup
def initialize(markup)
@markup = markup
end
def to_html
@html ||= @markup.split(/(\r\n){2,}|\n{2,}/).map {|p| Paragraph.new(p).to_html }.join("\n")
end
class Paragraph
def initialize(paragraph)
@p = paragraph
end
def to_html
@p.gsub!(/'{3}([^']+)'{3}/, "<strong>\\1</strong>")
@p.gsub!(/'{2}([^']+)'{2}/, "<em>\\1</em>")
@p.gsub!(/`([^`]+)`/, "<code>\\1</code>")
case @p
when /^=/
level = (@p.count("=") / 2) + 1 # Starting on h2
@p.gsub!(/^[= ]+|[= ]+$/, "")
"<h#{level}>" + @p + "</h#{level}>"
when /^(\*|\#)/
# I'm parsing lists here. Quite a lot of code, and not relevant, so
# I'm leaving it out.
else
@p.gsub!("\n", "\n<br/>")
"<p>" + @p + "</p>"
end
end
end
end
p Markup.new("Here is `code` and ''emphasis'' and '''bold'''!
Baz").to_html
# => "<p>Here is <code>code</code> and <em>emphasis</em> and <strong>bold</strong>!</p>\n<p>Baz</p>"
Итак, как вы можете видеть, я разбиваю текст на абзацы, и каждый абзац является либо заголовком, списком, либо обычным абзацем.
Реально ли добавить поддержку тегов nowiki (где все между не анализируется) для такого синтаксического анализатора? Не стесняйтесь отвечать «нет» и предлагать альтернативные способы создания парсера:)
В качестве sidenote вы можете увидеть фактический код парсера на Github. markup.rb и параграф.rb