diff --git a/Manifest.txt b/Manifest.txt index 6ad13463..f54c089b 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -385,6 +385,7 @@ lib/publify_core/text_filter/markdown.rb lib/publify_core/text_filter/markdown_smartquotes.rb lib/publify_core/text_filter/none.rb lib/publify_core/text_filter/smartypants.rb +lib/publify_core/text_transformer.rb lib/publify_core/version.rb lib/publify_guid.rb lib/publify_plugins.rb diff --git a/app/models/article.rb b/app/models/article.rb index af9fb367..5d7df410 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -80,7 +80,7 @@ class Article < Content def set_permalink return if draft? || permalink.present? - self.permalink = title.to_permalink + self.permalink = PublifyCore::TextTransformer.to_permalink(title) end def has_child? diff --git a/app/models/content_base.rb b/app/models/content_base.rb index f3ec78ab..ddc2e01e 100644 --- a/app/models/content_base.rb +++ b/app/models/content_base.rb @@ -55,7 +55,7 @@ def excerpt_text(length = 160) html(:all) end - text = text.strip_html + text = PublifyCore::TextTransformer.strip_html(text) text.slice(0, length) + (text.length > length ? "..." : "") diff --git a/app/models/note.rb b/app/models/note.rb index caf21081..e9e1f739 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -82,7 +82,10 @@ def link_to_mentioned_user(base_url, login) end def set_permalink - self.permalink = "#{id}-#{body.to_permalink[0..79]}" if permalink.blank? + if permalink.blank? + base_permalink = PublifyCore::TextTransformer.to_permalink(body)[0..79] + self.permalink = "#{id}-#{base_permalink}" + end save end @@ -122,7 +125,7 @@ def truncate(message, length) end def twitter_message - base_message = body.strip_html + base_message = PublifyCore::TextTransformer.strip_html(body) if too_long?("#{base_message} (#{short_link})") max_length = 140 - "... (#{redirect.from_url})".length - 1 "#{truncate(base_message, max_length)}... (#{redirect.from_url})" diff --git a/app/models/page.rb b/app/models/page.rb index 75c71431..1d575be1 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -13,7 +13,7 @@ class Page < Content after_save :shorten_url def set_permalink - self.name = title.to_permalink if name.blank? + self.name = PublifyCore::TextTransformer.to_permalink(title) if name.blank? end content_fields :body diff --git a/app/models/post_type.rb b/app/models/post_type.rb index dce6dcb7..0705e072 100644 --- a/app/models/post_type.rb +++ b/app/models/post_type.rb @@ -15,6 +15,6 @@ def name_is_not_read end def sanitize_title - self.permalink = name.to_permalink + self.permalink = PublifyCore::TextTransformer.to_permalink(name) end end diff --git a/app/models/tag.rb b/app/models/tag.rb index 25233393..14cbc73f 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -23,7 +23,7 @@ def self.create_from_article!(article) x.first.tr("\"'", "") end tagwords.uniq.each do |tagword| - tagname = tagword.to_url + tagname = PublifyCore::TextTransformer.to_url(tagword) tags << article.blog.tags.find_or_create_by(name: tagname) do |tag| tag.display_name = tagword end @@ -35,7 +35,7 @@ def self.create_from_article!(article) def ensure_naming_conventions self.display_name = name if display_name.blank? - self.name = display_name.to_url if display_name.present? + self.name = PublifyCore::TextTransformer.to_url(display_name) if display_name.present? end def self.find_all_with_content_counters diff --git a/app/views/admin/notes/_note.html.erb b/app/views/admin/notes/_note.html.erb index eac0a696..3ec0073f 100644 --- a/app/views/admin/notes/_note.html.erb +++ b/app/views/admin/notes/_note.html.erb @@ -1,6 +1,6 @@ - <%= h(note.body.strip_html.slice(0..140)) %> + <%= h(note.excerpt_text(140)) %> <%= author_link(note) %>
diff --git a/lib/publify_core.rb b/lib/publify_core.rb index fe92b66f..ed04bc57 100644 --- a/lib/publify_core.rb +++ b/lib/publify_core.rb @@ -12,6 +12,7 @@ require "publify_core/text_filter/markdown_smartquotes" require "publify_core/text_filter/smartypants" require "publify_core/string_ext" +require "publify_core/text_transformer" require "bootstrap" require "carrierwave" @@ -44,4 +45,10 @@ module PublifyCore # Mime type is fully determined by url Engine.config.action_dispatch.ignore_accept_header = true + + def self.deprecator + @deprecator ||= ActiveSupport::Deprecation.new("10.1", "PublifyCore") + end + + deprecator.deprecate_methods PublifyCore::StringExt, :to_permalink, :to_url, :strip_html end diff --git a/lib/publify_core/string_ext.rb b/lib/publify_core/string_ext.rb index 002e36c4..1d39a6d4 100644 --- a/lib/publify_core/string_ext.rb +++ b/lib/publify_core/string_ext.rb @@ -3,47 +3,20 @@ # FIXME: Replace with helpers and/or methods provided by Rails module PublifyCore module StringExt - ACCENTS = { %w(á à â ä ã Ã Ä Â À) => "a", - %w(é è ê ë Ë É È Ê) => "e", - %w(í ì î ï I Î Ì) => "i", - %w(ó ò ô ö õ Õ Ö Ô Ò) => "o", - ["œ"] => "oe", - ["ß"] => "ss", - %w(ú ù û ü U Û Ù) => "u", - %w(ç Ç) => "c" }.freeze - def to_permalink - string = self - ACCENTS.each do |key, value| - string = string.tr(key.join, value) - end - string = string.tr("'", "-") - string.gsub(/<[^>]*>/, "").to_url + PublifyCore::TextTransformer.to_permalink(self) end - # Returns a-string-with-dashes when passed 'a string with dashes'. - # All special chars are stripped in the process def to_url - return if nil? - - s = downcase.tr("\"'", "") - s = s.gsub(/\P{Word}/, " ") - s.strip.tr_s(" ", "-").tr(" ", "-").sub(/^$/, "-") + PublifyCore::TextTransformer.to_url(self) end def to_title(item, settings, params) TitleBuilder.new(self).build(item, settings, params) end - # Strips any html markup from a string - TYPO_TAG_KEY = TYPO_ATTRIBUTE_KEY = /[\w:_-]+/ - TYPO_ATTRIBUTE_VALUE = /(?:[A-Za-z0-9]+|(?:'[^']*?'|"[^"]*?"))/ - TYPO_ATTRIBUTE = /(?:#{TYPO_ATTRIBUTE_KEY}(?:\s*=\s*#{TYPO_ATTRIBUTE_VALUE})?)/ - TYPO_ATTRIBUTES = /(?:#{TYPO_ATTRIBUTE}(?:\s+#{TYPO_ATTRIBUTE})*)/ - TAG = %r{<[!/?\[]?(?:#{TYPO_TAG_KEY}|--)(?:\s+#{TYPO_ATTRIBUTES})?\s*(?:[!/?\]]+|--)?>} - def strip_html - gsub(TAG, "").gsub(/\s+/, " ").strip + PublifyCore::TextTransformer.strip_html(self) end end end diff --git a/lib/publify_core/text_transformer.rb b/lib/publify_core/text_transformer.rb new file mode 100644 index 00000000..5af29d73 --- /dev/null +++ b/lib/publify_core/text_transformer.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module PublifyCore + module TextTransformer + module_function + + ACCENTS = { %w(á à â ä ã Ã Ä Â À) => "a", + %w(é è ê ë Ë É È Ê) => "e", + %w(í ì î ï I Î Ì) => "i", + %w(ó ò ô ö õ Õ Ö Ô Ò) => "o", + ["œ"] => "oe", + ["ß"] => "ss", + %w(ú ù û ü U Û Ù) => "u", + %w(ç Ç) => "c" }.freeze + + def to_permalink(string) + ACCENTS.each do |key, value| + string = string.tr(key.join, value) + end + string = string.tr("'", "-") + to_url(string.gsub(/<[^>]*>/, "")) + end + + # Returns a-string-with-dashes when passed 'a string with dashes'. + # All special chars are stripped in the process + def to_url(string) + return if string.nil? + + s = string.downcase.tr("\"'", "") + s = s.gsub(/\P{Word}/, " ") + s.strip.tr_s(" ", "-").tr(" ", "-").sub(/^$/, "-") + end + + # Strips any html markup from a string + TYPO_TAG_KEY = TYPO_ATTRIBUTE_KEY = /[\w:_-]+/ + TYPO_ATTRIBUTE_VALUE = /(?:[A-Za-z0-9]+|(?:'[^']*?'|"[^"]*?"))/ + TYPO_ATTRIBUTE = /(?:#{TYPO_ATTRIBUTE_KEY}(?:\s*=\s*#{TYPO_ATTRIBUTE_VALUE})?)/ + TYPO_ATTRIBUTES = /(?:#{TYPO_ATTRIBUTE}(?:\s+#{TYPO_ATTRIBUTE})*)/ + TAG = %r{<[!/?\[]?(?:#{TYPO_TAG_KEY}|--)(?:\s+#{TYPO_ATTRIBUTES})?\s*(?:[!/?\]]+|--)?>} + + def strip_html(string) + string.gsub(TAG, "").gsub(/\s+/, " ").strip + end + end +end diff --git a/spec/models/article_spec.rb b/spec/models/article_spec.rb index 57839f04..ec278893 100644 --- a/spec/models/article_spec.rb +++ b/spec/models/article_spec.rb @@ -132,16 +132,6 @@ expect(not_found).to be_nil end - it "test_strip_title" do - expect("Article-3".to_url).to eq "article-3" - expect("Article 3!?#".to_url).to eq "article-3" - expect("There is Sex in my Violence!".to_url).to eq "there-is-sex-in-my-violence" - expect("-article-".to_url).to eq "article" - expect("Lorem ipsum dolor sit amet, consectetaur adipisicing elit".to_url) - .to eq "lorem-ipsum-dolor-sit-amet-consectetaur-adipisicing-elit" - expect("My Cat's Best Friend".to_url).to eq "my-cats-best-friend" - end - describe "#set_permalink" do it "works for simple cases" do a = blog.articles.build(title: "Article 3!", state: :published) diff --git a/spec/publify_core/string_ext_spec.rb b/spec/publify_core/string_ext_spec.rb index 01fe7f52..e15376cb 100644 --- a/spec/publify_core/string_ext_spec.rb +++ b/spec/publify_core/string_ext_spec.rb @@ -3,26 +3,36 @@ require "rails_helper" RSpec.describe PublifyCore::StringExt do + include ActiveSupport::Testing::Deprecation + describe "#to_permalink" do it "builds a nice permalink from an accentuated string" do - expect("L'été s'ra chaud, l'été s'ra chaud".to_permalink) - .to eq("l-ete-s-ra-chaud-l-ete-s-ra-chaud") + assert_deprecated(/to_permalink/, PublifyCore.deprecator) do + expect("L'été s'ra chaud, l'été s'ra chaud".to_permalink) + .to eq("l-ete-s-ra-chaud-l-ete-s-ra-chaud") + end end end describe "to_url" do it "gives a proper space-less, trimmed URL" do - expect(" this is a sentence ".to_url).to eq("this-is-a-sentence") + assert_deprecated(/to_url/, PublifyCore.deprecator) do + expect(" this is a sentence ".to_url).to eq("this-is-a-sentence") + end end end describe "strip_html" do it "renders text only" do - expect("my blog".strip_html).to eq("my blog") + assert_deprecated(/strip_html/, PublifyCore.deprecator) do + expect("my blog".strip_html).to eq("my blog") + end end it "does not remove a > from a numeric comparison" do - expect("5 < 6 > 4".strip_html).to eq("5 < 6 > 4") + assert_deprecated(/strip_html/, PublifyCore.deprecator) do + expect("5 < 6 > 4".strip_html).to eq("5 < 6 > 4") + end end end end diff --git a/spec/publify_core/text_transformer_spec.rb b/spec/publify_core/text_transformer_spec.rb new file mode 100644 index 00000000..88077113 --- /dev/null +++ b/spec/publify_core/text_transformer_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe PublifyCore::TextTransformer do + describe "#to_permalink" do + it "builds a nice permalink from an accentuated string" do + expect(described_class.to_permalink("L'été s'ra chaud, l'été s'ra chaud")) + .to eq("l-ete-s-ra-chaud-l-ete-s-ra-chaud") + end + end + + describe "to_url" do + it "gives a proper space-less, trimmed URL" do + expect(described_class.to_url(" this is a sentence ")).to eq("this-is-a-sentence") + end + + it "test_strip_title" do + aggregate_failures do + expect(described_class.to_url("Article-3")).to eq "article-3" + expect(described_class.to_url("Article 3!?#")).to eq "article-3" + expect(described_class.to_url("There is Sex in my Violence!")) + .to eq "there-is-sex-in-my-violence" + expect(described_class.to_url("-article-")).to eq "article" + expect(described_class.to_url("Lorem ipsum dolor sit amet," \ + " consectetaur adipisicing elit")) + .to eq "lorem-ipsum-dolor-sit-amet-consectetaur-adipisicing-elit" + expect(described_class.to_url("My Cat's Best Friend")).to eq "my-cats-best-friend" + end + end + end + + describe "strip_html" do + it "renders text only" do + expect(described_class.strip_html("my blog")) + .to eq("my blog") + end + + it "does not remove a > from a numeric comparison" do + expect(described_class.strip_html("5 < 6 > 4")).to eq("5 < 6 > 4") + end + end +end