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

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

Към профила на Дарина Нейчева

Резултати

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

Код

# !/usr/local/rvm/rubies/ruby-1.9.2-p290/bin/ruby
# encoding: UTF-8
class Formatter
attr_reader :unformatted, :formatted
def initialize(string_to_convert)
@unformatted = string_to_convert
@formatted = string_to_convert
end
def inspect
@unformatted
end
def to_html
format2 = InlineFormatter.new(@formatted)
@formatted = format2.to_format
format1 = ParagraphFormatter.new(@formatted)
@formatted = format1.to_format
@formatted
end
def to_s
to_html
end
end
class ParagraphFormatter
attr_reader :formatted
def initialize(unformatted)
@formatted = unformatted
end
def to_format
paragraphs
headers12
code
links
unordered_list
ordered_list
blockquote
@formatted
end
def paragraphs
@formatted.each_line do |line|
/(^#####+\s|^#*\w|^[^*>#])\w.*/u.match(line) do |match|
@formatted = @formatted.sub(match.to_s, "<p>#{match}</p>")
end
/(^\#{1,}|^\d[^\.].*)$/.match(line) do |match|
@formatted = @formatted.sub(match.to_s, "<p>#{match}</p>")
end
end
@formatted = @formatted.chomp
end
def headers12
@formatted.each_line do |line|
/\A#\s{1,}.*/u.match(line) do |match|
@formatted = @formatted.sub(match.to_s, "#{match.to_s.sub("# ", "<h1>")}</h1>")
end
/\A##\s{1,}.*/u.match(line) do |match|
@formatted = @formatted.sub(match.to_s, "#{match.to_s.sub("## ", "<h2>")}</h2>")
end
end
headers34
end
def headers34
@formatted.each_line do |line|
/\A###\s{1,}.*/u.match(line) do |match|
@formatted = @formatted.sub(match.to_s, "#{match.to_s.sub("### ", "<h3>")}</h3>")
end
/\A####\s{1,}.*/u.match(line) do |match|
@formatted = @formatted.sub(match.to_s, "#{match.to_s.sub("#### ", "<h4>")}</h4>")
end
end
end
def code
codes = @formatted.scan(/^\s{4}.*/m)
codes.each do |c|
@formatted = @formatted.sub(c, "<pre><code>#{c.slice(4..-1).chomp}</code></pre>")
@formatted = @formatted.gsub(/\n\s*?\n\s*/, "\n\n")
end
end
def links
links = @formatted.scan(/\[.*\]\(.*\)/u)
links.each do |link|
text = /\[(?<text>.*)\]/u.match(link)[:text]
href = /\((?<href>.*)\)/u.match(link)[:href]
@formatted = @formatted.sub(link, "<a href=\"#{href}\">#{text}</a>")
end
end
def unordered_list
list = @formatted.scan(/^\*\s.*$/mu)
list.each { |ul| @formatted = @formatted.sub(ul, "<ul>\n#{ul}\n</ul>") }
unordered = @formatted.scan(/^\*\s.*/u)
unordered.each do |ul|
@formatted = @formatted.sub(ul, " <li>#{ul.slice(2..-1)}</li>")
end
end
def ordered_list
list = @formatted.scan(/^\d\.\s.*$/mu)
list.each { |ol| @formatted = @formatted.sub(ol, "<ol>\n#{ol}\n</ol>") }
ordered = @formatted.scan(/^\d\.\s.*/u)
ordered.each do |ol|
@formatted = @formatted.sub(ol, " <li>#{ol.slice(3..-1)}</li>")
end
end
def blockquote
quotes = @formatted.scan(/^>\s.*$/mu)
quotes.each do |q|
@formatted = @formatted.sub(q, "<blockquote><p>#{q.slice(2..-1)}</p></blockquote>")
end
end
end
class InlineFormatter
attr_reader :formatted
def initialize(unformatted)
@formatted = unformatted
end
def to_format
special_symbols
italic
strong
newlines
@formatted
end
def special_symbols
@formatted = @formatted.gsub(/\&/, "&amp;")
less = @formatted.scan(/\<[^ph\/]/)
less.each { |lt| @formatted = @formatted.sub(lt, "&lt;" << lt.slice(1..-1))}
great = @formatted.scan(/[^p1-4]\>/)
great.each { |gt| @formatted = @formatted.sub(gt, gt.slice(0..-2) << "&gt;")}
@formatted = @formatted.gsub(/\"/, "&quot;")
end
def italic
@formatted.lines do |line|
italic = @formatted.scan(/_.*?\_/u)
italic.each do |em|
@formatted = @formatted.sub(em, "<em>#{em.slice(1..-2)}</em>")
end
end
end
def strong
bold = @formatted.scan(/\*\*.*?\*\*/u)
bold.each do |strong|
@formatted = @formatted.sub(strong, "<strong>#{strong.slice(2..-3)}</strong>")
end
end
def newlines
@formatted = @formatted.gsub(/\A(\s+\n+\s+|\n*)/, "")
@formatted = @formatted.gsub(/\n{2}$/, "")
whitespaces = @formatted.scan(/\A\s{1,3}[^\s].*/)
whitespaces.each do |space|
@formatted = @formatted.sub(space, "#{space.strip}")
end
@formatted.lines { |line| @formatted = @formatted.gsub(/\s{3}$/, "") }
end
end

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

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

Failures:

  1) Formatter paragraphs renders multiline paragraps
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<p>First line.\nSecond line.\nThird line.</p>\n\n<p>Last line, of course.</p>"
            got: "<p>First line.</p>\n<p>Second line.</p>\n<p>Third line.</p>\n\n<p>Last line, of course.</p>"
       
       (compared using ==)
       
       Diff:
       @@ -1,6 +1,6 @@
       -<p>First line.
       -Second line.
       -Third line.</p>
       +<p>First line.</p>
       +<p>Second line.</p>
       +<p>Third line.</p>
        
        <p>Last line, of course.</p>
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:45: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>Trailing wsp</h2>"
            got: "<h2>Trailing wsp  </h2>"
       
       (compared using ==)
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:665:in `block in expect_transformations'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:664:in `each'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:664:in `expect_transformations'
     # /tmp/d20111129-16859-1qf13cw/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 multiple ones
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<pre><code>First code-block</code></pre>\n\n<pre><code>Second block of code</code></pre>"
            got: "<pre><code>First code-block\n\nSecond block of code</code></pre>"
       
       (compared using ==)
       
       Diff:
       
       @@ -1,4 +1,4 @@
       -<pre><code>First code-block</code></pre>
       +<pre><code>First code-block
        
       -<pre><code>Second block of code</code></pre>
       +Second block of code</code></pre>
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:156: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 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.\n    include &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>"
       
       (compared using ==)
       
       Diff:
       
       @@ -1,9 +1,9 @@
        <pre><code>// Пример за блок с код.
       -// В него всеки ред, дори празните, е предшестван от точно четири интервала.
       -include &lt;stdio.h&gt;
       +    // В него всеки ред, дори празните, е предшестван от точно четири интервала.
       +    include &lt;stdio.h&gt;
        
        int main(int, char**) {
       -	// Whitespace след четирите задължителни интервала в началото, се запазва винаги.
       -	return 42;
       -}</code></pre>
       +    	// Whitespace след четирите задължителни интервала в началото, се запазва винаги.
       +    	return 42;
       +    }</code></pre>
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/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)>'

  5) Formatter code blocks renders properly with mixed content
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<h1>This is a header</h1>\n\n<p>Some parahraphs here</p>\n\n<pre><code>Some clean code\nWhich is also beautiful\nAnd maybe also compiles!</code></pre>\n\n<p>More paragraphs there?</p>"
            got: "<h1>This is a header</h1>\n\n<p>Some parahraphs here</p>\n<pre><code> Some clean code\n    Which is also beautiful\n    And maybe also compiles!\n\n<p>More paragraphs there?</p></code></pre>"
       
       (compared using ==)
       
       Diff:
       
       @@ -1,10 +1,9 @@
        <h1>This is a header</h1>
        
        <p>Some parahraphs here</p>
       +<pre><code> Some clean code
       +    Which is also beautiful
       +    And maybe also compiles!
        
       -<pre><code>Some clean code
       -Which is also beautiful
       -And maybe also compiles!</code></pre>
       -
       -<p>More paragraphs there?</p>
       +<p>More paragraphs there?</p></code></pre>
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:214: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 blockquotes renders multiline ones
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<blockquote><p>First line.\nSecond line.\nThird line.</p></blockquote>"
            got: "<blockquote><p>First line.\n<p>&gt; Second line.</p>\n<p>&gt; Third line.</p></p></blockquote>"
       
       (compared using ==)
       
       Diff:
       @@ -1,4 +1,4 @@
        <blockquote><p>First line.
       -Second line.
       -Third line.</p></blockquote>
       +<p>&gt; Second line.</p>
       +<p>&gt; Third line.</p></p></blockquote>
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:236: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 blockquotes renders multiple ones
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<blockquote><p>First quote.</p></blockquote>\n\n<blockquote><p>Second quote.</p></blockquote>"
            got: "<blockquote><p>First quote.\n\n<p>&gt; Second quote.</p></p></blockquote>"
       
       (compared using ==)
       
       Diff:
       
       @@ -1,4 +1,4 @@
       -<blockquote><p>First quote.</p></blockquote>
       +<blockquote><p>First quote.
        
       -<blockquote><p>Second quote.</p></blockquote>
       +<p>&gt; Second quote.</p></p></blockquote>
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:252: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 blockquotes renders multiline ones with multiple paragraphs
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<blockquote><p>First quote.</p>\n\n<p>Second quote.</p></blockquote>"
            got: "<blockquote><p>First quote.\n<p>&gt; </p>\n<p>&gt; Second quote.</p></p></blockquote>"
       
       (compared using ==)
       
       Diff:
       @@ -1,4 +1,4 @@
       -<blockquote><p>First quote.</p>
       -
       -<p>Second quote.</p></blockquote>
       +<blockquote><p>First quote.
       +<p>&gt; </p>
       +<p>&gt; Second quote.</p></p></blockquote>
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:268: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 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: "\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."
       
       (compared using ==)
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/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)>'

  10) 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=\"some-url) and [Second](another-url\">a first](some-url) and [Second</a>.</p>"
       
       (compared using ==)
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/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)>'

  11) Formatter links does not render them in code blocks
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<pre><code>This one [is a link](in-a-code-block) - keep as-is.</code></pre>"
            got: "<pre><code>This one <a href=\"in-a-code-block\">is a link</a> - keep as-is.</code></pre>"
       
       (compared using ==)
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:299: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 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: "<p>1) \u041F\u044A\u0440\u0432\u043E.</p>\n<p>2 \u0412\u0442\u043E\u0440\u043E.</p>\n3.\u0422\u0440\u0435\u0442\u043E\n<ol>\n  <li>\u0427\u0435\u0442\u0432\u044A\u0440\u0442\u043E</li>\n</ol>"
       
       (compared using ==)
       
       Diff:
       @@ -1,6 +1,6 @@
       -<p>1) Първо.
       -2 Второ.
       -3.Трето</p>
       +<p>1) Първо.</p>
       +<p>2 Второ.</p>
       +3.Трето
        <ol>
          <li>Четвърто</li>
        </ol>
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/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)>'

  13) Formatter bold and italic text rendering does not render in code blocks
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<pre><code>Some _more words_ _to be_ **emphasized**?</code></pre>"
            got: "<pre><code>Some <em>more words</em> <em>to be</em> <strong>emphasized</strong>?</code></pre>"
       
       (compared using ==)
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:459: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 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-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/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)>'

  15) Formatter whitespace ignores leading and trailing whitespace of lines whenever possible
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<p>A line here</p>"
            got: "A line here"
       
       (compared using ==)
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:665:in `block in expect_transformations'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:664:in `each'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:664:in `expect_transformations'
     # /tmp/d20111129-16859-1qf13cw/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)>'

  16) Formatter whitespace does not touch trailing whitespace in code blocks
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<pre><code>First  \n  Second  </code></pre>"
            got: "<pre><code>First  \n      Second  </code></pre>"
       
       (compared using ==)
       
       Diff:
       @@ -1,3 +1,3 @@
        <pre><code>First  
       -  Second  </code></pre>
       +      Second  </code></pre>
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:665:in `block in expect_transformations'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:664:in `each'
     # /tmp/d20111129-16859-1qf13cw/spec.rb:664:in `expect_transformations'
     # /tmp/d20111129-16859-1qf13cw/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)>'

  17) 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\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.\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\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:\n<p><p>&gt; </p>Markdown is intended to be as easy-to-read and easy-to-write as is feasible.</p>\n&gt; \n<p>&gt; 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>\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 <a href=\"http://daringfireball.net/projects/markdown\">\u0441\u0430\u0439\u0442\u0430 \u043D\u0430 <strong>Markdown</strong></a>.\n\n<h2>\u041F\u0440\u0435\u0434\u0438\u043C\u0441\u0442\u0432\u0430</h2>\n\n\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.\n\n\u0415\u0442\u043E \u043D\u044F\u043A\u043E\u0438 \u043E\u0442 \u0442\u044F\u0445:\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\n<h2>\u041F\u043E\u0434\u0434\u0440\u044A\u0436\u043A\u0430 \u0432 <em>Ruby</em></h2>\n\n\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.\n\n\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:\n<pre><code> # \u041C\u043D\u043E\u0433\u043E \u043F\u0440\u043E\u0441\u0442\u043E\n    formatter = Formatter.new &quot;## My Markdown&quot;\n    puts formatter.to_html</code></pre>\n</ul>"
       
       (compared using ==)
       
       Diff:
       
       
       
       
       
       
       
       @@ -1,33 +1,32 @@
        <h1>Цялостен пример</h1>
       -<p>Тук ще демонстрираме накратко възможностите на нашия прост Markdown-преобразувател.</p>
       +Тук ще демонстрираме накратко възможностите на нашия прост Markdown-преобразувател.
        
        <h2><em>Философия</em> на <a href="http://daringfireball.net/projects/markdown/syntax#philosophy">Markdown</a></h2>
        
       -<p>Кратък цитат относно философията на Markdown:</p>
       -<blockquote><p>Markdown is intended to be as easy-to-read and easy-to-write as is feasible.</p>
       +Кратък цитат относно философията на Markdown:
       +<p><p>&gt; </p>Markdown is intended to be as easy-to-read and easy-to-write as is feasible.</p>
       +&gt; 
       +<p>&gt; 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>
       +Повече информация може да намерите на <a href="http://daringfireball.net/projects/markdown">сайта на <strong>Markdown</strong></a>.
        
       -<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>Създаването на съдържание във формата Markdown има множество предимства.</p>
       +Създаването на съдържание във формата Markdown има множество предимства.
        
       -<p>Ето някои от тях:</p>
       +Ето някои от тях:
        <ul>
          <li>Лесно четим в <em>суров</em> вид</li>
          <li>Без &quot;скрити&quot; форматиращи тагове — форматирането ви никога не се чупи</li>
          <li>След обработка може да изглежда много добре</li>
       -</ul>
        
        <h2>Поддръжка в <em>Ruby</em></h2>
        
       -<p>В <strong>Ruby</strong> има множество Gem-ове, които могат да ви помогнат за да прехвърляте Markdown-съдържание в HTML-формат.
       -Кодът, който вие създавате, също може да върши това до известна степен.</p>
       +В <strong>Ruby</strong> има множество Gem-ове, които могат да ви помогнат за да прехвърляте Markdown-съдържание в HTML-формат.
       +Кодът, който вие създавате, също може да върши това до известна степен.
        
       -<p>Пример за употреба на вашия код:</p>
       -
       -<pre><code># Много просто
       -formatter = Formatter.new &quot;## My Markdown&quot;
       -puts formatter.to_html</code></pre>
       +Пример за употреба на вашия код:
       +<pre><code> # Много просто
       +    formatter = Formatter.new &quot;## My Markdown&quot;
       +    puts formatter.to_html</code></pre>
       +</ul>
     # /tmp/d20111129-16859-1qf13cw/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-1qf13cw/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.62888 seconds
57 examples, 17 failures

Failed examples:

rspec /tmp/d20111129-16859-1qf13cw/spec.rb:28 # Formatter paragraphs renders multiline paragraps
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:99 # Formatter headers renders tricky ones
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:143 # Formatter code blocks renders multiple ones
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:163 # Formatter code blocks renders properly a longer example with tabs and Unicode
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:189 # Formatter code blocks renders properly with mixed content
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:223 # Formatter blockquotes renders multiline ones
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:239 # Formatter blockquotes renders multiple ones
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:255 # Formatter blockquotes renders multiline ones with multiple paragraphs
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:281 # Formatter links renders properly Unicode ones
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:285 # Formatter links allows multiple links on a single line
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:298 # Formatter links does not render them in code blocks
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:377 # Formatter lists does not choke on malformed lists
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:458 # Formatter bold and italic text rendering does not render in code blocks
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:495 # Formatter bold and italic text rendering does not allow parial overlapping
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:550 # Formatter whitespace ignores leading and trailing whitespace of lines whenever possible
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:558 # Formatter whitespace does not touch trailing whitespace in code blocks
rspec /tmp/d20111129-16859-1qf13cw/spec.rb:586 # Formatter mixed, complex input renders properly

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

Дарина обнови решението на 23.11.2011 17:28 (преди над 12 години)

+# !/usr/local/rvm/rubies/ruby-1.9.2-p290/bin/ruby
+# encoding: UTF-8
+
+class Formatter
+
+ attr_reader :unformatted, :formatted
+ def initialize(string_to_convert)
+ @unformatted = string_to_convert
+ @formatted = string_to_convert
+ end
+
+ def inspect
+ @unformatted
+ end
+
+ def to_html
+ format2 = InlineFormatter.new(@formatted)
+ @formatted = format2.to_format
+ format1 = ParagraphFormatter.new(@formatted)
+ @formatted = format1.to_format
+ @formatted
+ end
+
+ def to_s
+ to_html
+ end
+
+end
+
+class ParagraphFormatter
+
+ attr_reader :formatted
+
+ def initialize(unformatted)
+ @formatted = unformatted
+ end
+
+ def to_format
+ paragraphs
+ headers12
+ code
+ links
+ unordered_list
+ ordered_list
+ blockquote
+ @formatted
+ end
+
+ def paragraphs
+ @formatted.each_line do |line|
+ /(^#####+\s|^#*\w|^[^*>#])\w.*/u.match(line) do |match|
+ @formatted = @formatted.sub(match.to_s, "<p>#{match}</p>")
+ end
+ /(^\#{1,}|^\d[^\.].*)$/.match(line) do |match|
+ @formatted = @formatted.sub(match.to_s, "<p>#{match}</p>")
+ end
+ end
+ @formatted = @formatted.chomp
+ end
+
+ def headers12
+ @formatted.each_line do |line|
+ /\A#\s{1,}.*/u.match(line) do |match|
+ @formatted = @formatted.sub(match.to_s, "#{match.to_s.sub("# ", "<h1>")}</h1>")
+ end
+ /\A##\s{1,}.*/u.match(line) do |match|
+ @formatted = @formatted.sub(match.to_s, "#{match.to_s.sub("## ", "<h2>")}</h2>")
+ end
+ end
+ headers34
+ end
+
+ def headers34
+ @formatted.each_line do |line|
+ /\A###\s{1,}.*/u.match(line) do |match|
+ @formatted = @formatted.sub(match.to_s, "#{match.to_s.sub("### ", "<h3>")}</h3>")
+ end
+ /\A####\s{1,}.*/u.match(line) do |match|
+ @formatted = @formatted.sub(match.to_s, "#{match.to_s.sub("#### ", "<h4>")}</h4>")
+ end
+ end
+ end
+
+ def code
+ codes = @formatted.scan(/^\s{4}.*/m)
+ codes.each do |c|
+ @formatted = @formatted.sub(c, "<pre><code>#{c.slice(4..-1).chomp}</code></pre>")
+ @formatted = @formatted.gsub(/\n\s*?\n\s*/, "\n\n")
+ end
+ end
+
+ def links
+ links = @formatted.scan(/\[.*\]\(.*\)/u)
+ links.each do |link|
+ text = /\[(?<text>.*)\]/u.match(link)[:text]
+ href = /\((?<href>.*)\)/u.match(link)[:href]
+ @formatted = @formatted.sub(link, "<a href=\"#{href}\">#{text}</a>")
+ end
+ end
+
+ def unordered_list
+ list = @formatted.scan(/^\*\s.*$/mu)
+ list.each { |ul| @formatted = @formatted.sub(ul, "<ul>\n#{ul}\n</ul>") }
+ unordered = @formatted.scan(/^\*\s.*/u)
+ unordered.each do |ul|
+ @formatted = @formatted.sub(ul, " <li>#{ul.slice(2..-1)}</li>")
+ end
+ end
+
+ def ordered_list
+ list = @formatted.scan(/^\d\.\s.*$/mu)
+ list.each { |ol| @formatted = @formatted.sub(ol, "<ol>\n#{ol}\n</ol>") }
+ ordered = @formatted.scan(/^\d\.\s.*/u)
+ ordered.each do |ol|
+ @formatted = @formatted.sub(ol, " <li>#{ol.slice(3..-1)}</li>")
+ end
+ end
+
+ def blockquote
+ quotes = @formatted.scan(/^>\s.*$/mu)
+ quotes.each do |q|
+ @formatted = @formatted.sub(q, "<blockquote><p>#{q.slice(2..-1)}</p></blockquote>")
+ end
+ end
+
+end
+
+
+class InlineFormatter
+
+ attr_reader :formatted
+
+ def initialize(unformatted)
+ @formatted = unformatted
+ end
+
+ def to_format
+ special_symbols
+ italic
+ strong
+ newlines
+ @formatted
+ end
+
+ def special_symbols
+ @formatted = @formatted.gsub(/\&/, "&amp;")
+ less = @formatted.scan(/\<[^ph\/]/)
+ less.each { |lt| @formatted = @formatted.sub(lt, "&lt;" << lt.slice(1..-1))}
+ great = @formatted.scan(/[^p1-4]\>/)
+ great.each { |gt| @formatted = @formatted.sub(gt, gt.slice(0..-2) << "&gt;")}
+ @formatted = @formatted.gsub(/\"/, "&quot;")
+ end
+
+ def italic
+ @formatted.lines do |line|
+ italic = @formatted.scan(/_.*?\_/u)
+ italic.each do |em|
+ @formatted = @formatted.sub(em, "<em>#{em.slice(1..-2)}</em>")
+ end
+ end
+ end
+
+ def strong
+ bold = @formatted.scan(/\*\*.*?\*\*/u)
+ bold.each do |strong|
+ @formatted = @formatted.sub(strong, "<strong>#{strong.slice(2..-3)}</strong>")
+ end
+ end
+
+ def newlines
+ @formatted = @formatted.gsub(/\A(\s+\n+\s+|\n*)/, "")
+ @formatted = @formatted.gsub(/\n{2}$/, "")
+ whitespaces = @formatted.scan(/\A\s{1,3}[^\s].*/)
+ whitespaces.each do |space|
+ @formatted = @formatted.sub(space, "#{space.strip}")
+ end
+ @formatted.lines { |line| @formatted = @formatted.gsub(/\s{3}$/, "") }
+ end
+
+
+end