parent
12ed2d793b
commit
e7aa2be828
29 changed files with 193 additions and 51 deletions
@ -0,0 +1,10 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
class ASCIIFolding |
||||
NON_ASCII_CHARS = 'ÀÁÂÃÄÅàáâãäåĀāĂ㥹ÇçĆćĈĉĊċČčÐðĎďĐđÈÉÊËèéêëĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħÌÍÎÏìíîïĨĩĪīĬĭĮįİıĴĵĶķĸĹĺĻļĽľĿŀŁłÑñŃńŅņŇňʼnŊŋÒÓÔÕÖØòóôõöøŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšſŢţŤťŦŧÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųŴŵÝýÿŶŷŸŹźŻżŽž' |
||||
EQUIVALENT_ASCII_CHARS = 'AAAAAAaaaaaaAaAaAaCcCcCcCcCcDdDdDdEEEEeeeeEeEeEeEeEeGgGgGgGgHhHhIIIIiiiiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnNnnNnOOOOOOooooooOoOoOoRrRrRrSsSsSsSssTtTtTtUUUUuuuuUuUuUuUuUuUuWwYyyYyYZzZzZz' |
||||
|
||||
def fold(str) |
||||
str.tr(NON_ASCII_CHARS, EQUIVALENT_ASCII_CHARS) |
||||
end |
||||
end |
@ -0,0 +1,25 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
class HashtagNormalizer |
||||
def normalize(str) |
||||
remove_invalid_characters(ascii_folding(lowercase(cjk_width(str)))) |
||||
end |
||||
|
||||
private |
||||
|
||||
def remove_invalid_characters(str) |
||||
str.gsub(/[^[:alnum:]#{Tag::HASHTAG_SEPARATORS}]/, '') |
||||
end |
||||
|
||||
def ascii_folding(str) |
||||
ASCIIFolding.new.fold(str) |
||||
end |
||||
|
||||
def lowercase(str) |
||||
str.mb_chars.downcase.to_s |
||||
end |
||||
|
||||
def cjk_width(str) |
||||
str.unicode_normalize(:nfkc) |
||||
end |
||||
end |
@ -1,6 +1,6 @@ |
||||
= opengraph 'og:site_name', t('about.hosted_on', domain: site_hostname) |
||||
= opengraph 'og:url', tag_url(@tag) |
||||
= opengraph 'og:type', 'website' |
||||
= opengraph 'og:title', "##{@tag.name}" |
||||
= opengraph 'og:description', strip_tags(t('about.about_hashtag_html', hashtag: @tag.name)) |
||||
= opengraph 'og:title', "##{@tag.display_name}" |
||||
= opengraph 'og:description', strip_tags(t('about.about_hashtag_html', hashtag: @tag.display_name)) |
||||
= opengraph 'twitter:card', 'summary' |
||||
|
@ -0,0 +1,5 @@ |
||||
class AddDisplayNameToTags < ActiveRecord::Migration[6.1] |
||||
def change |
||||
add_column :tags, :display_name, :string |
||||
end |
||||
end |
@ -0,0 +1,29 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
require 'rails_helper' |
||||
|
||||
describe HashtagNormalizer do |
||||
subject { described_class.new } |
||||
|
||||
describe '#normalize' do |
||||
it 'converts full-width Latin characters into basic Latin characters' do |
||||
expect(subject.normalize('Synthwave')).to eq 'synthwave' |
||||
end |
||||
|
||||
it 'converts half-width Katakana into Kana characters' do |
||||
expect(subject.normalize('シーサイドライナー')).to eq 'シーサイドライナー' |
||||
end |
||||
|
||||
it 'converts modified Latin characters into basic Latin characters' do |
||||
expect(subject.normalize('BLÅHAJ')).to eq 'blahaj' |
||||
end |
||||
|
||||
it 'strips out invalid characters' do |
||||
expect(subject.normalize('#foo')).to eq 'foo' |
||||
end |
||||
|
||||
it 'keeps valid characters' do |
||||
expect(subject.normalize('a·b')).to eq 'a·b' |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue