Make truncate() Unicode-aware
This commit is contained in:
parent
2c5e5a0015
commit
d3e79ea84a
4 changed files with 41 additions and 9 deletions
|
@ -1,5 +1,6 @@
|
||||||
# The methods added to this helper will be available to all templates in the application.
|
# The methods added to this helper will be available to all templates in the application.
|
||||||
module ApplicationHelper
|
module ApplicationHelper
|
||||||
|
require 'stringsupport'
|
||||||
|
|
||||||
# Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container
|
# Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container
|
||||||
# where the elements respond to first and last (such as a two-element array), the "lasts" serve as option values and
|
# where the elements respond to first and last (such as a two-element array), the "lasts" serve as option values and
|
||||||
|
@ -111,15 +112,17 @@ module ApplicationHelper
|
||||||
PageRenderer.new(page.revisions.last).display_content
|
PageRenderer.new(page.revisions.last).display_content
|
||||||
end
|
end
|
||||||
|
|
||||||
def truncate(text, length = 30, truncate_string = '...')
|
def truncate(text, *args)
|
||||||
return text if text.length <= length
|
options = args.extract_options!
|
||||||
len = length - truncate_string.length
|
options.reverse_merge!(:length => 30, :omission => "...")
|
||||||
|
return text if text.num_chars <= options[:length]
|
||||||
|
len = options[:length] - options[:omission].as_utf8.num_chars
|
||||||
t = ''
|
t = ''
|
||||||
text.split.collect do |word|
|
text.split.collect do |word|
|
||||||
if t.length + word.length <= len
|
if t.num_chars + word.num_chars <= len
|
||||||
t << word + ' '
|
t << word + ' '
|
||||||
else
|
else
|
||||||
return t.chop + truncate_string
|
return t.chop + options[:omission]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<%- @pages_in_category.each do |page| -%>
|
<%- @pages_in_category.each do |page| -%>
|
||||||
<li>
|
<li>
|
||||||
<%= link_to_existing_page page, truncate(page.plain_name, 35) %>
|
<%= link_to_existing_page page, truncate(page.plain_name, :length => 35) %>
|
||||||
</li>
|
</li>
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
<ul style="margin-bottom: 10px">
|
<ul style="margin-bottom: 10px">
|
||||||
<%- @page_names_that_are_wanted.each do |wanted_page_name| -%>
|
<%- @page_names_that_are_wanted.each do |wanted_page_name| -%>
|
||||||
<li>
|
<li>
|
||||||
<%= link_to_page(wanted_page_name, @web, truncate(WikiWords.separate(wanted_page_name), 35)) %>
|
<%= link_to_page(wanted_page_name, @web, truncate(WikiWords.separate(wanted_page_name), :length => 35)) %>
|
||||||
wanted by
|
wanted by
|
||||||
<%= @web.select.pages_that_reference(wanted_page_name).collect { |referring_page|
|
<%= @web.select.pages_that_reference(wanted_page_name).collect { |referring_page|
|
||||||
link_to_existing_page referring_page
|
link_to_existing_page referring_page
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
<ul style="margin-bottom: 35px">
|
<ul style="margin-bottom: 35px">
|
||||||
<%- @pages_that_are_orphaned.each do |orphan_page| -%>
|
<%- @pages_that_are_orphaned.each do |orphan_page| -%>
|
||||||
<li>
|
<li>
|
||||||
<%= link_to_existing_page orphan_page, truncate(orphan_page.plain_name, 35) %>
|
<%= link_to_existing_page orphan_page, truncate(orphan_page.plain_name, :length => 35) %>
|
||||||
</li>
|
</li>
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -2,8 +2,30 @@
|
||||||
|
|
||||||
class String
|
class String
|
||||||
|
|
||||||
|
# Return the number of unicode characters in a string
|
||||||
|
#
|
||||||
|
# :call-seq:
|
||||||
|
# string.num_chars -> integer
|
||||||
|
#
|
||||||
|
# Because Rails 2.3.5's String#mb_chars.length is broken,
|
||||||
|
# we provide this method.
|
||||||
|
#--
|
||||||
|
if "".respond_to?(:force_encoding)
|
||||||
|
def num_chars
|
||||||
|
length
|
||||||
|
end
|
||||||
|
else
|
||||||
|
def num_chars
|
||||||
|
unpack('U*').length
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#++
|
||||||
# A method to allow byte-oriented operations in both Ruby 1.8 and Ruby 1.9
|
# A method to allow byte-oriented operations in both Ruby 1.8 and Ruby 1.9
|
||||||
#
|
#
|
||||||
|
# :call-seq:
|
||||||
|
# string.to_utf_8 -> string (with the encoding set to "ASCII-8BIT")
|
||||||
|
#
|
||||||
# Under 1.8, this is a NOOP. Under 1.9, it sets the encoding to "ASCII-8BIT"
|
# Under 1.8, this is a NOOP. Under 1.9, it sets the encoding to "ASCII-8BIT"
|
||||||
#--
|
#--
|
||||||
if "".respond_to?(:force_encoding)
|
if "".respond_to?(:force_encoding)
|
||||||
|
@ -19,6 +41,9 @@ end
|
||||||
#++
|
#++
|
||||||
# A method to allow string-oriented operations in both Ruby 1.8 and Ruby 1.9
|
# A method to allow string-oriented operations in both Ruby 1.8 and Ruby 1.9
|
||||||
#
|
#
|
||||||
|
# :call-seq:
|
||||||
|
# string.to_utf_8 -> string (with the encoding set to "UTF-8")
|
||||||
|
#
|
||||||
# Under 1.8, this is a NOOP. Under 1.9, it sets the encoding to "UTF-8"
|
# Under 1.8, this is a NOOP. Under 1.9, it sets the encoding to "UTF-8"
|
||||||
#--
|
#--
|
||||||
if "".respond_to?(:force_encoding)
|
if "".respond_to?(:force_encoding)
|
||||||
|
|
|
@ -40,8 +40,12 @@ class WikiControllerTest < ActionController::TestCase
|
||||||
def test_truncate_page_name
|
def test_truncate_page_name
|
||||||
wanted_page_name = 'This is a very, very, very, very, VERY long page name'
|
wanted_page_name = 'This is a very, very, very, very, VERY long page name'
|
||||||
evil_page_name = 'This page has plenty of fun & games'
|
evil_page_name = 'This page has plenty of fun & games'
|
||||||
assert_equal 'This is a very, very, very,...', @controller.truncate(WikiWords.separate(wanted_page_name), 35)
|
unicode_page_name = "This p\xF0\x9D\x94\xB8\xF0\x9D\x94\xBE\xF0\x9D\x94\xBC has plenty of fun & games"
|
||||||
|
assert_equal 'This is a very, very, very,...', @controller.truncate(WikiWords.separate(wanted_page_name), :length => 35)
|
||||||
assert_equal 'This page has plenty of fun...', @controller.truncate(WikiWords.separate(evil_page_name))
|
assert_equal 'This page has plenty of fun...', @controller.truncate(WikiWords.separate(evil_page_name))
|
||||||
|
truncated = "".respond_to?(:force_encoding) ? "This p\u{1D538}\u{1D53E}\u{1D53C} has plenty of fun\u2633\u2633" :
|
||||||
|
"This p\xF0\x9D\x94\xB8\xF0\x9D\x94\xBE\xF0\x9D\x94\xBC has plenty of fun\xE2\x98\xB3\xE2\x98\xB3"
|
||||||
|
assert_equal truncated, @controller.truncate(WikiWords.separate(unicode_page_name), :omission =>"\xE2\x98\xB3\xE2\x98\xB3")
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_authenticate
|
def test_authenticate
|
||||||
|
|
Loading…
Reference in a new issue