Extract markdown helper; use Nokogiri for link_most_content

This commit is contained in:
Rei
2014-01-20 22:32:48 +08:00
parent 32138af819
commit ec594f72a9
6 changed files with 64 additions and 43 deletions

View File

@@ -55,6 +55,9 @@ gem 'bcrypt-ruby', '~> 3.1.2'
# Paignator
gem 'kaminari', '~> 0.15.1'
# Nokogiri XML parser
gem 'nokogiri', '~> 1.6.1'
group :development do
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/jonleighton/spring
gem 'spring'

View File

@@ -142,8 +142,11 @@ GEM
treetop (~> 1.4.8)
method_source (0.8.2)
mime-types (1.25.1)
mini_portile (0.5.2)
minitest (5.2.0)
multi_json (1.8.2)
nokogiri (1.6.1)
mini_portile (~> 0.5.0)
pg (0.17.1)
polyglot (0.3.3)
pry (0.9.12.4)
@@ -204,6 +207,7 @@ DEPENDENCIES
jquery-rails
jquery-turbolinks (~> 2.0.1)
kaminari (~> 0.15.1)
nokogiri (~> 1.6.1)
pg
rack-livereload
rails!

View File

@@ -0,0 +1,22 @@
require 'rouge/plugins/redcarpet'
module MarkdownHelper
class HTMLRender < Redcarpet::Render::HTML
include Rouge::Plugins::Redcarpet
end
def markdown_post(content)
renderer = HTMLRender.new(hard_wrap: true,
filter_html: true,
link_attributes: { rel: 'nofollow' })
markdown = Redcarpet::Markdown.new(renderer,
autolink: true,
space_after_headers: true,
space_after_headers: true,
fenced_code_blocks: true)
markdown.render(content)
end
end

View File

@@ -1,5 +1,3 @@
require 'rouge/plugins/redcarpet'
module PostsHelper
def post_votes(posts, user)
user.post_votes.where(post_id: posts.pluck(:id)).map { |post_vote|
@@ -7,45 +5,34 @@ module PostsHelper
}
end
def format_post(content)
sanitize(markdown_post(content),
def format_post(text)
sanitize(link_post_content(markdown_post(text)),
tags: %w(p br img h1 h2 h3 h4 blockquote pre code strong em a ul ol li span),
attributes: %w(href src class title alt target rel))
end
class PostHTMLRender < Redcarpet::Render::HTML
include Rouge::Plugins::Redcarpet
def link_post_content(text)
doc = Nokogiri::HTML.fragment(text)
def normal_text(text)
# extract @username
text.gsub!(/@(\w+)/) { |match|
username = $1
%Q|<a href="/~#{username}">#{match}</a>|
}
doc.search('text()').each do |node|
unless node.ancestors('a, pre, code').any?
text = node.text
# link @username
text.gsub!(/@(\w+)/) { |match|
username = $1
%Q|<a href="/~#{username}">#{match}</a>|
}
# extract #floor
text.gsub!(/#(\d+)/) { |match|
floor = $1
page = (floor.to_i + 24) / 25
%Q|<a href="?page=#{page}##{floor}">#{match}</a>|
}
text
# link #floor
text.gsub!(/#(\d+)/) { |match|
floor = $1
page = (floor.to_i + 24) / 25
%Q|<a href="?page=#{page}##{floor}">#{match}</a>|
}
node.replace text
end
end
end
def markdown_post(content)
renderer = PostHTMLRender.new(
hard_wrap: true,
filter_html: true,
link_attributes: { rel: 'nofollow' }
)
markdown = Redcarpet::Markdown.new(renderer,
autolink: true,
space_after_headers: true,
fenced_code_blocks: true)
markdown.render(content)
doc.to_html
end
end

View File

@@ -0,0 +1,4 @@
require 'test_helper'
class MarkdownHelperTest < ActionView::TestCase
end

View File

@@ -16,16 +16,17 @@ class PostsHelperTest < ActionView::TestCase
)
end
test "should convert @username" do
create :user, username: 'username'
assert_equal %Q|<p><a href="/~username">@username</a></p>\n|, markdown_post('@username')
test "should link mentions" do
assert_equal %q|<p><a href="/~username">@username</a></p>|, link_post_content('<p>@username</p>')
assert_equal %q|<a href="http://example.org/">@username</a>|, link_post_content(%q|<a href="http://example.org/">@username</a>|)
assert_equal %q|<pre>@username</pre>|, link_post_content(%q|<pre>@username</pre>|)
assert_equal %q|<code>@username</code>|, link_post_content(%q|<code>@username</code>|)
end
test "should convert floor" do
assert_equal %Q|<p><a href="?page=1#1">#1</a></p>\n|, markdown_post('#1')
assert_equal %Q|<p><a href="?page=1#25">#25</a></p>\n|, markdown_post("#25")
assert_equal %Q|<p><a href="?page=2#26">#26</a></p>\n|, markdown_post("#26")
assert_equal %Q|<p><a href="?page=3#51">#51</a></p>\n|, markdown_post("#51")
test "should link floor" do
assert_equal %Q|<p><a href="?page=1#1">#1</a></p>|, link_post_content('<p>#1</p>')
assert_equal %Q|<p><a href="?page=1#25">#25</a></p>|, link_post_content("<p>#25</p>")
assert_equal %Q|<p><a href="?page=2#26">#26</a></p>|, link_post_content("<p>#26</p>")
assert_equal %Q|<p><a href="?page=3#51">#51</a></p>|, link_post_content("<p>#51</p>")
end
end