Решение на Пета задача от Славена Василева

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

Към профила на Славена Василева

Резултати

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

Код

module Patterns
def self.block
pattern = ''
pattern << code + '|'
pattern << unordered_list + '|'
pattern << ordered_list + '|'
pattern << blockquote + '|'
pattern << header
Regexp.new(pattern)
end
@private
def self.code
'(^ {4}.*\n?)+'
end
def self.unordered_list
'(^[ \t\r\f]*\* .*\n?)+'
end
def self.ordered_list
'(^[ \t\r\f]*\d+\. .*\n?)+'
end
def self.blockquote
'(^[ \t\r\f]*\> .*\n?)+'
end
def self.header
'^[ \t\r\f]*#{1,4} .*\S.*'
end
end
class BlocksFormatter
def initialize(markdown_text)
@markdown_text = markdown_text
end
def to_blocks
format_text(@markdown_text).strip
end
def format_text(text)
block_element = text.match(Patterns.block)
if block_element
format_paragraphs(block_element.pre_match) +
format_block(block_element[0]) +
format_text(block_element.post_match)
else
format_paragraphs(text)
end
end
def format_block(text)
case text
when /^\s* {4}/ then format_pre(text)
when /^\s*> / then format_quote(text)
when /^\s*\* / then format_unordered(text)
when /^\s*\d+\. / then format_ordered(text)
when /^\s*(\#{1,4}) / then format_header(text, $1.size)
end
end
def format_paragraphs(text)
text.gsub(/(^(.*)\S(.*)\n?)+/) do |paragraph|
paragraph_content = paragraph.lines.inject("") do |all, line|
all << line.strip + "\n"
end
"<p>#{paragraph_content.chomp}</p>\n"
end
end
def format_header(text, count)
clear_text = text.strip.gsub(/\#{1,4} \s*(.*?)\s*$/, "\\1")
"<h#{count.to_s}>" + clear_text + "</h#{count.to_s}>"
end
def format_pre(text)
clear_text = text.gsub(/ {4}(.*)$/, "\\1").chomp
"<pre><code>" + clear_text + "</code></pre>\n"
end
def format_quote(text)
clear_text = text.gsub(/> (.*)$/, "\\1")
"<blockquote>" + format_paragraphs(clear_text).chomp + "</blockquote>\n"
end
def format_unordered(text)
clear_text = text.gsub(/\* (.*)$/, " <li>\\1</li>").chomp
"<ul>\n" + clear_text + "\n</ul>\n"
end
def format_ordered(text)
clear_text = text.gsub(/\d+\. (.*)$/, " <li>\\1</li>").chomp
"<ol>\n" + clear_text + "\n</ol>\n"
end
end
class Formatter
def initialize(markdown_text)
@markdown_text = markdown_text
@html_text = @markdown_text
end
def to_html
format_symbols
format_anchors
format_text_styles
format_blocks
@html_text
end
def format_blocks
blocks_formatter = BlocksFormatter.new(@html_text)
@html_text = blocks_formatter.to_blocks
end
def format_symbols
@html_text = @html_text.gsub(/&|<|(?<!^)>|\"/) do |symbol|
case symbol
when /&/ then "&amp;"
when /</ then "&lt;"
when />/ then "&gt;"
when /\"/ then "&quot;"
end
end
end
def format_anchors
@html_text = @html_text.gsub(/\[(.*)\]\((.*)\)/,"<a href=\"\\2\">\\1</a>")
end
def format_text_styles
@html_text = @html_text.gsub(/.*(\*\*|_).*?\1.*/) do |line|
line.start_with?("> ", " ") ? line : format_text_style(line)
end
end
def format_text_style text
text.gsub(/(\*\*|_)(.*?)\1/) do |styled_text|
case $1
when "**" then "<strong>#{format_text_style($2)}</strong>"
when "_" then "<em>#{format_text_style($2)}</em>"
end
end
end
def to_s
to_html
end
def inspect
@markdown_text
end
end

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

.......................F.F...........F...................

Failures:

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

  2) 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-5x9fso/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-5x9fso/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)>'

  3) Formatter bold and italic text rendering works in blockquotes
     Failure/Error: Formatter.new(plain).to_html.should eq formatted.strip
       
       expected: "<blockquote><p><em>Simplest</em> case</p></blockquote>"
            got: "<blockquote><p>_Simplest_ case</p></blockquote>"
       
       (compared using ==)
     # /tmp/d20111129-16859-5x9fso/spec.rb:660:in `expect_transformation'
     # /tmp/d20111129-16859-5x9fso/spec.rb:665:in `block in expect_transformations'
     # /tmp/d20111129-16859-5x9fso/spec.rb:664:in `each'
     # /tmp/d20111129-16859-5x9fso/spec.rb:664:in `expect_transformations'
     # /tmp/d20111129-16859-5x9fso/spec.rb:455: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.63552 seconds
57 examples, 3 failures

Failed examples:

rspec /tmp/d20111129-16859-5x9fso/spec.rb:285 # Formatter links allows multiple links on a single line
rspec /tmp/d20111129-16859-5x9fso/spec.rb:298 # Formatter links does not render them in code blocks
rspec /tmp/d20111129-16859-5x9fso/spec.rb:450 # Formatter bold and italic text rendering works in blockquotes

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

Славена обнови решението на 23.11.2011 22:44 (преди над 12 години)

+module Patterns
+ def self.block
+ pattern = ''
+ pattern << code + '|'
+ pattern << unordered_list + '|'
+ pattern << ordered_list + '|'
+ pattern << blockquote + '|'
+ pattern << header
+ Regexp.new(pattern)
+ end
+
+ @private
+ def self.code
+ '(^ {4}.*\n?)+'
+ end
+
+ def self.unordered_list
+ '(^[ \t\r\f]*\* .*\n?)+'
+ end
+
+ def self.ordered_list
+ '(^[ \t\r\f]*\d+\. .*\n?)+'
+ end
+
+ def self.blockquote
+ '(^[ \t\r\f]*\> .*\n?)+'
+ end
+
+ def self.header
+ '^[ \t\r\f]*#{1,4} .*\S.*'
+ end
+end
+
+class BlocksFormatter
+ def initialize(markdown_text)
+ @markdown_text = markdown_text
+ end
+
+ def to_blocks
+ format_text(@markdown_text).strip
+ end
+
+ def format_text(text)
+ block_element = text.match(Patterns.block)
+ if block_element
+ format_paragraphs(block_element.pre_match) +
+ format_block(block_element[0]) +
+ format_text(block_element.post_match)
+ else
+ format_paragraphs(text)
+ end
+ end
+
+ def format_block(text)
+ case text
+ when /^\s* {4}/ then format_pre(text)
+ when /^\s*> / then format_quote(text)
+ when /^\s*\* / then format_unordered(text)
+ when /^\s*\d+\. / then format_ordered(text)
+ when /^\s*(\#{1,4}) / then format_header(text, $1.size)
+ end
+ end
+
+ def format_paragraphs(text)
+ text.gsub(/(^(.*)\S(.*)\n?)+/) do |paragraph|
+ paragraph_content = paragraph.lines.inject("") do |all, line|
+ all << line.strip + "\n"
+ end
+ "<p>#{paragraph_content.chomp}</p>\n"
+ end
+ end
+
+ def format_header(text, count)
+ clear_text = text.strip.gsub(/\#{1,4} \s*(.*?)\s*$/, "\\1")
+ "<h#{count.to_s}>" + clear_text + "</h#{count.to_s}>"
+ end
+
+ def format_pre(text)
+ clear_text = text.gsub(/ {4}(.*)$/, "\\1").chomp
+ "<pre><code>" + clear_text + "</code></pre>\n"
+ end
+
+ def format_quote(text)
+ clear_text = text.gsub(/> (.*)$/, "\\1")
+ "<blockquote>" + format_paragraphs(clear_text).chomp + "</blockquote>\n"
+ end
+
+ def format_unordered(text)
+ clear_text = text.gsub(/\* (.*)$/, " <li>\\1</li>").chomp
+ "<ul>\n" + clear_text + "\n</ul>\n"
+ end
+
+ def format_ordered(text)
+ clear_text = text.gsub(/\d+\. (.*)$/, " <li>\\1</li>").chomp
+ "<ol>\n" + clear_text + "\n</ol>\n"
+ end
+end
+
+class Formatter
+ def initialize(markdown_text)
+ @markdown_text = markdown_text
+ @html_text = @markdown_text
+ end
+
+ def to_html
+ format_symbols
+ format_anchors
+ format_text_styles
+ format_blocks
+ @html_text
+ end
+
+ def format_blocks
+ blocks_formatter = BlocksFormatter.new(@html_text)
+ @html_text = blocks_formatter.to_blocks
+ end
+
+ def format_symbols
+ @html_text = @html_text.gsub(/&|<|(?<!^)>|\"/) do |symbol|
+ case symbol
+ when /&/ then "&amp;"
+ when /</ then "&lt;"
+ when />/ then "&gt;"
+ when /\"/ then "&quot;"
+ end
+ end
+ end
+
+ def format_anchors
+ @html_text = @html_text.gsub(/\[(.*)\]\((.*)\)/,"<a href=\"\\2\">\\1</a>")
+ end
+
+ def format_text_styles
+ @html_text = @html_text.gsub(/.*(\*\*|_).*?\1.*/) do |line|
+ line.start_with?("> ", " ") ? line : format_text_style(line)
+ end
+ end
+
+ def format_text_style text
+ text.gsub(/(\*\*|_)(.*?)\1/) do |styled_text|
+ case $1
+ when "**" then "<strong>#{format_text_style($2)}</strong>"
+ when "_" then "<em>#{format_text_style($2)}</em>"
+ end
+ end
+ end
+
+ def to_s
+ to_html
+ end
+
+ def inspect
+ @markdown_text
+ end
+end