Решение на Пета задача от Николай Стоицев

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

Към профила на Николай Стоицев

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 42 успешни тест(а)
  • 15 неуспешни тест(а)

Код

class Formatter
def initialize(input)
@plain = input
@formatted = ''
@html = Html.new
end
def to_html()
if @formatted != ''
@formatted
else
@plain.split("\n\n").map { |x| @formatted += parse_paragraph(x) }
@formatted = @formatted[0..-3]
end
end
def parse_paragraph(text)
case text
when /^(\#{1,4}?) ([^\s].+)$/ then @html.header($1, $2)
when /^\s{4}(.*)/m then @html.codeblock($1)
when /^>\s(.+)/m then @html.blockquote($1)
when /\[([\w ]+)\]\((http[:\w\/.]+)\)/ then @html.link($1, $2)
when /^\*\s(.+)/m then @html.unordered_list($1)
when /^\d\.\s(.+)/m then @html.ordered_list($1)
else @html.paragraph(text)
end
end
def to_s()
to_html
end
def inspect()
@plain
end
end
class Html
def paragraph(content)
'<p>' + Encoder::htmlify(content) + "</p>\n\n"
end
def header(level, text = nil)
level = level.size.to_s
'<h' + level + '>' + Encoder::htmlify(text) + '</h' + level + ">\n\n"
end
def codeblock(content)
content = content.strip.gsub(/^\s{4}/, "")
'<pre><code>' + Encoder::encode(content) + "</code></pre>\n\n"
end
def blockquote(content)
content = content.gsub(/\n>\s/, "\n")
formatter = Formatter.new(content)
'<blockquote>' + formatter.to_html + "</blockquote>\n\n"
end
def link(text, href)
output = '<p><a href="' + Encoder::htmlify(href) + '">'
output << Encoder::htmlify(text) + "</a></p>\n\n"
end
def ordered_list(input)
input = input.gsub(/\n\d\.\s/, "\n")
"<ol>\n" + list_elements(input) + "</ol>\n\n"
end
def unordered_list(input)
input = input.gsub(/\n\*\s/, "\n")
"<ul>\n" + list_elements(input) + "</ul>\n\n"
end
def strong(text)
'<strong>' + Encoder::encode(text) + '</strong>'
end
def em(text)
'<em>' + Encoder::encode(text) + '</em>'
end
private
def list_elements(input)
output = ""
input.split("\n").each { |elm|
output << " <li>" + Encoder::htmlify(elm) + "</li>\n"
}
output
end
end
class Encoder
def self.encode(text)
output = text.strip
output = output.gsub('&', '&amp;')
output = output.gsub('<', '&lt;')
output = output.gsub('>', '&gt;')
output.gsub('"', '&quot;')
end
def self.decorate(output)
output = output.gsub(/\*\*([^\*\*|.]+)\*\*/, '<strong>\1</strong>')
output.gsub(/_([^_|.]+)_/, '<em>\1</em>')
end
def self.htmlify(text)
decorate(encode(text))
end
end

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

....F..F..............FF..FF...F.F.....F.F.F......FFF...F

Failures:

  1) Formatter paragraphs breaks paragraphs with block-level elements
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<p>First line.</p>\n<h1>Header...</h1>\n<p>Third line.</p>\n\n<p>Separate line</p>"
            got: "<h1>Header...</h1>\n\n<p>Separate line</p>"
       
       (compared using ==)
       
       Diff:
       
       @@ -1,6 +1,4 @@
       -<p>First line.</p>
        <h1>Header...</h1>
       -<p>Third line.</p>
        
        <p>Separate line</p>
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:69: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-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:665:in `block in expect_transformations'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:664:in `each'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:664:in `expect_transformations'
     # /tmp/d20111129-16859-1dqt6p0/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 links renders properly Unicode ones
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<p>\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.</p>"
            got: "<p>\u0412\u044A\u043F\u0440\u043E\u0441? [\u0418\u043C\u0430 Google](http://google.com/) \u0437\u0430 \u0442\u0430\u0437\u0438 \u0446\u0435\u043B.</p>"
       
       (compared using ==)
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:282: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 first](some-url) and [Second](another-url).</p>"
       
       (compared using ==)
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/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 links escapes special entities in the link description
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<p>Also testing <a href=\"here\">special &amp; &quot;entities&quot; &lt;b&gt;</a>.</p>"
            got: "<p>Also testing [special &amp; &quot;entities&quot; &lt;b&gt;](here).</p>"
       
       (compared using ==)
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:304: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 links escapes special entities in the link URL
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<p>Or <a href=\"special &amp; &quot;entities&quot; &lt;b&gt;\">what if</a> are in the URL, eh?</p>"
            got: "<p>Or [what if](special &amp; &quot;entities&quot; &lt;b&gt;) are in the URL, eh?</p>"
       
       (compared using ==)
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:309: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 lists does not choke on malformed lists
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<p>1) \u041F\u044A\u0440\u0432\u043E.\n2 \u0412\u0442\u043E\u0440\u043E.\n3.\u0422\u0440\u0435\u0442\u043E</p>\n<ol>\n  <li>\u0427\u0435\u0442\u0432\u044A\u0440\u0442\u043E</li>\n</ol>"
            got: "<ol>\n  <li>\u0427\u0435\u0442\u0432\u044A\u0440\u0442\u043E</li>\n</ol>"
       
       (compared using ==)
       
       Diff:
       @@ -1,6 +1,3 @@
       -<p>1) Първо.
       -2 Второ.
       -3.Трето</p>
        <ol>
          <li>Четвърто</li>
        </ol>
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:394: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 lists allows links in list elements
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<ul>\n  <li>A <a href=\" here \">simple link</a> or there?</li>\n</ul>"
            got: "<ul>\n  <li>A [simple link]( here ) or there?</li>\n</ul>"
       
       (compared using ==)
       
       Diff:
       @@ -1,4 +1,4 @@
        <ul>
       -  <li>A <a href=" here ">simple link</a> or there?</li>
       +  <li>A [simple link]( here ) or there?</li>
        </ul>
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:424: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)>'

  9) Formatter bold and italic text rendering works in links
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<p>Some <a href=\"okay\"><em>more words here</em> <em>to be</em> <strong>emphasized</strong></a>?</p>"
            got: "<p>Some [<em>more words here</em> <em>to be</em> <strong>emphasized</strong>](okay)?</p>"
       
       (compared using ==)
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:464: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)>'

  10) Formatter bold and italic text rendering works in links in list elements
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<ul>\n  <li>Some <a href=\"okay\"><em>more words</em> <em>to be</em> <strong>emphasized</strong></a>!</li>\n</ul>"
            got: "<ul>\n  <li>Some [<em>more words</em> <em>to be</em> <strong>emphasized</strong>](okay)!</li>\n</ul>"
       
       (compared using ==)
       
       Diff:
       @@ -1,4 +1,4 @@
        <ul>
       -  <li>Some <a href="okay"><em>more words</em> <em>to be</em> <strong>emphasized</strong></a>!</li>
       +  <li>Some [<em>more words</em> <em>to be</em> <strong>emphasized</strong>](okay)!</li>
        </ul>
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:487: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)>'

  11) 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-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/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)>'

  12) Formatter whitespace removes excess leading and trailing whitespace
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<p>Some txt</p>"
            got: "<p></p>\n\n<p>Some txt</p>"
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,4 @@
       +<p></p>
       +
        <p>Some txt</p>
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:665:in `block in expect_transformations'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:664:in `each'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:664:in `expect_transformations'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:547: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)>'

  13) 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-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:665:in `block in expect_transformations'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:664:in `each'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:664:in `expect_transformations'
     # /tmp/d20111129-16859-1dqt6p0/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)>'

  14) Formatter whitespace does not touch trailing whitespace in code blocks
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<pre><code>Simple code blk  </code></pre>"
            got: "<pre><code>Simple code blk</code></pre>"
       
       (compared using ==)
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:665:in `block in expect_transformations'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:664:in `each'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:664:in `expect_transformations'
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:563: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)>'

  15) 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: "<h1>\u0426\u044F\u043B\u043E\u0441\u0442\u0435\u043D \u043F\u0440\u0438\u043C\u0435\u0440</h1>\n\n<h2><em>\u0424\u0438\u043B\u043E\u0441\u043E\u0444\u0438\u044F</em> \u043D\u0430 [Markdown](http://daringfireball.net/projects/markdown/syntax#philosophy)</h2>\n\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.\n\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).</p></blockquote>\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<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>"
       
       (compared using ==)
       
       Diff:
       
       
       
       
       @@ -1,19 +1,16 @@
        <h1>Цялостен пример</h1>
       -<p>Тук ще демонстрираме накратко възможностите на нашия прост Markdown-преобразувател.</p>
        
       -<h2><em>Философия</em> на <a href="http://daringfireball.net/projects/markdown/syntax#philosophy">Markdown</a></h2>
       +<h2><em>Философия</em> на [Markdown](http://daringfireball.net/projects/markdown/syntax#philosophy)</h2>
        
       -<p>Кратък цитат относно философията на Markdown:</p>
        <blockquote><p>Markdown is intended to be as easy-to-read and easy-to-write as is feasible.</p>
        
       -<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>
       +<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.
       +Повече информация може да намерите на [сайта на <strong>Markdown</strong>](http://daringfireball.net/projects/markdown).</p></blockquote>
        
        <h2>Предимства</h2>
        
        <p>Създаването на съдържание във формата Markdown има множество предимства.</p>
        
       -<p>Ето някои от тях:</p>
        <ul>
          <li>Лесно четим в <em>суров</em> вид</li>
          <li>Без &quot;скрити&quot; форматиращи тагове — форматирането ви никога не се чупи</li>
     # /tmp/d20111129-16859-1dqt6p0/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1dqt6p0/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.65241 seconds
57 examples, 15 failures

Failed examples:

rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:52 # Formatter paragraphs breaks paragraphs with block-level elements
rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:99 # Formatter headers renders tricky ones
rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:281 # Formatter links renders properly Unicode ones
rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:285 # Formatter links allows multiple links on a single line
rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:303 # Formatter links escapes special entities in the link description
rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:308 # Formatter links escapes special entities in the link URL
rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:377 # Formatter lists does not choke on malformed lists
rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:413 # Formatter lists allows links in list elements
rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:463 # Formatter bold and italic text rendering works in links
rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:479 # Formatter bold and italic text rendering works in links in list elements
rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:495 # Formatter bold and italic text rendering does not allow parial overlapping
rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:541 # Formatter whitespace removes excess leading and trailing whitespace
rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:550 # Formatter whitespace ignores leading and trailing whitespace of lines whenever possible
rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:558 # Formatter whitespace does not touch trailing whitespace in code blocks
rspec /tmp/d20111129-16859-1dqt6p0/spec.rb:586 # Formatter mixed, complex input renders properly

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

Николай обнови решението на 21.11.2011 02:41 (преди около 13 години)

+class Formatter
+ def initialize(input)
+ @plain = input
+ @formatted = ''
+ @html = Html.new
+ end
+
+ def to_html()
+ if @formatted != ''
+ @formatted
+ else
+ @plain.split("\n\n").map { |x| @formatted += parse_paragraph(x) }
+ @formatted = @formatted[0..-3]
+ end
+ end
+
+ def parse_paragraph(text)
+ case text
+ when /^(\#{1,4}?) ([^\s].+)$/ then @html.header($1, $2)
+ when /^\s{4}(.*)/m then @html.codeblock($1)
+ when /^>\s(.+)/m then @html.blockquote($1)
+ when /\[([\w ]+)\]\((http[:\w\/.]+)\)/ then @html.link($1, $2)
+ when /^\*\s(.+)/m then @html.unordered_list($1)
+ when /^\d\.\s(.+)/m then @html.ordered_list($1)
+ else @html.paragraph(text)
+ end
+ end
+
+ def to_s()
+ to_html
+ end
+
+ def inspect()
+ @plain
+ end
+
+end
+
+class Html
+ def paragraph(content)
+ '<p>' + Encoder::htmlify(content) + "</p>\n\n"
+ end
+
+ def header(level, text = nil)
+ level = level.size.to_s
+ '<h' + level + '>' + Encoder::htmlify(text) + '</h' + level + ">\n\n"
+ end
+
+ def codeblock(content)
+ content = content.strip.gsub(/^\s{4}/, "")
+ '<pre><code>' + Encoder::encode(content) + "</code></pre>\n\n"
+ end
+
+ def blockquote(content)
+ content = content.gsub(/\n>\s/, "\n")
+ formatter = Formatter.new(content)
+ '<blockquote>' + formatter.to_html + "</blockquote>\n\n"
+ end
+
+ def link(text, href)
+ output = '<p><a href="' + Encoder::htmlify(href) + '">'
+ output << Encoder::htmlify(text) + "</a></p>\n\n"
+ end
+
+ def ordered_list(input)
+ input = input.gsub(/\n\d\.\s/, "\n")
+ "<ol>\n" + list_elements(input) + "</ol>\n\n"
+ end
+
+ def unordered_list(input)
+ input = input.gsub(/\n\*\s/, "\n")
+ "<ul>\n" + list_elements(input) + "</ul>\n\n"
+ end
+
+ def strong(text)
+ '<strong>' + Encoder::encode(text) + '</strong>'
+ end
+
+ def em(text)
+ '<em>' + Encoder::encode(text) + '</em>'
+ end
+
+ private
+
+ def list_elements(input)
+ output = ""
+ input.split("\n").each { |elm|
+ output << " <li>" + Encoder::htmlify(elm) + "</li>\n"
+ }
+ output
+ end
+
+end
+
+class Encoder
+ def self.encode(text)
+ output = text.strip
+ output = output.gsub('&', '&amp;')
+ output = output.gsub('<', '&lt;')
+ output = output.gsub('>', '&gt;')
+ output.gsub('"', '&quot;')
+ end
+
+ def self.decorate(output)
+ output = output.gsub(/\*\*([^\*\*|.]+)\*\*/, '<strong>\1</strong>')
+ output.gsub(/_([^_|.]+)_/, '<em>\1</em>')
+ end
+
+ def self.htmlify(text)
+ decorate(encode(text))
+ end
+
+end