Решение на Пета задача от Ивайло Петров

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

Към профила на Ивайло Петров

Резултати

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

Код

module InlineFormatters
def format_font string
sub = ->(args) do
add_tags(format_font(args[2]), {'_' => 'em', '**' => "strong"}[args[1]])
end
string.gsub(/^.*(_|\*\*)([^<\n]+?)\1.*$/) do |s|
format s, /(_|\*\*)([^<]+?)\1/, sub
end
end
def format_link string
string.gsub(/^.*\[(.+?)\]\((.+?)\).*$/) do |s|
format s, /\[(.+?)\]\((.+?)\)/, ->(args) { "<a href=\"#{args[2]}\">#{args[1]}</a>" }
end
end
def escape string
escape_symbols = {'&' => '&amp;', '<' => '&lt;', '"' => '&quot;'}
result = string.gsub(/[&<"]/, escape_symbols).gsub(/(?<!^)>/, '&gt;')
end
def add_tags(body, tag, separator = '', end_tag = nil)
if body.end_with? "\n"
body = body.chomp "\n"
suffix = "\n"
else
suffix = ''
end
"<#{tag}>#{separator}#{body.chomp}#{separator}</#{end_tag ? end_tag : tag}>" + suffix
end
def format string, pattern, block
# Make it more general in order to use in format_paragraphs and format_headers
if string.start_with?(' ')
string
else
string.gsub(pattern) { block.call($~.to_a) }
end
end
end
module ParagraphFormatters
def format_paragraphs string
string.gsub(/(^[^<>\n\t][^<\n]*[^<\s][^<\n]*$\n?)+/) do |s|
if s.start_with?(' ') or s.start_with?("> ")
s
else
add_tags(s.gsub(/^[ \t]*(.*?\S)[ \t]*$/, '\1'), 'p')
end
end
end
def format_headers string
string.gsub(/^[ \t]*(\#{1,4})\s+(\S.*)$/) do |s|
if s.start_with? ' '
s
else
add_tags($2.strip,'h' + $1.size.to_s)
end
end
end
def format_code_block string
string.gsub(/((^ {4}(.*)$\n?)+)/) do |s|
add_tags(s.gsub(/^ (.*)$/, '\1'), 'pre><code', '', 'code></pre')
end
end
def format_block_quotes string
string.gsub(/(^>\s+.*$\n?)+/) do |s|
add_tags(format_paragraphs(s.gsub(/^>\s+?(.*)$/, '\1')), 'blockquote')
end
end
def format_unordered_list string
string.gsub(/^(\*\s+.*$\n?)+/) do |s|
add_tags(s.gsub(/^\*\s+(.*)$/, ' <li>\1</li>'), 'ul', "\n")
end
end
def format_ordered_list string
string.gsub(/^(\d+\.\s+.*$\n?)+/) do |s|
add_tags(s.gsub(/^\d+\.\s+(.*)$/, ' <li>\1</li>'), 'ol', "\n")
end
end
def format_empty_lines string
string.gsub(/^\s{1,3}$/, '')
end
end
class Formatter
include InlineFormatters
include ParagraphFormatters
def initialize raw_string
@raw_string = raw_string
end
def to_html
# we cache the result
@result ||= generate_result
end
def inspect
@raw_string
end
def generate_result
result = format_empty_lines(escape(@raw_string.dup))
result = format_headers result
result = format_unordered_list result
result = format_ordered_list result
result = format_paragraphs result
result = format_block_quotes result
result = format_font(format_link(result))
format_code_block(result).strip
end
alias to_s to_html
end

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

.........................................................

Finished in 0.62908 seconds
57 examples, 0 failures

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

Ивайло обнови решението на 22.11.2011 15:10 (преди над 12 години)

+module InlineFormatters
+ def format_font string
+ sub = ->(args) do
+ add_tags(format_font(args[2]), {'_' => 'em', '**' => "strong"}[args[1]])
+ end
+
+ string.gsub(/^.*(_|\*\*)([^<\n]+?)\1.*$/) do |s|
+ format s, /(_|\*\*)([^<]+?)\1/, sub
+ end
+ end
+
+ def format_link string
+ string.gsub(/^.*\[(.+?)\]\((.+?)\).*$/) do |s|
+ format s, /\[(.+?)\]\((.+?)\)/, ->(args) { "<a href=\"#{args[2]}\">#{args[1]}</a>" }
+ end
+ end
+
+ def escape string
+ escape_symbols = {'&' => '&amp;', '<' => '&lt;', '"' => '&quot;'}
+
+ result = string.gsub(/[&<"]/, escape_symbols).gsub(/(?<!^)>/, '&gt;')
+ end
+
+ def add_tags(body, tag, separator = '', end_tag = nil)
+ if body.end_with? "\n"
+ body = body.chomp "\n"
+ suffix = "\n"
+ else
+ suffix = ''
+ end
+
+ "<#{tag}>#{separator}#{body.chomp}#{separator}</#{end_tag ? end_tag : tag}>" + suffix
+ end
+
+ def format string, pattern, block
+ # Make it more general in order to use in format_paragraphs and format_headers
+ if string.start_with?(' ')
+ string
+ else
+ string.gsub(pattern) { block.call($~.to_a) }
+ end
+ end
+end
+
+module ParagraphFormatters
+ def format_paragraphs string
+ string.gsub(/(^[^<>\n\t][^<\n]*[^<\s][^<\n]*$\n?)+/) do |s|
+ if s.start_with?(' ') or s.start_with?("> ")
+ s
+ else
+ add_tags(s.gsub(/^[ \t]*(.*?\S)[ \t]*$/, '\1'), 'p')
+ end
+ end
+ end
+
+ def format_headers string
+ string.gsub(/^[ \t]*(\#{1,4})\s+(\S.*)$/) do |s|
+ if s.start_with? ' '
+ s
+ else
+ add_tags($2.strip,'h' + $1.size.to_s)
+ end
+ end
+ end
+
+ def format_code_block string
+ string.gsub(/((^ {4}(.*)$\n?)+)/) do |s|
+ add_tags(s.gsub(/^ (.*)$/, '\1'), 'pre><code', '', 'code></pre')
+ end
+ end
+
+ def format_block_quotes string
+ string.gsub(/(^>\s+.*$\n?)+/) do |s|
+ add_tags(format_paragraphs(s.gsub(/^>\s+?(.*)$/, '\1')), 'blockquote')
+ end
+ end
+
+ def format_unordered_list string
+ string.gsub(/^(\*\s+.*$\n?)+/) do |s|
+ add_tags(s.gsub(/^\*\s+(.*)$/, ' <li>\1</li>'), 'ul', "\n")
+ end
+ end
+
+ def format_ordered_list string
+ string.gsub(/^(\d+\.\s+.*$\n?)+/) do |s|
+ add_tags(s.gsub(/^\d+\.\s+(.*)$/, ' <li>\1</li>'), 'ol', "\n")
+ end
+ end
+
+ def format_empty_lines string
+ string.gsub(/^\s{1,3}$/, '')
+ end
+end
+
+class Formatter
+ include InlineFormatters
+ include ParagraphFormatters
+
+ def initialize raw_string
+ @raw_string = raw_string
+ end
+
+ def to_html
+ # we cache the result
+ @result ||= generate_result
+ end
+
+ def inspect
+ @raw_string
+ end
+
+ def generate_result
+ result = format_empty_lines(escape(@raw_string.dup))
+ result = format_headers result
+ result = format_unordered_list result
+ result = format_ordered_list result
+ result = format_paragraphs result
+ result = format_block_quotes result
+ result = format_font(format_link(result))
+
+ format_code_block(result).strip
+ end
+
+ alias to_s to_html
+end