Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
kakusuke committed Sep 6, 2014
1 parent f6b448d commit d24f658
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 51 deletions.
81 changes: 34 additions & 47 deletions app/models/concerns/markdownable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,74 +4,61 @@ module Markdownable
module ClassMethods
def markdownable(*fields)
fields.each do |field|
define_method "#{field}_html_with_toc" do
text = self.send(field)
Markdownable.markdown(text, true)
end
define_method "#{field}_html" do
text = self.send(field)
Markdownable.markdown(text, false)
Markdownable.markdown(self.send(field))
end
define_method "#{field}_toc" do
Markdownable.markdown_toc(self.send(field))
end
end
end
end

class ArticlesRenderer < Redcarpet::Render::HTML
def initialize(extensions = {})
super extensions.merge(link_attributes: { target: "_blank" })
end

def block_code(code, language)
code.sub!(/(@@@[^\n]+@@@\n)/, "")
title = $1 || ""
begin
code = CGI.unescapeHTML code
code = CodeRay.scan(code, language).div()
code.sub(/^/, create_filename_row(title))
rescue
self.block_code(title + code, :text)
end
language, filename = language.split ':'
filename(filename) + CodeRay.scan(code, language).div()
end

def initialize(extensions = {})
super extensions.merge(link_attributes: { target: "_blank" })
def paragraph(text)
text.gsub(/\n/, "<br>\n")
end

def create_filename_row(filename)
return "" if filename.empty?
%!<div class="code-filename">#{filename.gsub("@@@", "")}</div>!
private

def filename(filename)
return "" if filename.blank?
%!<div class="code-filename">#{filename}</div>!
end
end

NO_TOC_TEXT = "--no-toc"

def self.markdown(text, with_toc)
renderer = ArticlesRenderer.new(with_toc_data: true)
markdown = Redcarpet::Markdown.new(
renderer,
autolink: true,
space_after_headers: false,
fenced_code_blocks: true,
tables: true,
strikethrough: true,
superscript: true
)
# 引用ができなくなるのを防ぐため、エスケープ後 「>」 記号だけ元に戻す。
text = ERB::Util.html_escape(text).gsub("&gt;", ">").gsub(/\r?\n/, " \n")
toc = with_toc ? markdown_toc(text) : ""
text.sub!(/^#{NO_TOC_TEXT}/, "")
html = markdown.render(parse_filename(text)).gsub("&amp;", "&")
toc + html
def self.markdown(text)
Redcarpet::Markdown.new(
ArticlesRenderer.new(),
autolink: true,
space_after_headers: false,
fenced_code_blocks: true,
tables: true,
strikethrough: true,
superscript: true)
.render(text.sub(NO_TOC_TEXT, ''))
end

def self.markdown_toc(text)
return "" if text.match(/^#{NO_TOC_TEXT}/)
html_toc = Redcarpet::Markdown.new(Redcarpet::Render::HTML_TOC, fenced_code_blocks: true)
# 引用ができなくなるのを防ぐため、エスケープ後 「>」 記号だけ元に戻す。
toc = html_toc.render(text)
toc = "<h1>#{I18n.t('articles.index_title')}</h1> #{toc}<hr>" unless toc.blank?
toc
Redcarpet::Markdown.new(
Redcarpet::Render::HTML_TOC,
fenced_code_blocks: true)
.render(text)
.tap {|toc|
break "<h1>#{I18n.t('articles.index_title')}</h1> #{toc}<hr>" unless toc.blank?
}
end

def self.parse_filename(text)
text.gsub(/(```[^:\r\n]*):([^\n\r]+)(\r|\n)/, "#{'\1'}\n@@@#{'\2'}@@@\n")
end


end
1 change: 1 addition & 0 deletions app/views/articles/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
</div>

<div class="panel-body markdown">
<%= @article.body_toc.html_safe %>
<%= @article.body_html.html_safe %>
</div>
</div>
Expand Down
10 changes: 6 additions & 4 deletions spec/support/has_markdownable_tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@

setter = "#{attr}="
attr_html = "#{attr}_html"
attr_html_with_toc = "#{attr}_html_with_toc"
attr_toc = "#{attr}_toc"

subject (:model) { described_class.new }

describe attr_html do

where(:md, :html) do
'#title' | '<h1 id="title">title</h1>'
"```ruby\n<a>\n```" | /\A(?!<div class="code-filename">).*\Z/m
"```ruby:name.rb\n<a>\n```" | /<div class="code-filename">name\.rb/
"```ruby:name.rb\n<a>\n```" | /class="CodeRay".*<pre>&lt;a&gt;/m
"foo\nbar" | /foo<br>.*bar/m
Expand All @@ -22,14 +23,15 @@
end
end

describe attr_html_with_toc do
describe attr_toc do
where(:md, :html) do
"#h1\n##h2" | /<li>.*h1.*<ul>.*<li>.*h2/m
"#h1\n##h2" | /<li>.*h1.*<ul>.*<li>.*h2/m
"--no-toc\n#h1" | /\A\Z/m
end

with_them do
before { model.send setter, md }
its(attr_html_with_toc) { should match html }
its(attr_toc) { should match html }
end
end
end

0 comments on commit d24f658

Please sign in to comment.