Решение на Пета задача от Константин Добрев

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

Към профила на Константин Добрев

Резултати

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

Код

class MarkupPrototype
def format str
result = ""
str.lines { |line| result += line_format(line) }
remove_newline result
end
def line_format str
""
end
def remove_newline str
str.end_with?("\n") ? str.chop : str
end
end
class SpecialChars < MarkupPrototype
def initialize
@sym_table = {"&" => "&amp;", "<" => "&lt;", ">" => "&gt;", "\"" => "&quot;"}
end
private
def line_format line
result = line
@sym_table.each do |key, value|
result = replace(result, key, value)
end
result
end
def replace str, prev, repl
if str.start_with? ">" and prev == ">"
return ">" + str[1..-1].gsub(prev, repl)
end
str.gsub(prev, repl)
end
end
class FontMarkup < MarkupPrototype
private
def line_format str
unless /^\ {4}/.match str
if wrong_nesting_str(str).start_with?("**")
return strong(str)
elsif wrong_nesting_str(str).start_with?("_")
return em(str)
end
return em strong(str)
end
str
end
def strong str
result = str
until ((/\*\*.*\*\*/. match result) == nil) do
result = result.sub("**", "<strong>")
result = result.sub("**", "</strong>")
end
result
end
def em str
result = str
until ((/_.*_/. match result) == nil) do
result = result.sub("_", "<em>")
result = result.sub("_", "</em>")
end
result
end
def wrong_nesting_str str
(/(\*\*.*_.*\*\*.*_)|(_.*\*\*.*_.*\*\*)/.match str).to_s
end
end
class Link < MarkupPrototype
private
def line_format str
if (not /^\ {4}/.match str) and /\[.*\]\(.*\)/.match str
return str.gsub(/\[.*\]\(.*\)/, extract_link(str))
end
str
end
def correct? str
text_cond = (not extract_text(str).include? "]")
url_cond = (not extract_url(str).include? ")")
text_cond and url_cond
end
def extract_link str
link = (/\[.*\]\(.*\)/.match str).to_s
if correct? link
text, url = extract_text(link), extract_url(link)
return "<a href=\"" + url + "\">" + text + "</a>"
end
str
end
def extract_text str
result = (/\[.*\]/.match str).to_s[1..-2]
end
def extract_url str
result = (/\(.*\)/.match str).to_s[1..-2]
if /^&quot;.*&quot;/.match result
return result.to_s[6..-7].strip
end
result
end
end
class Header < MarkupPrototype
private
def line_format str
if /^\s{0,3}\#{1,4}\ \s*\S+/.match str
h_num = header_type(str)
temp = str.sub(/^\s*\#{1,4}\s+/, "<h#{h_num}>")
return temp.strip.sub(/$/, "</h#{h_num}>") + "\n"
end
str
end
def header_type str
(/\#{1,4}\ +/.match str).to_s.count "#"
end
end
class Paragraph
def format str
str_arr = []
paragraphed_arr(str).each do |elem|
str_arr << elem
if str_arr[-1].start_with? "<p>"
str_arr[-1] = "<p>" + str_arr[-1][3..-1].strip + "</p>"
end
end
str_arr.join("\n")
end
private
def paragraphed_arr str
result = []
str.lines do |line|
if condition?(line)
result = construct_paragraph(result, line)
else
result << remove_newline(line)
end
end
result
end
def construct_paragraph array, line
result = array
if condition?(result[-1])
result[-1] += line
else
result << "<p>" + line
end
result
end
def remove_newline str
str.end_with?("\n") ? str.chop : str
end
def condition? str
cond = (/(^\s*\#{1,4}\ \s*\S+)|(^\ {4}.*)|(^> )|(^\d+\. )|(^\* )/.match str) == nil
(str != "") and (str != nil) and (str != "\n") and cond
end
end
class Blockquote
def format str
str_arr = []
quoted_arr(str).each do |elem|
str_arr << elem
if str_arr[-1].start_with? "<blockquote>"
str_arr[-1] = str_arr[-1].strip + "</blockquote>\n"
end
end
str_arr.join
end
private
def quoted_arr str
result = []
str.lines do |line|
if condition?(line)
result = construct_quote(result, line)
else
result << line
end
end
put_paragraphs(result)
end
def construct_quote array, line
result = array
if condition?(result[-1])
result[-1] += line[2..-1]
else
result << "<blockquote>" + line[2..-1]
end
result
end
def put_paragraphs array
result = []
array.each do |elem|
if elem.start_with? "<blockquote>"
result << "<blockquote>" + paragraphs(elem[12..-1])
else
result << elem
end
end
result
end
def paragraphs line
elems_arr = []
quote_elem(line). each do |elem|
temp = (/^ *\S/.match elem) ? ("<p>" + elem.strip + "</p>") : elem.strip
elems_arr << temp
end
elems_arr.join("\n")
end
def quote_elem line
result = []
line.split("\n").each do |elem|
if /^ *\S/.match elem
result = push_elem(result, elem)
else
result << elem
end
end
result
end
def push_elem array, elem
result = array
if /^ *\S/.match result[-1]
result[-1] += "\n" + elem
else
result << elem
end
result
end
def condition? str
/(^\> +)|(^<blockquote>)/.match str
end
end
class Codeblock
def format str
str_arr = []
coded_arr(str).each do |elem|
str_arr << elem
if str_arr[-1].start_with? "<pre><code>"
str_arr[-1] = remove_newline(str_arr[-1]) + "</code></pre>"
end
end
str_arr.join("\n")
end
private
def coded_arr str
result = []
str.lines do |line|
if condition?(line)
result = construct_codeblock(result, line)
else
result << remove_newline(line)
end
end
result
end
def construct_codeblock array, line
result = array
if condition?(result[-1])
result[-1] += line[4..-1]
else
result << "<pre><code>" + line[4..-1]
end
result
end
def remove_newline str
str.end_with?("\n") ? str.chop : str
end
def condition? str
/(^\ {4}.*)|(^<pre><code>)/.match str
end
end
class List
def format str
str_arr = []
listed_arr(str).each do |elem|
str_arr << elem
if str_arr[-1].start_with? "<ul>\n"
str_arr[-1] = str_arr[-1].strip + "\n</ul>"
elsif str_arr[-1].start_with? "<ol>\n"
str_arr[-1] = str_arr[-1].strip + "\n</ol>"
end
end
str_arr.join("\n")
end
private
def listed_arr str
result = []
str.lines do |line|
if /^\d+.\ /.match line
result = constr_ordered_list(result, line)
elsif /^\*\ /.match line
result = constr_unordered_list(result, line)
else
result << remove_newline(line)
end
end
result
end
def constr_ordered_list array, line
result = array
if result[-1] != nil and result[-1].start_with? "<ol>"
result[-1] += list_elem(line, "ol")
else
result << "<ol>\n" + list_elem(line, "ol")
end
result
end
def constr_unordered_list array, line
result = array
if result[-1] != nil and result[-1].start_with? "<ul>"
result[-1] += list_elem(line, "ul")
else
result << "<ul>\n" + list_elem(line, "ul")
end
result
end
def list_elem str, type
if type == "ol"
offset = (/(^\d+.\ )/.match str).to_s.length
return " <li>" + str[offset..-1].strip + "</li>\n"
else
" <li>" + str[2..-1].strip + "</li>\n"
end
end
def remove_newline str
str.end_with?("\n") ? str.chop : str
end
def condition? str
/(^\d+.\ )|(^\*\ )/.match str
end
end
class Formatter
def initialize output_str
@output_str = output_str
end
def to_html
result = SpecialChars.new.format @output_str
result = FontMarkup.new.format result
result = Link.new.format result
result = Paragraph.new.format result
result = Header.new.format result
result = Blockquote.new.format result
result = Codeblock.new.format result
List.new.format result
end
def to_s
to_html
end
def inspect
@output_str
end
end

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

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

Finished in 0.66527 seconds
57 examples, 2 failures

Failed examples:

rspec /tmp/d20111129-16859-1t0nly0/spec.rb:285 # Formatter links allows multiple links on a single line
rspec /tmp/d20111129-16859-1t0nly0/spec.rb:541 # Formatter whitespace removes excess leading and trailing whitespace

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

Константин обнови решението на 23.11.2011 02:21 (преди над 12 години)

+class MarkupPrototype
+
+ def format str
+ result = ""
+ str.lines { |line| result += line_format(line) }
+ remove_newline result
+ end
+
+ def line_format str
+ ""
+ end
+
+ def remove_newline str
+ str.end_with?("\n") ? str.chop : str
+ end
+
+end
+
+class SpecialChars < MarkupPrototype
+
+ def initialize
+ @sym_table = {"&" => "&amp;", "<" => "&lt;", ">" => "&gt;", "\"" => "&quot;"}
+ end
+
+ private
+
+ def line_format line
+ result = line
+ @sym_table.each do |key, value|
+ result = replace(result, key, value)
+ end
+ result
+ end
+
+ def replace str, prev, repl
+ if str.start_with? ">" and prev == ">"
+ return ">" + str[1..-1].gsub(prev, repl)
+ end
+ str.gsub(prev, repl)
+ end
+
+end
+
+class FontMarkup < MarkupPrototype
+
+ private
+
+ def line_format str
+ unless /^\ {4}/.match str
+ if wrong_nesting_str(str).start_with?("**")
+ return strong(str)
+ elsif wrong_nesting_str(str).start_with?("_")
+ return em(str)
+ end
+ return em strong(str)
+ end
+ str
+ end
+
+ def strong str
+ result = str
+ until ((/\*\*.*\*\*/. match result) == nil) do
+ result = result.sub("**", "<strong>")
+ result = result.sub("**", "</strong>")
+ end
+ result
+ end
+
+ def em str
+ result = str
+ until ((/_.*_/. match result) == nil) do
+ result = result.sub("_", "<em>")
+ result = result.sub("_", "</em>")
+ end
+ result
+ end
+
+ def wrong_nesting_str str
+ (/(\*\*.*_.*\*\*.*_)|(_.*\*\*.*_.*\*\*)/.match str).to_s
+ end
+
+end
+
+class Link < MarkupPrototype
+
+ private
+
+ def line_format str
+ if (not /^\ {4}/.match str) and /\[.*\]\(.*\)/.match str
+ return str.gsub(/\[.*\]\(.*\)/, extract_link(str))
+ end
+ str
+ end
+
+ def correct? str
+ text_cond = (not extract_text(str).include? "]")
+ url_cond = (not extract_url(str).include? ")")
+ text_cond and url_cond
+ end
+
+ def extract_link str
+ link = (/\[.*\]\(.*\)/.match str).to_s
+ if correct? link
+ text, url = extract_text(link), extract_url(link)
+ return "<a href=\"" + url + "\">" + text + "</a>"
+ end
+ str
+ end
+
+ def extract_text str
+ result = (/\[.*\]/.match str).to_s[1..-2]
+ end
+
+ def extract_url str
+ result = (/\(.*\)/.match str).to_s[1..-2]
+ if /^&quot;.*&quot;/.match result
+ return result.to_s[6..-7].strip
+ end
+ result
+ end
+
+end
+
+class Header < MarkupPrototype
+
+ private
+
+ def line_format str
+ if /^\s{0,3}\#{1,4}\ \s*\S+/.match str
+ h_num = header_type(str)
+ temp = str.sub(/^\s*\#{1,4}\s+/, "<h#{h_num}>")
+ return temp.strip.sub(/$/, "</h#{h_num}>") + "\n"
+ end
+ str
+ end
+
+ def header_type str
+ (/\#{1,4}\ +/.match str).to_s.count "#"
+ end
+
+end
+
+class Paragraph
+
+ def format str
+ str_arr = []
+ paragraphed_arr(str).each do |elem|
+ str_arr << elem
+ if str_arr[-1].start_with? "<p>"
+ str_arr[-1] = "<p>" + str_arr[-1][3..-1].strip + "</p>"
+ end
+ end
+ str_arr.join("\n")
+ end
+
+ private
+
+ def paragraphed_arr str
+ result = []
+ str.lines do |line|
+ if condition?(line)
+ result = construct_paragraph(result, line)
+ else
+ result << remove_newline(line)
+ end
+ end
+ result
+ end
+
+ def construct_paragraph array, line
+ result = array
+ if condition?(result[-1])
+ result[-1] += line
+ else
+ result << "<p>" + line
+ end
+ result
+ end
+
+ def remove_newline str
+ str.end_with?("\n") ? str.chop : str
+ end
+
+ def condition? str
+ cond = (/(^\s*\#{1,4}\ \s*\S+)|(^\ {4}.*)|(^> )|(^\d+\. )|(^\* )/.match str) == nil
+ (str != "") and (str != nil) and (str != "\n") and cond
+ end
+
+end
+
+class Blockquote
+
+ def format str
+ str_arr = []
+ quoted_arr(str).each do |elem|
+ str_arr << elem
+ if str_arr[-1].start_with? "<blockquote>"
+ str_arr[-1] = str_arr[-1].strip + "</blockquote>\n"
+ end
+ end
+ str_arr.join
+ end
+
+ private
+
+ def quoted_arr str
+ result = []
+ str.lines do |line|
+ if condition?(line)
+ result = construct_quote(result, line)
+ else
+ result << line
+ end
+ end
+ put_paragraphs(result)
+ end
+
+ def construct_quote array, line
+ result = array
+ if condition?(result[-1])
+ result[-1] += line[2..-1]
+ else
+ result << "<blockquote>" + line[2..-1]
+ end
+ result
+ end
+
+ def put_paragraphs array
+ result = []
+ array.each do |elem|
+ if elem.start_with? "<blockquote>"
+ result << "<blockquote>" + paragraphs(elem[12..-1])
+ else
+ result << elem
+ end
+ end
+ result
+ end
+
+ def paragraphs line
+ elems_arr = []
+ quote_elem(line). each do |elem|
+ temp = (/^ *\S/.match elem) ? ("<p>" + elem.strip + "</p>") : elem.strip
+ elems_arr << temp
+ end
+ elems_arr.join("\n")
+ end
+
+ def quote_elem line
+ result = []
+ line.split("\n").each do |elem|
+ if /^ *\S/.match elem
+ result = push_elem(result, elem)
+ else
+ result << elem
+ end
+ end
+ result
+ end
+
+ def push_elem array, elem
+ result = array
+ if /^ *\S/.match result[-1]
+ result[-1] += "\n" + elem
+ else
+ result << elem
+ end
+ result
+ end
+
+ def condition? str
+ /(^\> +)|(^<blockquote>)/.match str
+ end
+
+end
+
+class Codeblock
+
+ def format str
+ str_arr = []
+ coded_arr(str).each do |elem|
+ str_arr << elem
+ if str_arr[-1].start_with? "<pre><code>"
+ str_arr[-1] = remove_newline(str_arr[-1]) + "</code></pre>"
+ end
+ end
+ str_arr.join("\n")
+ end
+
+ private
+
+ def coded_arr str
+ result = []
+ str.lines do |line|
+ if condition?(line)
+ result = construct_codeblock(result, line)
+ else
+ result << remove_newline(line)
+ end
+ end
+ result
+ end
+
+ def construct_codeblock array, line
+ result = array
+ if condition?(result[-1])
+ result[-1] += line[4..-1]
+ else
+ result << "<pre><code>" + line[4..-1]
+ end
+ result
+ end
+
+ def remove_newline str
+ str.end_with?("\n") ? str.chop : str
+ end
+
+ def condition? str
+ /(^\ {4}.*)|(^<pre><code>)/.match str
+ end
+
+end
+
+class List
+
+ def format str
+ str_arr = []
+ listed_arr(str).each do |elem|
+ str_arr << elem
+ if str_arr[-1].start_with? "<ul>\n"
+ str_arr[-1] = str_arr[-1].strip + "\n</ul>"
+ elsif str_arr[-1].start_with? "<ol>\n"
+ str_arr[-1] = str_arr[-1].strip + "\n</ol>"
+ end
+ end
+ str_arr.join("\n")
+ end
+
+ private
+
+ def listed_arr str
+ result = []
+ str.lines do |line|
+ if /^\d+.\ /.match line
+ result = constr_ordered_list(result, line)
+ elsif /^\*\ /.match line
+ result = constr_unordered_list(result, line)
+ else
+ result << remove_newline(line)
+ end
+ end
+ result
+ end
+
+ def constr_ordered_list array, line
+ result = array
+ if result[-1] != nil and result[-1].start_with? "<ol>"
+ result[-1] += list_elem(line, "ol")
+ else
+ result << "<ol>\n" + list_elem(line, "ol")
+ end
+ result
+ end
+
+ def constr_unordered_list array, line
+ result = array
+ if result[-1] != nil and result[-1].start_with? "<ul>"
+ result[-1] += list_elem(line, "ul")
+ else
+ result << "<ul>\n" + list_elem(line, "ul")
+ end
+ result
+ end
+
+ def list_elem str, type
+ if type == "ol"
+ offset = (/(^\d+.\ )/.match str).to_s.length
+ return " <li>" + str[offset..-1].strip + "</li>\n"
+ else
+ " <li>" + str[2..-1].strip + "</li>\n"
+ end
+ end
+
+ def remove_newline str
+ str.end_with?("\n") ? str.chop : str
+ end
+
+ def condition? str
+ /(^\d+.\ )|(^\*\ )/.match str
+ end
+
+end
+
+class Formatter
+
+ def initialize output_str
+ @output_str = output_str
+ end
+
+ def to_html
+ result = SpecialChars.new.format @output_str
+ result = FontMarkup.new.format result
+ result = Link.new.format result
+ result = Paragraph.new.format result
+ result = Header.new.format result
+ result = Blockquote.new.format result
+ result = Codeblock.new.format result
+ List.new.format result
+ end
+
+ def to_s
+ to_html
+ end
+
+ def inspect
+ @output_str
+ end
+
+end