Решение на Пета задача от Николай Добромиров

Обратно към всички решения

Към профила на Николай Добромиров

Резултати

  • 7 точки от тестове
  • 0 бонус точки
  • 7 точки общо
  • 49 успешни тест(а)
  • 8 неуспешни тест(а)

Код

# encoding: UTF-8
class Processor
attr_accessor :text
def initialize(text)
@text = text
end
def process()
raise "Not implemented!"
end
def process_content content
content
end
def process_text content
processors = [Entities, Bold, Italic, Link]
bold_index, italic_index = content.index("**"), content.index('_')
bold_is_after_italic = bold_index && italic_index && bold_index > italic_index
processors[1,2] = processors[1,2].reverse if bold_is_after_italic
processors.inject(content) {|result, processor| p processor.new(result).process}
end
end
class Entities < Processor
def process
translation_table = {'&'=>'&amp;', '<'=>'&lt;','>'=>'&gt;','"'=>'&quot;'}
text.gsub(/[<>&"]/) {|sign| translation_table[sign]}
end
end
class Link < Processor
def process
text.gsub(/\[(.+)\]\((.+)\)/) {|match| "<a href=\"#{$2}\">#{$1}</a>"}
end
end
class OrderedList < Processor
def process()
text.gsub(/^\d+\.\s(.+)$/) {|m| "<ol>\n <li>#{process_text $1.strip}</li>\n</ol>"}
.gsub(/<\/ol>\n<ol>\n/, '')
end
end
class UnorderedList < Processor
def process()
text.gsub(/^\*\s+(.+)$/) {|m| "<ul>\n <li>#{process_text $1.strip}</li>\n</ul>"}
.gsub(/<\/ul>\n<ul>\n/, '')
end
end
class Headings < Processor
def process
text.gsub(/^([#]{1,4})\s+([\w\*_].*)$/) do |m|
"<h#{$1.length}>#{process_text $2}</h#{$1.length}>"
end
end
end
class Code < Processor
def process
text.gsub(/(^ {4}.*?$)+/m){|m| "<pre><code>#{$1}</code></pre>"}
.gsub(/<pre><code> {4}/, '<pre><code>')
.gsub(/<\/code><\/pre>\n<pre><code>/, "\n")
.gsub(/<pre><code>(.+?)<\/code><\/pre>/) do |m|
"<pre><code>#{process_content $1}</code></pre>"
end
end
def process_content content
Entities.new(content).process
end
end
class Paragrapf < Processor
def process
pattern = /^((?! |\*\s+|\n|([#]{1,4})\s+([\w\*_].*)|> |\d+\.\s.+).*?)$/
text.gsub(pattern) {|m| "<p>#{$1.strip}</p>"}
.gsub(/<\/p>\n<p>/,"\n")
.gsub(/<p>(.+?)<\/p>/m) {|m| "<p>#{process_text $1.strip}</p>"}
end
end
class Blockquotes < Processor
def process
text.gsub(/^>\s(.*?)$/) {|m| "<blockquote>#{$1}</blockquote>"}
.gsub(/<\/blockquote>\n<blockquote>/, "\n")
.gsub(/<blockquote>(.*?)<\/blockquote>/m) do |m|
"<blockquote>#{process_content $1}</blockquote>"
end
end
def process_content content
Paragrapf.new(content).process
end
end
class Italic < Processor
def process
text.gsub(/_(.+?)_/) {|m| "<em>#{ process_content $1}</em>"}
end
def process_content content
if content.count('**') % 2 == 1 || content.count('strong>') % 2 == 1
content
else
Bold.new(content).process
end
end
end
class Bold < Processor
def process
text.gsub(/\*\*(.+?)\*\*/) {|m| "<strong>#{process_content $1}</strong>"}
end
def process_content content
if content.count('em>') % 2 == 1|| content.count('_') % 2 == 1
content
else
Italic.new(content).process
end
end
end
class Formatter
attr_accessor :output, :text
def initialize(mark_down_text)
@text = mark_down_text
@processors = [Paragrapf, OrderedList, UnorderedList, Headings, Code, Blockquotes,]
end
def to_html
result = processors.inject(text) do |output, processor|
processor.new(output).process
end
result.strip
end
def to_s
to_html
end
def inspect
@text
end
private
attr_accessor :processors
end

Лог от изпълнението

"Simple text!"
"Simple text!"
"Simple text!"
"Simple text!"
."First line."
"First line."
"First line."
"First line."
"Second line."
"Second line."
"Second line."
"Second line."
"Third line."
"Third line."
"Third line."
"Third line."
."First line.\nSecond line.\nThird line."
"First line.\nSecond line.\nThird line."
"First line.\nSecond line.\nThird line."
"First line.\nSecond line.\nThird line."
"Last line, of course."
"Last line, of course."
"Last line, of course."
"Last line, of course."
.F"First line."
"First line."
"First line."
"First line."
"Third line."
"Third line."
"Third line."
"Third line."
"Separate line"
"Separate line"
"Separate line"
"Separate line"
"Header..."
"Header..."
"Header..."
"Header..."
."Cats &amp; Cash"
"Cats &amp; Cash"
"Cats &amp; Cash"
"Cats &amp; Cash"
"Cool, &lt;right&gt;?"
"Cool, &lt;right&gt;?"
"Cool, &lt;right&gt;?"
"Cool, &lt;right&gt;?"
."This one is an H1"
"This one is an H1"
"This one is an H1"
"This one is an H1"
"This one is an H2"
"This one is an H2"
"This one is an H2"
"This one is an H2"
"This one is an H3"
"This one is an H3"
"This one is an H3"
"This one is an H3"
"This one is an H4"
"This one is an H4"
"This one is an H4"
"This one is an H4"
."This one is an H3 ###"
"This one is an H3 ###"
"This one is an H3 ###"
"This one is an H3 ###"
"This one is # an H4"
"This one is # an H4"
"This one is # an H4"
"This one is # an H4"
"## Leading wsp"
"## Leading wsp"
"## Leading wsp"
"## Leading wsp"
F"#No whitespace!"
"#No whitespace!"
"#No whitespace!"
"#No whitespace!"
"##### Header TOO small"
"##### Header TOO small"
"##### Header TOO small"
"##### Header TOO small"
"###"
"###"
"###"
"###"
."Cash &amp; &quot;Carry me away&quot;..."
"Cash &amp; &quot;Carry me away&quot;..."
"Cash &amp; &quot;Carry me away&quot;..."
"Cash &amp; &quot;Carry me away&quot;..."
.....F"Some parahraphs here"
"Some parahraphs here"
"Some parahraphs here"
"Some parahraphs here"
"More paragraphs there?"
"More paragraphs there?"
"More paragraphs there?"
"More paragraphs there?"
"This is a header"
"This is a header"
"This is a header"
"This is a header"
."Simple quote"
"Simple quote"
"Simple quote"
"Simple quote"
."First line.\nSecond line.\nThird line."
"First line.\nSecond line.\nThird line."
"First line.\nSecond line.\nThird line."
"First line.\nSecond line.\nThird line."
."First quote."
"First quote."
"First quote."
"First quote."
"Second quote."
"Second quote."
"Second quote."
"Second quote."
."First quote."
"First quote."
"First quote."
"First quote."
"Second quote."
"Second quote."
"Second quote."
"Second quote."
."Cuttin &amp; Pastin, w/o Quotin (&quot;)"
"Cuttin &amp; Pastin, w/o Quotin (&quot;)"
"Cuttin &amp; Pastin, w/o Quotin (&quot;)"
"Cuttin &amp; Pastin, w/o Quotin (&quot;)"
."[Programming in Ruby](http://fmi.ruby.bg/)"
"[Programming in Ruby](http://fmi.ruby.bg/)"
"[Programming in Ruby](http://fmi.ruby.bg/)"
"<a href=\"http://fmi.ruby.bg/\">Programming in Ruby</a>"
."\u0412\u044A\u043F\u0440\u043E\u0441? [\u0418\u043C\u0430 Google](http://google.com/) \u0437\u0430 \u0442\u0430\u0437\u0438 \u0446\u0435\u043B."
"\u0412\u044A\u043F\u0440\u043E\u0441? [\u0418\u043C\u0430 Google](http://google.com/) \u0437\u0430 \u0442\u0430\u0437\u0438 \u0446\u0435\u043B."
"\u0412\u044A\u043F\u0440\u043E\u0441? [\u0418\u043C\u0430 Google](http://google.com/) \u0437\u0430 \u0442\u0430\u0437\u0438 \u0446\u0435\u043B."
"\u0412\u044A\u043F\u0440\u043E\u0441? <a href=\"http://google.com/\">\u0418\u043C\u0430 Google</a> \u0437\u0430 \u0442\u0430\u0437\u0438 \u0446\u0435\u043B."
."We have [a first](some-url) and [Second](another-url)."
"We have [a first](some-url) and [Second](another-url)."
"We have [a first](some-url) and [Second](another-url)."
"We have <a href=\"another-url\">a first](some-url) and [Second</a>."
F"This one is [clearly] (broken)!"
"This one is [clearly] (broken)!"
"This one is [clearly] (broken)!"
"This one is [clearly] (broken)!"
"This one [is broken (too)]!"
"This one [is broken (too)]!"
"This one [is broken (too)]!"
"This one [is broken (too)]!"
"The wind [is blowing (here)!"
"The wind [is blowing (here)!"
"The wind [is blowing (here)!"
"The wind [is blowing (here)!"
.."Also testing [special &amp; &quot;entities&quot; &lt;b&gt;](here)."
"Also testing [special &amp; &quot;entities&quot; &lt;b&gt;](here)."
"Also testing [special &amp; &quot;entities&quot; &lt;b&gt;](here)."
"Also testing <a href=\"here\">special &amp; &quot;entities&quot; &lt;b&gt;</a>."
."Or [what if](special &amp; &quot;entities&quot; &lt;b&gt;) are in the URL, eh?"
"Or [what if](special &amp; &quot;entities&quot; &lt;b&gt;) are in the URL, eh?"
"Or [what if](special &amp; &quot;entities&quot; &lt;b&gt;) are in the URL, eh?"
"Or <a href=\"special &amp; &quot;entities&quot; &lt;b&gt;\">what if</a> are in the URL, eh?"
."\u0415\u0434\u043D\u043E."
"\u0415\u0434\u043D\u043E."
"\u0415\u0434\u043D\u043E."
"\u0415\u0434\u043D\u043E."
"\u0414\u0440\u0443\u0433\u043E."
"\u0414\u0440\u0443\u0433\u043E."
"\u0414\u0440\u0443\u0433\u043E."
"\u0414\u0440\u0443\u0433\u043E."
"\u0422\u0440\u0435\u0442\u043E..."
"\u0422\u0440\u0435\u0442\u043E..."
"\u0422\u0440\u0435\u0442\u043E..."
"\u0422\u0440\u0435\u0442\u043E..."
."\u041F\u044A\u0440\u0432\u043E."
"\u041F\u044A\u0440\u0432\u043E."
"\u041F\u044A\u0440\u0432\u043E."
"\u041F\u044A\u0440\u0432\u043E."
"\u0412\u0442\u043E\u0440\u043E."
"\u0412\u0442\u043E\u0440\u043E."
"\u0412\u0442\u043E\u0440\u043E."
"\u0412\u0442\u043E\u0440\u043E."
"\u0422\u0440\u0435\u0442\u043E..."
"\u0422\u0440\u0435\u0442\u043E..."
"\u0422\u0440\u0435\u0442\u043E..."
"\u0422\u0440\u0435\u0442\u043E..."
."Single item."
"Single item."
"Single item."
"Single item."
"Single item."
"Single item."
"Single item."
"Single item."
."1) \u041F\u044A\u0440\u0432\u043E.\n2 \u0412\u0442\u043E\u0440\u043E.\n3.\u0422\u0440\u0435\u0442\u043E"
"1) \u041F\u044A\u0440\u0432\u043E.\n2 \u0412\u0442\u043E\u0440\u043E.\n3.\u0422\u0440\u0435\u0442\u043E"
"1) \u041F\u044A\u0440\u0432\u043E.\n2 \u0412\u0442\u043E\u0440\u043E.\n3.\u0422\u0440\u0435\u0442\u043E"
"1) \u041F\u044A\u0440\u0432\u043E.\n2 \u0412\u0442\u043E\u0440\u043E.\n3.\u0422\u0440\u0435\u0442\u043E"
"\u0427\u0435\u0442\u0432\u044A\u0440\u0442\u043E"
"\u0427\u0435\u0442\u0432\u044A\u0440\u0442\u043E"
"\u0427\u0435\u0442\u0432\u044A\u0440\u0442\u043E"
"\u0427\u0435\u0442\u0432\u044A\u0440\u0442\u043E"
."The &amp;&amp; and || are logical operators"
"The &amp;&amp; and || are logical operators"
"The &amp;&amp; and || are logical operators"
"The &amp;&amp; and || are logical operators"
"The `&quot;` symbol"
"The `&quot;` symbol"
"The `&quot;` symbol"
"The `&quot;` symbol"
."A [simple link]( here ) or there?"
"A [simple link]( here ) or there?"
"A [simple link]( here ) or there?"
"A <a href=\" here \">simple link</a> or there?"
."_Simplest_ case"
"_Simplest_ case"
"<em>Simplest</em> case"
"<em>Simplest</em> case"
"_Simplest case_"
"_Simplest case_"
"<em>Simplest case</em>"
"<em>Simplest case</em>"
"**Simplest case**"
"<strong>Simplest case</strong>"
"<strong>Simplest case</strong>"
"<strong>Simplest case</strong>"
."Some _more words here_ _to be_ **emphasized**, okay?"
"Some <em>more words here</em> <em>to be</em> **emphasized**, okay?"
"Some <em>more words here</em> <em>to be</em> <strong>emphasized</strong>, okay?"
"Some <em>more words here</em> <em>to be</em> <strong>emphasized</strong>, okay?"
."_Simplest_ case"
"_Simplest_ case"
"<em>Simplest</em> case"
"<em>Simplest</em> case"
"_Simplest case_"
"_Simplest case_"
"<em>Simplest case</em>"
"<em>Simplest case</em>"
"**Simplest case**"
"<strong>Simplest case</strong>"
"<strong>Simplest case</strong>"
"<strong>Simplest case</strong>"
."_Simplest_ case"
"_Simplest_ case"
"<em>Simplest</em> case"
"<em>Simplest</em> case"
"_Simplest case_"
"_Simplest case_"
"<em>Simplest case</em>"
"<em>Simplest case</em>"
"**Strongest** case"
"<strong>Strongest</strong> case"
"<strong>Strongest</strong> case"
"<strong>Strongest</strong> case"
.."Some [_more words here_ _to be_ **emphasized**](okay)?"
"Some [<em>more words here</em> <em>to be</em> **emphasized**](okay)?"
"Some [<em>more words here</em> <em>to be</em> <strong>emphasized</strong>](okay)?"
"Some <a href=\"okay\"><em>more words here</em> <em>to be</em> <strong>emphasized</strong></a>?"
."Some _more words_ _to be_ **emphasized**"
"Some <em>more words</em> <em>to be</em> **emphasized**"
"Some <em>more words</em> <em>to be</em> <strong>emphasized</strong>"
"Some <em>more words</em> <em>to be</em> <strong>emphasized</strong>"
."Some [_more words_ _to be_ **emphasized**](okay)!"
"Some [<em>more words</em> <em>to be</em> **emphasized**](okay)!"
"Some [<em>more words</em> <em>to be</em> <strong>emphasized</strong>](okay)!"
"Some <a href=\"okay\"><em>more words</em> <em>to be</em> <strong>emphasized</strong></a>!"
."Some _more &amp; words_ _to be_ **&quot;emphasized&quot;**!"
"Some <em>more &amp; words</em> <em>to be</em> **&quot;emphasized&quot;**!"
"Some <em>more &amp; words</em> <em>to be</em> <strong>&quot;emphasized&quot;</strong>!"
"Some <em>more &amp; words</em> <em>to be</em> <strong>&quot;emphasized&quot;</strong>!"
."Some _more words **to be_ emphasized**!"
"Some <em>more words **to be</em> emphasized**!"
"Some <em>more words <strong>to be</em> emphasized</strong>!"
"Some <em>more words <strong>to be</em> emphasized</strong>!"
F"Some _more words **to be** emphasized_!"
"Some <em>more words <strong>to be</strong> emphasized</em>!"
"Some <em>more words <strong>to be</strong> emphasized</em>!"
"Some <em>more words <strong>to be</strong> emphasized</em>!"
"Some **more words _to be_ emphasized**!"
"Some <strong>more words <em>to be</em> emphasized</strong>!"
"Some <strong>more words <em>to be</em> emphasized</strong>!"
"Some <strong>more words <em>to be</em> emphasized</strong>!"
."&quot;Black &amp; Decker&quot;!"
"&quot;Black &amp; Decker&quot;!"
"&quot;Black &amp; Decker&quot;!"
"&quot;Black &amp; Decker&quot;!"
."## &quot;Black &amp; Decker&quot;!"
"## &quot;Black &amp; Decker&quot;!"
"## &quot;Black &amp; Decker&quot;!"
"## &quot;Black &amp; Decker&quot;!"
F."&quot;Black &amp; Decker&quot;!"
"&quot;Black &amp; Decker&quot;!"
"&quot;Black &amp; Decker&quot;!"
"&quot;Black &amp; Decker&quot;!"
."_&quot;Black &amp; Decker&quot;_!"
"_&quot;Black &amp; Decker&quot;_!"
"<em>&quot;Black &amp; Decker&quot;</em>!"
"<em>&quot;Black &amp; Decker&quot;</em>!"
."Some txt"
"Some txt"
"Some txt"
"Some txt"
"Some txt"
"Some txt"
"Some txt"
"Some txt"
"Some txt"
"Some txt"
"Some txt"
"Some txt"
"Some txt"
"Some txt"
"Some txt"
"Some txt"
."A line here"
"A line here"
"A line here"
"A line here"
"First one."
"First one."
"First one."
"First one."
"Second one."
"Second one."
"Second one."
"Second one."
"#    Test with a header"
"#    Test with a header"
"#    Test with a header"
"#    Test with a header"
F."simple"
"simple"
"simple"
"simple"
."Plain"
"Plain"
"Plain"
"Plain"
.."# \u0426\u044F\u043B\u043E\u0441\u0442\u0435\u043D \u043F\u0440\u0438\u043C\u0435\u0440\n\u0422\u0443\u043A \u0449\u0435 \u0434\u0435\u043C\u043E\u043D\u0441\u0442\u0440\u0438\u0440\u0430\u043C\u0435 \u043D\u0430\u043A\u0440\u0430\u0442\u043A\u043E \u0432\u044A\u0437\u043C\u043E\u0436\u043D\u043E\u0441\u0442\u0438\u0442\u0435 \u043D\u0430 \u043D\u0430\u0448\u0438\u044F \u043F\u0440\u043E\u0441\u0442 Markdown-\u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u0432\u0430\u0442\u0435\u043B."
"# \u0426\u044F\u043B\u043E\u0441\u0442\u0435\u043D \u043F\u0440\u0438\u043C\u0435\u0440\n\u0422\u0443\u043A \u0449\u0435 \u0434\u0435\u043C\u043E\u043D\u0441\u0442\u0440\u0438\u0440\u0430\u043C\u0435 \u043D\u0430\u043A\u0440\u0430\u0442\u043A\u043E \u0432\u044A\u0437\u043C\u043E\u0436\u043D\u043E\u0441\u0442\u0438\u0442\u0435 \u043D\u0430 \u043D\u0430\u0448\u0438\u044F \u043F\u0440\u043E\u0441\u0442 Markdown-\u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u0432\u0430\u0442\u0435\u043B."
"# \u0426\u044F\u043B\u043E\u0441\u0442\u0435\u043D \u043F\u0440\u0438\u043C\u0435\u0440\n\u0422\u0443\u043A \u0449\u0435 \u0434\u0435\u043C\u043E\u043D\u0441\u0442\u0440\u0438\u0440\u0430\u043C\u0435 \u043D\u0430\u043A\u0440\u0430\u0442\u043A\u043E \u0432\u044A\u0437\u043C\u043E\u0436\u043D\u043E\u0441\u0442\u0438\u0442\u0435 \u043D\u0430 \u043D\u0430\u0448\u0438\u044F \u043F\u0440\u043E\u0441\u0442 Markdown-\u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u0432\u0430\u0442\u0435\u043B."
"# \u0426\u044F\u043B\u043E\u0441\u0442\u0435\u043D \u043F\u0440\u0438\u043C\u0435\u0440\n\u0422\u0443\u043A \u0449\u0435 \u0434\u0435\u043C\u043E\u043D\u0441\u0442\u0440\u0438\u0440\u0430\u043C\u0435 \u043D\u0430\u043A\u0440\u0430\u0442\u043A\u043E \u0432\u044A\u0437\u043C\u043E\u0436\u043D\u043E\u0441\u0442\u0438\u0442\u0435 \u043D\u0430 \u043D\u0430\u0448\u0438\u044F \u043F\u0440\u043E\u0441\u0442 Markdown-\u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u0432\u0430\u0442\u0435\u043B."
"\u041A\u0440\u0430\u0442\u044A\u043A \u0446\u0438\u0442\u0430\u0442 \u043E\u0442\u043D\u043E\u0441\u043D\u043E \u0444\u0438\u043B\u043E\u0441\u043E\u0444\u0438\u044F\u0442\u0430 \u043D\u0430 Markdown:"
"\u041A\u0440\u0430\u0442\u044A\u043A \u0446\u0438\u0442\u0430\u0442 \u043E\u0442\u043D\u043E\u0441\u043D\u043E \u0444\u0438\u043B\u043E\u0441\u043E\u0444\u0438\u044F\u0442\u0430 \u043D\u0430 Markdown:"
"\u041A\u0440\u0430\u0442\u044A\u043A \u0446\u0438\u0442\u0430\u0442 \u043E\u0442\u043D\u043E\u0441\u043D\u043E \u0444\u0438\u043B\u043E\u0441\u043E\u0444\u0438\u044F\u0442\u0430 \u043D\u0430 Markdown:"
"\u041A\u0440\u0430\u0442\u044A\u043A \u0446\u0438\u0442\u0430\u0442 \u043E\u0442\u043D\u043E\u0441\u043D\u043E \u0444\u0438\u043B\u043E\u0441\u043E\u0444\u0438\u044F\u0442\u0430 \u043D\u0430 Markdown:"
"\u041F\u043E\u0432\u0435\u0447\u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043C\u043E\u0436\u0435 \u0434\u0430 \u043D\u0430\u043C\u0435\u0440\u0438\u0442\u0435 \u043D\u0430 [\u0441\u0430\u0439\u0442\u0430 \u043D\u0430 **Markdown**](http://daringfireball.net/projects/markdown)."
"\u041F\u043E\u0432\u0435\u0447\u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043C\u043E\u0436\u0435 \u0434\u0430 \u043D\u0430\u043C\u0435\u0440\u0438\u0442\u0435 \u043D\u0430 [\u0441\u0430\u0439\u0442\u0430 \u043D\u0430 <strong>Markdown</strong>](http://daringfireball.net/projects/markdown)."
"\u041F\u043E\u0432\u0435\u0447\u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043C\u043E\u0436\u0435 \u0434\u0430 \u043D\u0430\u043C\u0435\u0440\u0438\u0442\u0435 \u043D\u0430 [\u0441\u0430\u0439\u0442\u0430 \u043D\u0430 <strong>Markdown</strong>](http://daringfireball.net/projects/markdown)."
"\u041F\u043E\u0432\u0435\u0447\u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043C\u043E\u0436\u0435 \u0434\u0430 \u043D\u0430\u043C\u0435\u0440\u0438\u0442\u0435 \u043D\u0430 <a href=\"http://daringfireball.net/projects/markdown\">\u0441\u0430\u0439\u0442\u0430 \u043D\u0430 <strong>Markdown</strong></a>."
"## \u041F\u0440\u0435\u0434\u0438\u043C\u0441\u0442\u0432\u0430"
"## \u041F\u0440\u0435\u0434\u0438\u043C\u0441\u0442\u0432\u0430"
"## \u041F\u0440\u0435\u0434\u0438\u043C\u0441\u0442\u0432\u0430"
"## \u041F\u0440\u0435\u0434\u0438\u043C\u0441\u0442\u0432\u0430"
"\u0421\u044A\u0437\u0434\u0430\u0432\u0430\u043D\u0435\u0442\u043E \u043D\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430\u043D\u0438\u0435 \u0432\u044A\u0432 \u0444\u043E\u0440\u043C\u0430\u0442\u0430 Markdown \u0438\u043C\u0430 \u043C\u043D\u043E\u0436\u0435\u0441\u0442\u0432\u043E \u043F\u0440\u0435\u0434\u0438\u043C\u0441\u0442\u0432\u0430."
"\u0421\u044A\u0437\u0434\u0430\u0432\u0430\u043D\u0435\u0442\u043E \u043D\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430\u043D\u0438\u0435 \u0432\u044A\u0432 \u0444\u043E\u0440\u043C\u0430\u0442\u0430 Markdown \u0438\u043C\u0430 \u043C\u043D\u043E\u0436\u0435\u0441\u0442\u0432\u043E \u043F\u0440\u0435\u0434\u0438\u043C\u0441\u0442\u0432\u0430."
"\u0421\u044A\u0437\u0434\u0430\u0432\u0430\u043D\u0435\u0442\u043E \u043D\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430\u043D\u0438\u0435 \u0432\u044A\u0432 \u0444\u043E\u0440\u043C\u0430\u0442\u0430 Markdown \u0438\u043C\u0430 \u043C\u043D\u043E\u0436\u0435\u0441\u0442\u0432\u043E \u043F\u0440\u0435\u0434\u0438\u043C\u0441\u0442\u0432\u0430."
"\u0421\u044A\u0437\u0434\u0430\u0432\u0430\u043D\u0435\u0442\u043E \u043D\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430\u043D\u0438\u0435 \u0432\u044A\u0432 \u0444\u043E\u0440\u043C\u0430\u0442\u0430 Markdown \u0438\u043C\u0430 \u043C\u043D\u043E\u0436\u0435\u0441\u0442\u0432\u043E \u043F\u0440\u0435\u0434\u0438\u043C\u0441\u0442\u0432\u0430."
"\u0415\u0442\u043E \u043D\u044F\u043A\u043E\u0438 \u043E\u0442 \u0442\u044F\u0445:"
"\u0415\u0442\u043E \u043D\u044F\u043A\u043E\u0438 \u043E\u0442 \u0442\u044F\u0445:"
"\u0415\u0442\u043E \u043D\u044F\u043A\u043E\u0438 \u043E\u0442 \u0442\u044F\u0445:"
"\u0415\u0442\u043E \u043D\u044F\u043A\u043E\u0438 \u043E\u0442 \u0442\u044F\u0445:"
"## \u041F\u043E\u0434\u0434\u0440\u044A\u0436\u043A\u0430 \u0432 _Ruby_"
"## \u041F\u043E\u0434\u0434\u0440\u044A\u0436\u043A\u0430 \u0432 _Ruby_"
"## \u041F\u043E\u0434\u0434\u0440\u044A\u0436\u043A\u0430 \u0432 <em>Ruby</em>"
"## \u041F\u043E\u0434\u0434\u0440\u044A\u0436\u043A\u0430 \u0432 <em>Ruby</em>"
"\u0412 **Ruby** \u0438\u043C\u0430 \u043C\u043D\u043E\u0436\u0435\u0441\u0442\u0432\u043E Gem-\u043E\u0432\u0435, \u043A\u043E\u0438\u0442\u043E \u043C\u043E\u0433\u0430\u0442 \u0434\u0430 \u0432\u0438 \u043F\u043E\u043C\u043E\u0433\u043D\u0430\u0442 \u0437\u0430 \u0434\u0430 \u043F\u0440\u0435\u0445\u0432\u044A\u0440\u043B\u044F\u0442\u0435 Markdown-\u0441\u044A\u0434\u044A\u0440\u0436\u0430\u043D\u0438\u0435 \u0432 HTML-\u0444\u043E\u0440\u043C\u0430\u0442.\n\u041A\u043E\u0434\u044A\u0442, \u043A\u043E\u0439\u0442\u043E \u0432\u0438\u0435 \u0441\u044A\u0437\u0434\u0430\u0432\u0430\u0442\u0435, \u0441\u044A\u0449\u043E \u043C\u043E\u0436\u0435 \u0434\u0430 \u0432\u044A\u0440\u0448\u0438 \u0442\u043E\u0432\u0430 \u0434\u043E \u0438\u0437\u0432\u0435\u0441\u0442\u043D\u0430 \u0441\u0442\u0435\u043F\u0435\u043D."
"\u0412 <strong>Ruby</strong> \u0438\u043C\u0430 \u043C\u043D\u043E\u0436\u0435\u0441\u0442\u0432\u043E Gem-\u043E\u0432\u0435, \u043A\u043E\u0438\u0442\u043E \u043C\u043E\u0433\u0430\u0442 \u0434\u0430 \u0432\u0438 \u043F\u043E\u043C\u043E\u0433\u043D\u0430\u0442 \u0437\u0430 \u0434\u0430 \u043F\u0440\u0435\u0445\u0432\u044A\u0440\u043B\u044F\u0442\u0435 Markdown-\u0441\u044A\u0434\u044A\u0440\u0436\u0430\u043D\u0438\u0435 \u0432 HTML-\u0444\u043E\u0440\u043C\u0430\u0442.\n\u041A\u043E\u0434\u044A\u0442, \u043A\u043E\u0439\u0442\u043E \u0432\u0438\u0435 \u0441\u044A\u0437\u0434\u0430\u0432\u0430\u0442\u0435, \u0441\u044A\u0449\u043E \u043C\u043E\u0436\u0435 \u0434\u0430 \u0432\u044A\u0440\u0448\u0438 \u0442\u043E\u0432\u0430 \u0434\u043E \u0438\u0437\u0432\u0435\u0441\u0442\u043D\u0430 \u0441\u0442\u0435\u043F\u0435\u043D."
"\u0412 <strong>Ruby</strong> \u0438\u043C\u0430 \u043C\u043D\u043E\u0436\u0435\u0441\u0442\u0432\u043E Gem-\u043E\u0432\u0435, \u043A\u043E\u0438\u0442\u043E \u043C\u043E\u0433\u0430\u0442 \u0434\u0430 \u0432\u0438 \u043F\u043E\u043C\u043E\u0433\u043D\u0430\u0442 \u0437\u0430 \u0434\u0430 \u043F\u0440\u0435\u0445\u0432\u044A\u0440\u043B\u044F\u0442\u0435 Markdown-\u0441\u044A\u0434\u044A\u0440\u0436\u0430\u043D\u0438\u0435 \u0432 HTML-\u0444\u043E\u0440\u043C\u0430\u0442.\n\u041A\u043E\u0434\u044A\u0442, \u043A\u043E\u0439\u0442\u043E \u0432\u0438\u0435 \u0441\u044A\u0437\u0434\u0430\u0432\u0430\u0442\u0435, \u0441\u044A\u0449\u043E \u043C\u043E\u0436\u0435 \u0434\u0430 \u0432\u044A\u0440\u0448\u0438 \u0442\u043E\u0432\u0430 \u0434\u043E \u0438\u0437\u0432\u0435\u0441\u0442\u043D\u0430 \u0441\u0442\u0435\u043F\u0435\u043D."
"\u0412 <strong>Ruby</strong> \u0438\u043C\u0430 \u043C\u043D\u043E\u0436\u0435\u0441\u0442\u0432\u043E Gem-\u043E\u0432\u0435, \u043A\u043E\u0438\u0442\u043E \u043C\u043E\u0433\u0430\u0442 \u0434\u0430 \u0432\u0438 \u043F\u043E\u043C\u043E\u0433\u043D\u0430\u0442 \u0437\u0430 \u0434\u0430 \u043F\u0440\u0435\u0445\u0432\u044A\u0440\u043B\u044F\u0442\u0435 Markdown-\u0441\u044A\u0434\u044A\u0440\u0436\u0430\u043D\u0438\u0435 \u0432 HTML-\u0444\u043E\u0440\u043C\u0430\u0442.\n\u041A\u043E\u0434\u044A\u0442, \u043A\u043E\u0439\u0442\u043E \u0432\u0438\u0435 \u0441\u044A\u0437\u0434\u0430\u0432\u0430\u0442\u0435, \u0441\u044A\u0449\u043E \u043C\u043E\u0436\u0435 \u0434\u0430 \u0432\u044A\u0440\u0448\u0438 \u0442\u043E\u0432\u0430 \u0434\u043E \u0438\u0437\u0432\u0435\u0441\u0442\u043D\u0430 \u0441\u0442\u0435\u043F\u0435\u043D."
"\u041F\u0440\u0438\u043C\u0435\u0440 \u0437\u0430 \u0443\u043F\u043E\u0442\u0440\u0435\u0431\u0430 \u043D\u0430 \u0432\u0430\u0448\u0438\u044F \u043A\u043E\u0434:"
"\u041F\u0440\u0438\u043C\u0435\u0440 \u0437\u0430 \u0443\u043F\u043E\u0442\u0440\u0435\u0431\u0430 \u043D\u0430 \u0432\u0430\u0448\u0438\u044F \u043A\u043E\u0434:"
"\u041F\u0440\u0438\u043C\u0435\u0440 \u0437\u0430 \u0443\u043F\u043E\u0442\u0440\u0435\u0431\u0430 \u043D\u0430 \u0432\u0430\u0448\u0438\u044F \u043A\u043E\u0434:"
"\u041F\u0440\u0438\u043C\u0435\u0440 \u0437\u0430 \u0443\u043F\u043E\u0442\u0440\u0435\u0431\u0430 \u043D\u0430 \u0432\u0430\u0448\u0438\u044F \u043A\u043E\u0434:"
"\u041B\u0435\u0441\u043D\u043E \u0447\u0435\u0442\u0438\u043C \u0432 _\u0441\u0443\u0440\u043E\u0432_ \u0432\u0438\u0434"
"\u041B\u0435\u0441\u043D\u043E \u0447\u0435\u0442\u0438\u043C \u0432 _\u0441\u0443\u0440\u043E\u0432_ \u0432\u0438\u0434"
"\u041B\u0435\u0441\u043D\u043E \u0447\u0435\u0442\u0438\u043C \u0432 <em>\u0441\u0443\u0440\u043E\u0432</em> \u0432\u0438\u0434"
"\u041B\u0435\u0441\u043D\u043E \u0447\u0435\u0442\u0438\u043C \u0432 <em>\u0441\u0443\u0440\u043E\u0432</em> \u0432\u0438\u0434"
"\u0411\u0435\u0437 &quot;\u0441\u043A\u0440\u0438\u0442\u0438&quot; \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u0430\u0449\u0438 \u0442\u0430\u0433\u043E\u0432\u0435 \u2014 \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u0430\u043D\u0435\u0442\u043E \u0432\u0438 \u043D\u0438\u043A\u043E\u0433\u0430 \u043D\u0435 \u0441\u0435 \u0447\u0443\u043F\u0438"
"\u0411\u0435\u0437 &quot;\u0441\u043A\u0440\u0438\u0442\u0438&quot; \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u0430\u0449\u0438 \u0442\u0430\u0433\u043E\u0432\u0435 \u2014 \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u0430\u043D\u0435\u0442\u043E \u0432\u0438 \u043D\u0438\u043A\u043E\u0433\u0430 \u043D\u0435 \u0441\u0435 \u0447\u0443\u043F\u0438"
"\u0411\u0435\u0437 &quot;\u0441\u043A\u0440\u0438\u0442\u0438&quot; \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u0430\u0449\u0438 \u0442\u0430\u0433\u043E\u0432\u0435 \u2014 \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u0430\u043D\u0435\u0442\u043E \u0432\u0438 \u043D\u0438\u043A\u043E\u0433\u0430 \u043D\u0435 \u0441\u0435 \u0447\u0443\u043F\u0438"
"\u0411\u0435\u0437 &quot;\u0441\u043A\u0440\u0438\u0442\u0438&quot; \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u0430\u0449\u0438 \u0442\u0430\u0433\u043E\u0432\u0435 \u2014 \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u0430\u043D\u0435\u0442\u043E \u0432\u0438 \u043D\u0438\u043A\u043E\u0433\u0430 \u043D\u0435 \u0441\u0435 \u0447\u0443\u043F\u0438"
"\u0421\u043B\u0435\u0434 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430 \u043C\u043E\u0436\u0435 \u0434\u0430 \u0438\u0437\u0433\u043B\u0435\u0436\u0434\u0430 \u043C\u043D\u043E\u0433\u043E \u0434\u043E\u0431\u0440\u0435"
"\u0421\u043B\u0435\u0434 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430 \u043C\u043E\u0436\u0435 \u0434\u0430 \u0438\u0437\u0433\u043B\u0435\u0436\u0434\u0430 \u043C\u043D\u043E\u0433\u043E \u0434\u043E\u0431\u0440\u0435"
"\u0421\u043B\u0435\u0434 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430 \u043C\u043E\u0436\u0435 \u0434\u0430 \u0438\u0437\u0433\u043B\u0435\u0436\u0434\u0430 \u043C\u043D\u043E\u0433\u043E \u0434\u043E\u0431\u0440\u0435"
"\u0421\u043B\u0435\u0434 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430 \u043C\u043E\u0436\u0435 \u0434\u0430 \u0438\u0437\u0433\u043B\u0435\u0436\u0434\u0430 \u043C\u043D\u043E\u0433\u043E \u0434\u043E\u0431\u0440\u0435"
"_\u0424\u0438\u043B\u043E\u0441\u043E\u0444\u0438\u044F_ \u043D\u0430 [Markdown](http://daringfireball.net/projects/markdown/syntax#philosophy)"
"_\u0424\u0438\u043B\u043E\u0441\u043E\u0444\u0438\u044F_ \u043D\u0430 [Markdown](http://daringfireball.net/projects/markdown/syntax#philosophy)"
"<em>\u0424\u0438\u043B\u043E\u0441\u043E\u0444\u0438\u044F</em> \u043D\u0430 [Markdown](http://daringfireball.net/projects/markdown/syntax#philosophy)"
"<em>\u0424\u0438\u043B\u043E\u0441\u043E\u0444\u0438\u044F</em> \u043D\u0430 <a href=\"http://daringfireball.net/projects/markdown/syntax#philosophy\">Markdown</a>"
"Markdown is intended to be as easy-to-read and easy-to-write as is feasible."
"Markdown is intended to be as easy-to-read and easy-to-write as is feasible."
"Markdown is intended to be as easy-to-read and easy-to-write as is feasible."
"Markdown is intended to be as easy-to-read and easy-to-write as is feasible."
"Readability, however, is emphasized above all else. A Markdown-formatted document should be publishable as-is, as plain text, without looking like it\u2019s been marked up with tags or formatting instructions."
"Readability, however, is emphasized above all else. A Markdown-formatted document should be publishable as-is, as plain text, without looking like it\u2019s been marked up with tags or formatting instructions."
"Readability, however, is emphasized above all else. A Markdown-formatted document should be publishable as-is, as plain text, without looking like it\u2019s been marked up with tags or formatting instructions."
"Readability, however, is emphasized above all else. A Markdown-formatted document should be publishable as-is, as plain text, without looking like it\u2019s been marked up with tags or formatting instructions."
F

Failures:

  1) Formatter paragraphs does not render empty paragraphs
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: ""
            got: "<p></p>"
       
       (compared using ==)
     # /tmp/d20111129-16859-yp4h4f/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:49:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) Formatter headers renders tricky ones
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<h2>Leading wsp</h2>"
            got: "<p>## Leading wsp</p>"
       
       (compared using ==)
     # /tmp/d20111129-16859-yp4h4f/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:665:in `block in expect_transformations'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:664:in `each'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:664:in `expect_transformations'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:106:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) Formatter code blocks renders properly a longer example with tabs and Unicode
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<pre><code>// \u041F\u0440\u0438\u043C\u0435\u0440 \u0437\u0430 \u0431\u043B\u043E\u043A \u0441 \u043A\u043E\u0434.\n// \u0412 \u043D\u0435\u0433\u043E \u0432\u0441\u0435\u043A\u0438 \u0440\u0435\u0434, \u0434\u043E\u0440\u0438 \u043F\u0440\u0430\u0437\u043D\u0438\u0442\u0435, \u0435 \u043F\u0440\u0435\u0434\u0448\u0435\u0441\u0442\u0432\u0430\u043D \u043E\u0442 \u0442\u043E\u0447\u043D\u043E \u0447\u0435\u0442\u0438\u0440\u0438 \u0438\u043D\u0442\u0435\u0440\u0432\u0430\u043B\u0430.\ninclude &lt;stdio.h&gt;\n\nint main(int, char**) {\n\t// Whitespace \u0441\u043B\u0435\u0434 \u0447\u0435\u0442\u0438\u0440\u0438\u0442\u0435 \u0437\u0430\u0434\u044A\u043B\u0436\u0438\u0442\u0435\u043B\u043D\u0438 \u0438\u043D\u0442\u0435\u0440\u0432\u0430\u043B\u0430 \u0432 \u043D\u0430\u0447\u0430\u043B\u043E\u0442\u043E, \u0441\u0435 \u0437\u0430\u043F\u0430\u0437\u0432\u0430 \u0432\u0438\u043D\u0430\u0433\u0438.\n\treturn 42;\n}</code></pre>"
            got: "<pre><code>// \u041F\u0440\u0438\u043C\u0435\u0440 \u0437\u0430 \u0431\u043B\u043E\u043A \u0441 \u043A\u043E\u0434.\n// \u0412 \u043D\u0435\u0433\u043E \u0432\u0441\u0435\u043A\u0438 \u0440\u0435\u0434, \u0434\u043E\u0440\u0438 \u043F\u0440\u0430\u0437\u043D\u0438\u0442\u0435, \u0435 \u043F\u0440\u0435\u0434\u0448\u0435\u0441\u0442\u0432\u0430\u043D \u043E\u0442 \u0442\u043E\u0447\u043D\u043E \u0447\u0435\u0442\u0438\u0440\u0438 \u0438\u043D\u0442\u0435\u0440\u0432\u0430\u043B\u0430.\ninclude <stdio.h>\n\nint main(int, char**) {\n\t// Whitespace \u0441\u043B\u0435\u0434 \u0447\u0435\u0442\u0438\u0440\u0438\u0442\u0435 \u0437\u0430\u0434\u044A\u043B\u0436\u0438\u0442\u0435\u043B\u043D\u0438 \u0438\u043D\u0442\u0435\u0440\u0432\u0430\u043B\u0430 \u0432 \u043D\u0430\u0447\u0430\u043B\u043E\u0442\u043E, \u0441\u0435 \u0437\u0430\u043F\u0430\u0437\u0432\u0430 \u0432\u0438\u043D\u0430\u0433\u0438.\n\treturn 42;\n}</code></pre>"
       
       (compared using ==)
       
       Diff:
       @@ -1,6 +1,6 @@
        <pre><code>// Пример за блок с код.
        // В него всеки ред, дори празните, е предшестван от точно четири интервала.
       -include &lt;stdio.h&gt;
       +include <stdio.h>
        
        int main(int, char**) {
        	// Whitespace след четирите задължителни интервала в началото, се запазва винаги.
     # /tmp/d20111129-16859-yp4h4f/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:186:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) Formatter links allows multiple links on a single line
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<p>We have <a href=\"some-url\">a first</a> and <a href=\"another-url\">Second</a>.</p>"
            got: "<p>We have <a href=\"another-url\">a first](some-url) and [Second</a>.</p>"
       
       (compared using ==)
     # /tmp/d20111129-16859-yp4h4f/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:286:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  5) Formatter bold and italic text rendering does not allow parial overlapping
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<p>Some <em>more words **to be</em> emphasized**!</p>"
            got: "<p>Some <em>more words <strong>to be</em> emphasized</strong>!</p>"
       
       (compared using ==)
     # /tmp/d20111129-16859-yp4h4f/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:496:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  6) Formatter special entities escapes them in headers
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<h2>&quot;Black &amp; Decker&quot;!</h2>"
            got: "<p>## &quot;Black &amp; Decker&quot;!</p>"
       
       (compared using ==)
     # /tmp/d20111129-16859-yp4h4f/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:665:in `block in expect_transformations'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:664:in `each'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:664:in `expect_transformations'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:518:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  7) Formatter whitespace ignores leading and trailing whitespace of lines whenever possible
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<h1>Test with a header</h1>"
            got: "<p>#    Test with a header</p>"
       
       (compared using ==)
     # /tmp/d20111129-16859-yp4h4f/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:665:in `block in expect_transformations'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:664:in `each'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:664:in `expect_transformations'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:555:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  8) Formatter mixed, complex input renders properly
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<h1>\u0426\u044F\u043B\u043E\u0441\u0442\u0435\u043D \u043F\u0440\u0438\u043C\u0435\u0440</h1>\n<p>\u0422\u0443\u043A \u0449\u0435 \u0434\u0435\u043C\u043E\u043D\u0441\u0442\u0440\u0438\u0440\u0430\u043C\u0435 \u043D\u0430\u043A\u0440\u0430\u0442\u043A\u043E \u0432\u044A\u0437\u043C\u043E\u0436\u043D\u043E\u0441\u0442\u0438\u0442\u0435 \u043D\u0430 \u043D\u0430\u0448\u0438\u044F \u043F\u0440\u043E\u0441\u0442 Markdown-\u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u0432\u0430\u0442\u0435\u043B.</p>\n\n<h2><em>\u0424\u0438\u043B\u043E\u0441\u043E\u0444\u0438\u044F</em> \u043D\u0430 <a href=\"http://daringfireball.net/projects/markdown/syntax#philosophy\">Markdown</a></h2>\n\n<p>\u041A\u0440\u0430\u0442\u044A\u043A \u0446\u0438\u0442\u0430\u0442 \u043E\u0442\u043D\u043E\u0441\u043D\u043E \u0444\u0438\u043B\u043E\u0441\u043E\u0444\u0438\u044F\u0442\u0430 \u043D\u0430 Markdown:</p>\n<blockquote><p>Markdown is intended to be as easy-to-read and easy-to-write as is feasible.</p>\n\n<p>Readability, however, is emphasized above all else. A Markdown-formatted document should be publishable as-is, as plain text, without looking like it\u2019s been marked up with tags or formatting instructions.</p></blockquote>\n<p>\u041F\u043E\u0432\u0435\u0447\u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043C\u043E\u0436\u0435 \u0434\u0430 \u043D\u0430\u043C\u0435\u0440\u0438\u0442\u0435 \u043D\u0430 <a href=\"http://daringfireball.net/projects/markdown\">\u0441\u0430\u0439\u0442\u0430 \u043D\u0430 <strong>Markdown</strong></a>.</p>\n\n<h2>\u041F\u0440\u0435\u0434\u0438\u043C\u0441\u0442\u0432\u0430</h2>\n\n<p>\u0421\u044A\u0437\u0434\u0430\u0432\u0430\u043D\u0435\u0442\u043E \u043D\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430\u043D\u0438\u0435 \u0432\u044A\u0432 \u0444\u043E\u0440\u043C\u0430\u0442\u0430 Markdown \u0438\u043C\u0430 \u043C\u043D\u043E\u0436\u0435\u0441\u0442\u0432\u043E \u043F\u0440\u0435\u0434\u0438\u043C\u0441\u0442\u0432\u0430.</p>\n\n<p>\u0415\u0442\u043E \u043D\u044F\u043A\u043E\u0438 \u043E\u0442 \u0442\u044F\u0445:</p>\n<ul>\n  <li>\u041B\u0435\u0441\u043D\u043E \u0447\u0435\u0442\u0438\u043C \u0432 <em>\u0441\u0443\u0440\u043E\u0432</em> \u0432\u0438\u0434</li>\n  <li>\u0411\u0435\u0437 &quot;\u0441\u043A\u0440\u0438\u0442\u0438&quot; \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u0430\u0449\u0438 \u0442\u0430\u0433\u043E\u0432\u0435 \u2014 \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u0430\u043D\u0435\u0442\u043E \u0432\u0438 \u043D\u0438\u043A\u043E\u0433\u0430 \u043D\u0435 \u0441\u0435 \u0447\u0443\u043F\u0438</li>\n  <li>\u0421\u043B\u0435\u0434 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430 \u043C\u043E\u0436\u0435 \u0434\u0430 \u0438\u0437\u0433\u043B\u0435\u0436\u0434\u0430 \u043C\u043D\u043E\u0433\u043E \u0434\u043E\u0431\u0440\u0435</li>\n</ul>\n\n<h2>\u041F\u043E\u0434\u0434\u0440\u044A\u0436\u043A\u0430 \u0432 <em>Ruby</em></h2>\n\n<p>\u0412 <strong>Ruby</strong> \u0438\u043C\u0430 \u043C\u043D\u043E\u0436\u0435\u0441\u0442\u0432\u043E Gem-\u043E\u0432\u0435, \u043A\u043E\u0438\u0442\u043E \u043C\u043E\u0433\u0430\u0442 \u0434\u0430 \u0432\u0438 \u043F\u043E\u043C\u043E\u0433\u043D\u0430\u0442 \u0437\u0430 \u0434\u0430 \u043F\u0440\u0435\u0445\u0432\u044A\u0440\u043B\u044F\u0442\u0435 Markdown-\u0441\u044A\u0434\u044A\u0440\u0436\u0430\u043D\u0438\u0435 \u0432 HTML-\u0444\u043E\u0440\u043C\u0430\u0442.\n\u041A\u043E\u0434\u044A\u0442, \u043A\u043E\u0439\u0442\u043E \u0432\u0438\u0435 \u0441\u044A\u0437\u0434\u0430\u0432\u0430\u0442\u0435, \u0441\u044A\u0449\u043E \u043C\u043E\u0436\u0435 \u0434\u0430 \u0432\u044A\u0440\u0448\u0438 \u0442\u043E\u0432\u0430 \u0434\u043E \u0438\u0437\u0432\u0435\u0441\u0442\u043D\u0430 \u0441\u0442\u0435\u043F\u0435\u043D.</p>\n\n<p>\u041F\u0440\u0438\u043C\u0435\u0440 \u0437\u0430 \u0443\u043F\u043E\u0442\u0440\u0435\u0431\u0430 \u043D\u0430 \u0432\u0430\u0448\u0438\u044F \u043A\u043E\u0434:</p>\n\n<pre><code># \u041C\u043D\u043E\u0433\u043E \u043F\u0440\u043E\u0441\u0442\u043E\nformatter = Formatter.new &quot;## My Markdown&quot;\nputs formatter.to_html</code></pre>"
            got: "<p># \u0426\u044F\u043B\u043E\u0441\u0442\u0435\u043D \u043F\u0440\u0438\u043C\u0435\u0440\n\u0422\u0443\u043A \u0449\u0435 \u0434\u0435\u043C\u043E\u043D\u0441\u0442\u0440\u0438\u0440\u0430\u043C\u0435 \u043D\u0430\u043A\u0440\u0430\u0442\u043A\u043E \u0432\u044A\u0437\u043C\u043E\u0436\u043D\u043E\u0441\u0442\u0438\u0442\u0435 \u043D\u0430 \u043D\u0430\u0448\u0438\u044F \u043F\u0440\u043E\u0441\u0442 Markdown-\u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u0432\u0430\u0442\u0435\u043B.</p>\n\n<h2><em>\u0424\u0438\u043B\u043E\u0441\u043E\u0444\u0438\u044F</em> \u043D\u0430 <a href=\"http://daringfireball.net/projects/markdown/syntax#philosophy\">Markdown</a></h2>\n\n<p>\u041A\u0440\u0430\u0442\u044A\u043A \u0446\u0438\u0442\u0430\u0442 \u043E\u0442\u043D\u043E\u0441\u043D\u043E \u0444\u0438\u043B\u043E\u0441\u043E\u0444\u0438\u044F\u0442\u0430 \u043D\u0430 Markdown:</p>\n<blockquote><p>Markdown is intended to be as easy-to-read and easy-to-write as is feasible.</p>\n\n<p>Readability, however, is emphasized above all else. A Markdown-formatted document should be publishable as-is, as plain text, without looking like it\u2019s been marked up with tags or formatting instructions.</p></blockquote>\n<p>\u041F\u043E\u0432\u0435\u0447\u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043C\u043E\u0436\u0435 \u0434\u0430 \u043D\u0430\u043C\u0435\u0440\u0438\u0442\u0435 \u043D\u0430 <a href=\"http://daringfireball.net/projects/markdown\">\u0441\u0430\u0439\u0442\u0430 \u043D\u0430 <strong>Markdown</strong></a>.</p>\n\n<p>## \u041F\u0440\u0435\u0434\u0438\u043C\u0441\u0442\u0432\u0430</p>\n\n<p>\u0421\u044A\u0437\u0434\u0430\u0432\u0430\u043D\u0435\u0442\u043E \u043D\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430\u043D\u0438\u0435 \u0432\u044A\u0432 \u0444\u043E\u0440\u043C\u0430\u0442\u0430 Markdown \u0438\u043C\u0430 \u043C\u043D\u043E\u0436\u0435\u0441\u0442\u0432\u043E \u043F\u0440\u0435\u0434\u0438\u043C\u0441\u0442\u0432\u0430.</p>\n\n<p>\u0415\u0442\u043E \u043D\u044F\u043A\u043E\u0438 \u043E\u0442 \u0442\u044F\u0445:</p>\n<ul>\n  <li>\u041B\u0435\u0441\u043D\u043E \u0447\u0435\u0442\u0438\u043C \u0432 <em>\u0441\u0443\u0440\u043E\u0432</em> \u0432\u0438\u0434</li>\n  <li>\u0411\u0435\u0437 &quot;\u0441\u043A\u0440\u0438\u0442\u0438&quot; \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u0430\u0449\u0438 \u0442\u0430\u0433\u043E\u0432\u0435 \u2014 \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u0430\u043D\u0435\u0442\u043E \u0432\u0438 \u043D\u0438\u043A\u043E\u0433\u0430 \u043D\u0435 \u0441\u0435 \u0447\u0443\u043F\u0438</li>\n  <li>\u0421\u043B\u0435\u0434 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430 \u043C\u043E\u0436\u0435 \u0434\u0430 \u0438\u0437\u0433\u043B\u0435\u0436\u0434\u0430 \u043C\u043D\u043E\u0433\u043E \u0434\u043E\u0431\u0440\u0435</li>\n</ul>\n\n<p>## \u041F\u043E\u0434\u0434\u0440\u044A\u0436\u043A\u0430 \u0432 <em>Ruby</em></p>\n\n<p>\u0412 <strong>Ruby</strong> \u0438\u043C\u0430 \u043C\u043D\u043E\u0436\u0435\u0441\u0442\u0432\u043E Gem-\u043E\u0432\u0435, \u043A\u043E\u0438\u0442\u043E \u043C\u043E\u0433\u0430\u0442 \u0434\u0430 \u0432\u0438 \u043F\u043E\u043C\u043E\u0433\u043D\u0430\u0442 \u0437\u0430 \u0434\u0430 \u043F\u0440\u0435\u0445\u0432\u044A\u0440\u043B\u044F\u0442\u0435 Markdown-\u0441\u044A\u0434\u044A\u0440\u0436\u0430\u043D\u0438\u0435 \u0432 HTML-\u0444\u043E\u0440\u043C\u0430\u0442.\n\u041A\u043E\u0434\u044A\u0442, \u043A\u043E\u0439\u0442\u043E \u0432\u0438\u0435 \u0441\u044A\u0437\u0434\u0430\u0432\u0430\u0442\u0435, \u0441\u044A\u0449\u043E \u043C\u043E\u0436\u0435 \u0434\u0430 \u0432\u044A\u0440\u0448\u0438 \u0442\u043E\u0432\u0430 \u0434\u043E \u0438\u0437\u0432\u0435\u0441\u0442\u043D\u0430 \u0441\u0442\u0435\u043F\u0435\u043D.</p>\n\n<p>\u041F\u0440\u0438\u043C\u0435\u0440 \u0437\u0430 \u0443\u043F\u043E\u0442\u0440\u0435\u0431\u0430 \u043D\u0430 \u0432\u0430\u0448\u0438\u044F \u043A\u043E\u0434:</p>\n\n<pre><code># \u041C\u043D\u043E\u0433\u043E \u043F\u0440\u043E\u0441\u0442\u043E\nformatter = Formatter.new \"## My Markdown\"\nputs formatter.to_html</code></pre>"
       
       (compared using ==)
       
       Diff:
       @@ -1,5 +1,5 @@
       -<h1>Цялостен пример</h1>
       -<p>Тук ще демонстрираме накратко възможностите на нашия прост Markdown-преобразувател.</p>
       +<p># Цялостен пример
       +Тук ще демонстрираме накратко възможностите на нашия прост Markdown-преобразувател.</p>
        
        <h2><em>Философия</em> на <a href="http://daringfireball.net/projects/markdown/syntax#philosophy">Markdown</a></h2>
        
       @@ -9,7 +9,7 @@
        <p>Readability, however, is emphasized above all else. A Markdown-formatted document should be publishable as-is, as plain text, without looking like it’s been marked up with tags or formatting instructions.</p></blockquote>
        <p>Повече информация може да намерите на <a href="http://daringfireball.net/projects/markdown">сайта на <strong>Markdown</strong></a>.</p>
        
       -<h2>Предимства</h2>
       +<p>## Предимства</p>
        
        <p>Създаването на съдържание във формата Markdown има множество предимства.</p>
        
       @@ -20,7 +20,7 @@
          <li>След обработка може да изглежда много добре</li>
        </ul>
        
       -<h2>Поддръжка в <em>Ruby</em></h2>
       +<p>## Поддръжка в <em>Ruby</em></p>
        
        <p>В <strong>Ruby</strong> има множество Gem-ове, които могат да ви помогнат за да прехвърляте Markdown-съдържание в HTML-формат.
        Кодът, който вие създавате, също може да върши това до известна степен.</p>
       @@ -28,6 +28,6 @@
        <p>Пример за употреба на вашия код:</p>
        
        <pre><code># Много просто
       -formatter = Formatter.new &quot;## My Markdown&quot;
       +formatter = Formatter.new "## My Markdown"
        puts formatter.to_html</code></pre>
     # /tmp/d20111129-16859-yp4h4f/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-yp4h4f/spec.rb:655:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.62243 seconds
57 examples, 8 failures

Failed examples:

rspec /tmp/d20111129-16859-yp4h4f/spec.rb:48 # Formatter paragraphs does not render empty paragraphs
rspec /tmp/d20111129-16859-yp4h4f/spec.rb:99 # Formatter headers renders tricky ones
rspec /tmp/d20111129-16859-yp4h4f/spec.rb:163 # Formatter code blocks renders properly a longer example with tabs and Unicode
rspec /tmp/d20111129-16859-yp4h4f/spec.rb:285 # Formatter links allows multiple links on a single line
rspec /tmp/d20111129-16859-yp4h4f/spec.rb:495 # Formatter bold and italic text rendering does not allow parial overlapping
rspec /tmp/d20111129-16859-yp4h4f/spec.rb:515 # Formatter special entities escapes them in headers
rspec /tmp/d20111129-16859-yp4h4f/spec.rb:550 # Formatter whitespace ignores leading and trailing whitespace of lines whenever possible
rspec /tmp/d20111129-16859-yp4h4f/spec.rb:586 # Formatter mixed, complex input renders properly

История (1 версия и 0 коментара)

Николай обнови решението на 23.11.2011 22:52 (преди над 12 години)

+# encoding: UTF-8
+
+class Processor
+ attr_accessor :text
+
+ def initialize(text)
+ @text = text
+ end
+
+ def process()
+ raise "Not implemented!"
+ end
+
+ def process_content content
+ content
+ end
+
+ def process_text content
+ processors = [Entities, Bold, Italic, Link]
+ bold_index, italic_index = content.index("**"), content.index('_')
+ bold_is_after_italic = bold_index && italic_index && bold_index > italic_index
+ processors[1,2] = processors[1,2].reverse if bold_is_after_italic
+ processors.inject(content) {|result, processor| p processor.new(result).process}
+ end
+end
+
+class Entities < Processor
+ def process
+ translation_table = {'&'=>'&amp;', '<'=>'&lt;','>'=>'&gt;','"'=>'&quot;'}
+ text.gsub(/[<>&"]/) {|sign| translation_table[sign]}
+ end
+end
+
+class Link < Processor
+ def process
+ text.gsub(/\[(.+)\]\((.+)\)/) {|match| "<a href=\"#{$2}\">#{$1}</a>"}
+ end
+end
+
+class OrderedList < Processor
+ def process()
+ text.gsub(/^\d+\.\s(.+)$/) {|m| "<ol>\n <li>#{process_text $1.strip}</li>\n</ol>"}
+ .gsub(/<\/ol>\n<ol>\n/, '')
+ end
+end
+
+class UnorderedList < Processor
+ def process()
+ text.gsub(/^\*\s+(.+)$/) {|m| "<ul>\n <li>#{process_text $1.strip}</li>\n</ul>"}
+ .gsub(/<\/ul>\n<ul>\n/, '')
+ end
+end
+
+class Headings < Processor
+ def process
+ text.gsub(/^([#]{1,4})\s+([\w\*_].*)$/) do |m|
+ "<h#{$1.length}>#{process_text $2}</h#{$1.length}>"
+ end
+ end
+end
+
+class Code < Processor
+ def process
+ text.gsub(/(^ {4}.*?$)+/m){|m| "<pre><code>#{$1}</code></pre>"}
+ .gsub(/<pre><code> {4}/, '<pre><code>')
+ .gsub(/<\/code><\/pre>\n<pre><code>/, "\n")
+ .gsub(/<pre><code>(.+?)<\/code><\/pre>/) do |m|
+ "<pre><code>#{process_content $1}</code></pre>"
+ end
+ end
+
+ def process_content content
+ Entities.new(content).process
+ end
+
+end
+
+class Paragrapf < Processor
+ def process
+ pattern = /^((?! |\*\s+|\n|([#]{1,4})\s+([\w\*_].*)|> |\d+\.\s.+).*?)$/
+ text.gsub(pattern) {|m| "<p>#{$1.strip}</p>"}
+ .gsub(/<\/p>\n<p>/,"\n")
+ .gsub(/<p>(.+?)<\/p>/m) {|m| "<p>#{process_text $1.strip}</p>"}
+ end
+end
+
+class Blockquotes < Processor
+ def process
+ text.gsub(/^>\s(.*?)$/) {|m| "<blockquote>#{$1}</blockquote>"}
+ .gsub(/<\/blockquote>\n<blockquote>/, "\n")
+ .gsub(/<blockquote>(.*?)<\/blockquote>/m) do |m|
+ "<blockquote>#{process_content $1}</blockquote>"
+ end
+ end
+
+ def process_content content
+ Paragrapf.new(content).process
+ end
+end
+
+class Italic < Processor
+ def process
+ text.gsub(/_(.+?)_/) {|m| "<em>#{ process_content $1}</em>"}
+ end
+
+ def process_content content
+ if content.count('**') % 2 == 1 || content.count('strong>') % 2 == 1
+ content
+ else
+ Bold.new(content).process
+ end
+ end
+end
+
+class Bold < Processor
+ def process
+ text.gsub(/\*\*(.+?)\*\*/) {|m| "<strong>#{process_content $1}</strong>"}
+ end
+
+ def process_content content
+ if content.count('em>') % 2 == 1|| content.count('_') % 2 == 1
+ content
+ else
+ Italic.new(content).process
+ end
+ end
+end
+
+class Formatter
+ attr_accessor :output, :text
+
+ def initialize(mark_down_text)
+ @text = mark_down_text
+ @processors = [Paragrapf, OrderedList, UnorderedList, Headings, Code, Blockquotes,]
+ end
+
+ def to_html
+ result = processors.inject(text) do |output, processor|
+ processor.new(output).process
+ end
+ result.strip
+ end
+
+ def to_s
+ to_html
+ end
+
+ def inspect
+ @text
+ end
+
+ private
+
+ attr_accessor :processors
+end