publify_core 10.0.0 → 10.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of publify_core might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -1
- data/app/controllers/admin/articles_controller.rb +1 -1
- data/app/controllers/admin/post_types_controller.rb +1 -1
- data/app/controllers/articles_controller.rb +2 -2
- data/app/controllers/setup_controller.rb +20 -11
- data/app/helpers/base_helper.rb +1 -1
- data/app/models/article.rb +1 -2
- data/app/models/note.rb +1 -1
- data/app/uploaders/resource_uploader.rb +3 -9
- data/app/views/notes/show_in_reply.html.erb +1 -1
- data/app/views/setup/index.html.erb +42 -11
- data/db/seeds.rb +5 -5
- data/lib/publify_core/string_ext.rb +52 -0
- data/lib/publify_core/text_filter/markdown.rb +53 -0
- data/lib/{publify_textfilter_markdown_smartquotes.rb → publify_core/text_filter/markdown_smartquotes.rb} +3 -3
- data/lib/publify_core/text_filter/none.rb +14 -0
- data/lib/publify_core/text_filter/smartypants.rb +14 -0
- data/lib/publify_core/text_filter/twitterfilter.rb +55 -0
- data/lib/publify_core/version.rb +1 -1
- data/lib/publify_core.rb +6 -6
- data/lib/text_filter_plugin.rb +23 -11
- metadata +45 -25
- data/lib/publify_textfilter_markdown.rb +0 -56
- data/lib/publify_textfilter_none.rb +0 -16
- data/lib/publify_textfilter_smartypants.rb +0 -16
- data/lib/publify_textfilter_twitterfilter.rb +0 -57
- data/lib/transforms.rb +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f07659f73a5dbeb0204128c9d42e6fcec4092ed7d4e920dceac39f1d104531f3
|
4
|
+
data.tar.gz: cef962bcdc17d957b1824f6e529534c48fdadb473280c910a33198cbcb49d2e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f1262b50e741c94cf9bfcf2cc9d30dade5ae00fccbb5a33206789e7a900af47d280246b204b4f6671f2baaf18547fa1c98aad558d890500347ce58cf97d14f6
|
7
|
+
data.tar.gz: 58e3228983425a5a802714855453184d726f351b81475c0f36f63acf19486c61c0be3f54b26a5cb205f0db48924158840a978fb83888c33cbbcaeaddc9d65b98
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 10.0.1 / 2023-10-28
|
4
|
+
|
5
|
+
* Update CarrierWave dependency to version 3.0 ([#102] by [mvz])
|
6
|
+
* Move String monkey-patches into a module under PublifyCore ([#115] by [mvz])
|
7
|
+
* Remove text filter plugin naming requirements ([#109], [#110], [#117] by [mvz])
|
8
|
+
* Fix name and description of Twitterfilter ([#118] by [mvz])
|
9
|
+
* Fix link to pull request in CHANGELOG ([#116] by [mvz])
|
10
|
+
* Provide proper validation feedback during setup ([#119] by [mvz])
|
11
|
+
|
12
|
+
[#102]: https://github.com/publify/publify_core/pull/102
|
13
|
+
[#109]: https://github.com/publify/publify_core/pull/109
|
14
|
+
[#110]: https://github.com/publify/publify_core/pull/110
|
15
|
+
[#115]: https://github.com/publify/publify_core/pull/115
|
16
|
+
[#116]: https://github.com/publify/publify_core/pull/116
|
17
|
+
[#117]: https://github.com/publify/publify_core/pull/117
|
18
|
+
[#118]: https://github.com/publify/publify_core/pull/118
|
19
|
+
[#119]: https://github.com/publify/publify_core/pull/119
|
20
|
+
[mvz]: https://github.com/mvz
|
21
|
+
[dependabot]: https://github.com/apps/dependabot
|
22
|
+
|
3
23
|
## 10.0.0 / 2023-06-25
|
4
24
|
|
5
25
|
### Updated dependencies
|
@@ -37,7 +57,7 @@
|
|
37
57
|
* Remove `sitealizer` table [publify#1089](https://github.com/publify/publify/pull/1089) by [SupriyaMedankar](https://github.com/SupriyaMedankar)
|
38
58
|
* Remove itunes fields from resources [publify#1092](https://github.com/publify/publify/pull/1092) by [SupriyaMedankar](https://github.com/SupriyaMedankar)
|
39
59
|
* Remove `page_caches` table [publify#1090](https://github.com/publify/publify/pull/1090) by [SupriyaMedankar](https://github.com/SupriyaMedankar)
|
40
|
-
* Remove obsolete Sidebar code [
|
60
|
+
* Remove obsolete Sidebar code [publify_core#58](https://github.com/publify/publify_core/pull/58)
|
41
61
|
|
42
62
|
## 9.2.10 / 2023-01-08
|
43
63
|
|
@@ -93,7 +93,7 @@ class Admin::ArticlesController < Admin::BaseController
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def auto_complete_for_article_keywords
|
96
|
-
@items = Tag.
|
96
|
+
@items = Tag.order(:display_name).pluck(:display_name)
|
97
97
|
render json: @items
|
98
98
|
end
|
99
99
|
|
@@ -38,7 +38,7 @@ class Admin::PostTypesController < Admin::BaseController
|
|
38
38
|
# Reset all Articles from the PostType we're destroying to the default PostType
|
39
39
|
# Wrap it in a transaction for safety
|
40
40
|
@post_type.transaction do
|
41
|
-
Article.where(post_type: @post_type.permalink).
|
41
|
+
Article.where(post_type: @post_type.permalink).find_each do |article|
|
42
42
|
article.post_type = "read"
|
43
43
|
article.save
|
44
44
|
end
|
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
class ArticlesController < ContentController
|
4
4
|
before_action :login_required, only: [:preview, :preview_page]
|
5
|
-
before_action :auto_discovery_feed, only: [:show, :index]
|
6
5
|
before_action :verify_config
|
6
|
+
before_action :auto_discovery_feed, only: [:show, :index]
|
7
7
|
|
8
8
|
layout :theme_layout, except: [:trackback]
|
9
9
|
|
@@ -201,7 +201,7 @@ class ArticlesController < ContentController
|
|
201
201
|
case from
|
202
202
|
when /^.*\.rss$/
|
203
203
|
request.format = "rss"
|
204
|
-
from = from.gsub(/\.rss
|
204
|
+
from = from.gsub(/\.rss$/, "")
|
205
205
|
when /^.*\.atom$/
|
206
206
|
request.format = "atom"
|
207
207
|
from = from.gsub(/\.atom$/, "")
|
@@ -4,23 +4,24 @@ class SetupController < BaseController
|
|
4
4
|
before_action :check_config
|
5
5
|
layout "accounts"
|
6
6
|
|
7
|
-
def index
|
7
|
+
def index
|
8
|
+
this_blog.blog_name = ""
|
9
|
+
@user = User.new
|
10
|
+
end
|
8
11
|
|
9
12
|
def create
|
10
|
-
this_blog.blog_name =
|
13
|
+
this_blog.blog_name = blog_params[:blog_name]
|
11
14
|
this_blog.base_url = blog_base_url
|
12
15
|
|
13
|
-
@user = User.new(login: "admin",
|
14
|
-
|
15
|
-
|
16
|
-
text_filter_name: this_blog.text_filter,
|
17
|
-
nickname: "Publify Admin")
|
16
|
+
@user = User.new(user_params.merge(login: "admin",
|
17
|
+
text_filter_name: this_blog.text_filter,
|
18
|
+
nickname: "Publify Admin"))
|
18
19
|
@user.name = @user.login
|
19
20
|
|
20
|
-
unless this_blog.
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
return render :index unless this_blog.valid? && @user.valid?
|
22
|
+
|
23
|
+
this_blog.save!
|
24
|
+
@user.save!
|
24
25
|
|
25
26
|
sign_in @user
|
26
27
|
|
@@ -36,6 +37,14 @@ class SetupController < BaseController
|
|
36
37
|
|
37
38
|
private
|
38
39
|
|
40
|
+
def blog_params
|
41
|
+
params.require(:blog).permit(:blog_name)
|
42
|
+
end
|
43
|
+
|
44
|
+
def user_params
|
45
|
+
params.require(:user).permit(:email, :password)
|
46
|
+
end
|
47
|
+
|
39
48
|
def create_first_post(user)
|
40
49
|
this_blog.articles.build(title: I18n.t("setup.article.title"),
|
41
50
|
author: user.login,
|
data/app/helpers/base_helper.rb
CHANGED
@@ -138,7 +138,7 @@ module BaseHelper
|
|
138
138
|
v = v.chomp
|
139
139
|
# trim the same number of spaces from the beginning of each line
|
140
140
|
# this way plugins can indent nicely without making ugly source output
|
141
|
-
spaces = /\A[ \t]*/.match(v)[0].gsub(
|
141
|
+
spaces = /\A[ \t]*/.match(v)[0].gsub("\t", " ")
|
142
142
|
# add 2 spaces to line up with the assumed position of the surrounding tags
|
143
143
|
v.gsub!(/^#{spaces}/, " ")
|
144
144
|
end
|
data/app/models/article.rb
CHANGED
data/app/models/note.rb
CHANGED
@@ -57,11 +57,9 @@ class ResourceUploader < CarrierWave::Uploader::Base
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def check_content_type!(new_file)
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
file_content_type(new_file)
|
64
|
-
end
|
60
|
+
return unless image? new_file
|
61
|
+
|
62
|
+
detected_type = file_content_content_type(new_file)
|
65
63
|
if detected_type != new_file.content_type
|
66
64
|
raise CarrierWave::IntegrityError, "has MIME type mismatch"
|
67
65
|
end
|
@@ -72,8 +70,4 @@ class ResourceUploader < CarrierWave::Uploader::Base
|
|
72
70
|
def file_content_content_type(new_file)
|
73
71
|
Marcel::MimeType.for Pathname.new(new_file.path)
|
74
72
|
end
|
75
|
-
|
76
|
-
def file_content_type(new_file)
|
77
|
-
Marcel::MimeType.for Pathname.new(new_file.path), name: new_file.filename
|
78
|
-
end
|
79
73
|
end
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<%= image_tag(@reply['user']['profile_image_url'], class: 'alignleft', alt: @reply['user']['name']) %>
|
6
6
|
<% end %>
|
7
7
|
<strong><%= get_reply_context_url(@reply) %></strong>
|
8
|
-
<p><%= nofollowify_links(
|
8
|
+
<p><%= nofollowify_links(PublifyCore::TextFilter::Twitterfilter.filtertext(@reply['text'])) %></p>
|
9
9
|
<p>
|
10
10
|
<small>
|
11
11
|
<%= get_reply_context_twitter_link(@reply) %>
|
@@ -1,17 +1,48 @@
|
|
1
|
+
<div class="row">
|
2
|
+
<div class="col-md-8 col-md-offset-2" id="error-message-page">
|
3
|
+
<% if this_blog.errors.any? %>
|
4
|
+
<div id="error_explanation">
|
5
|
+
<h2><%= t("errors.template.header", model: 'blog', count: this_blog.errors.count) %></h2>
|
6
|
+
<p><%= t("errors.template.body") %></p>
|
7
|
+
<ul>
|
8
|
+
<% this_blog.errors.full_messages.each do |message| %>
|
9
|
+
<li><%= message %></li>
|
10
|
+
<% end %>
|
11
|
+
</ul>
|
12
|
+
</div>
|
13
|
+
<% end %>
|
14
|
+
<% if @user.errors.any? %>
|
15
|
+
<div id="error_explanation">
|
16
|
+
<h2><%= t("errors.template.header", model: 'blog', count: @user.errors.count) %></h2>
|
17
|
+
<p><%= t("errors.template.body") %></p>
|
18
|
+
<ul>
|
19
|
+
<% @user.errors.full_messages.each do |message| %>
|
20
|
+
<li><%= message %></li>
|
21
|
+
<% end %>
|
22
|
+
</ul>
|
23
|
+
</div>
|
24
|
+
<% end %>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
|
1
28
|
<%= form_tag action: 'index' do %>
|
2
29
|
<div class='alert alert-info'>
|
3
30
|
<small><%= t('.welcome_to_your_blog_setup', publify: link_to('Publify', 'https://publify.github.io/')) %></small>
|
4
31
|
</div>
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
32
|
+
<%= fields model: this_blog do |form| %>
|
33
|
+
<div class='form-group'>
|
34
|
+
<%= form.text_field(:blog_name, class: 'form-control', placeholder: t('.blog_name')) %>
|
35
|
+
</div>
|
36
|
+
<% end %>
|
37
|
+
<%= fields model: @user do |form| %>
|
38
|
+
<div class='form-group'>
|
39
|
+
<%= form.text_field(:email, class: 'form-control', placeholder: t('.your_mail')) %>
|
40
|
+
</div>
|
41
|
+
<div class='form-group'>
|
42
|
+
<%= form.label :password, t('.password') %><br>
|
43
|
+
<%= form.password_field(:password, class: 'form-control') %>
|
44
|
+
</div>
|
45
|
+
<% end %>
|
15
46
|
|
16
|
-
<input type="submit" id="submit" class='btn btn-lg btn-success btn-block' value="<%= t('generic.save') %>"
|
47
|
+
<input type="submit" id="submit" class='btn btn-lg btn-success btn-block' value="<%= t('generic.save') %>">
|
17
48
|
<% end %>
|
data/db/seeds.rb
CHANGED
@@ -13,9 +13,9 @@
|
|
13
13
|
blog = Blog.first || Blog.create!
|
14
14
|
|
15
15
|
unless blog.sidebars.any?
|
16
|
-
PageSidebar.create!(active_position: 0, staged_position: 0,
|
17
|
-
TagSidebar.create!(active_position: 1,
|
18
|
-
ArchivesSidebar.create!(active_position: 2,
|
19
|
-
StaticSidebar.create!(active_position: 3,
|
20
|
-
MetaSidebar.create!(active_position: 4,
|
16
|
+
PageSidebar.create!(active_position: 0, staged_position: 0, blog: blog)
|
17
|
+
TagSidebar.create!(active_position: 1, blog: blog)
|
18
|
+
ArchivesSidebar.create!(active_position: 2, blog: blog)
|
19
|
+
StaticSidebar.create!(active_position: 3, blog: blog)
|
20
|
+
MetaSidebar.create!(active_position: 4, blog: blog)
|
21
21
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# FIXME: Replace with helpers and/or methods provided by Rails
|
4
|
+
module PublifyCore
|
5
|
+
module StringExt
|
6
|
+
ACCENTS = { %w(á à â ä ã Ã Ä Â À) => "a",
|
7
|
+
%w(é è ê ë Ë É È Ê) => "e",
|
8
|
+
%w(í ì î ï I Î Ì) => "i",
|
9
|
+
%w(ó ò ô ö õ Õ Ö Ô Ò) => "o",
|
10
|
+
["œ"] => "oe",
|
11
|
+
["ß"] => "ss",
|
12
|
+
%w(ú ù û ü U Û Ù) => "u",
|
13
|
+
%w(ç Ç) => "c" }.freeze
|
14
|
+
|
15
|
+
def to_permalink
|
16
|
+
string = self
|
17
|
+
ACCENTS.each do |key, value|
|
18
|
+
string = string.tr(key.join, value)
|
19
|
+
end
|
20
|
+
string = string.tr("'", "-")
|
21
|
+
string.gsub(/<[^>]*>/, "").to_url
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns a-string-with-dashes when passed 'a string with dashes'.
|
25
|
+
# All special chars are stripped in the process
|
26
|
+
def to_url
|
27
|
+
return if nil?
|
28
|
+
|
29
|
+
s = downcase.tr("\"'", "")
|
30
|
+
s = s.gsub(/\P{Word}/, " ")
|
31
|
+
s.strip.tr_s(" ", "-").tr(" ", "-").sub(/^$/, "-")
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_title(item, settings, params)
|
35
|
+
TitleBuilder.new(self).build(item, settings, params)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Strips any html markup from a string
|
39
|
+
TYPO_TAG_KEY = TYPO_ATTRIBUTE_KEY = /[\w:_-]+/.freeze
|
40
|
+
TYPO_ATTRIBUTE_VALUE = /(?:[A-Za-z0-9]+|(?:'[^']*?'|"[^"]*?"))/.freeze
|
41
|
+
TYPO_ATTRIBUTE = /(?:#{TYPO_ATTRIBUTE_KEY}(?:\s*=\s*#{TYPO_ATTRIBUTE_VALUE})?)/.freeze
|
42
|
+
TYPO_ATTRIBUTES = /(?:#{TYPO_ATTRIBUTE}(?:\s+#{TYPO_ATTRIBUTE})*)/.freeze
|
43
|
+
TAG =
|
44
|
+
%r{<[!/?\[]?(?:#{TYPO_TAG_KEY}|--)(?:\s+#{TYPO_ATTRIBUTES})?\s*(?:[!/?\]]+|--)?>}
|
45
|
+
.freeze
|
46
|
+
def strip_html
|
47
|
+
gsub(TAG, "").gsub(/\s+/, " ").strip
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
String.include PublifyCore::StringExt
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "text_filter_plugin"
|
4
|
+
require "commonmarker"
|
5
|
+
|
6
|
+
module PublifyCore::TextFilter
|
7
|
+
class Markdown < TextFilterPlugin::Markup
|
8
|
+
plugin_display_name "Markdown"
|
9
|
+
plugin_description "Markdown markup language from" \
|
10
|
+
' <a href="http://daringfireball.com/">Daring Fireball</a>'
|
11
|
+
|
12
|
+
def self.help_text
|
13
|
+
<<~TXT
|
14
|
+
[Markdown](http://daringfireball.net/projects/markdown/) is a simple
|
15
|
+
text-to-HTML converter that turns common text idioms into HTML. The
|
16
|
+
[full syntax](http://daringfireball.net/projects/markdown/syntax) is
|
17
|
+
available from the author's site, but here's a short summary:
|
18
|
+
|
19
|
+
* **Paragraphs**: Start a new paragraph by skipping a line.
|
20
|
+
* **Italics**: Put text in *italics* by enclosing it in either * or
|
21
|
+
_: `*italics*` turns into *italics*.
|
22
|
+
* **Bold**: Put text in **bold** by enclosing it in two *s:
|
23
|
+
`**bold**` turns into **bold**.
|
24
|
+
* **Pre-formatted text**: Enclosing a short block of text in
|
25
|
+
backquotes (`) displays it in a monospaced font and converts HTML
|
26
|
+
metacharacters so they display correctly. Example:
|
27
|
+
``<img src="foo"/>`` displays as `<img src="foo"/>`. Also,
|
28
|
+
any paragraph indented 4 or more spaces is treated as pre-formatted
|
29
|
+
text.
|
30
|
+
* **Block quotes**: Any paragraph (or line) that starts with a `>` is
|
31
|
+
treated as a blockquote.
|
32
|
+
* **Hyperlinks**: You can create links like this:
|
33
|
+
`[amazon's web site](http://www.amazon.com)`. That produces
|
34
|
+
"[amazon's web site](http://www.amazon.com)".
|
35
|
+
* **Lists**: You can create numbered or bulleted lists by ending a
|
36
|
+
paragraph with a colon (:), skipping a line, and then using asterisks
|
37
|
+
(*, for bullets) or numbers (for numbered lists). See the
|
38
|
+
[Markdown syntax page](http://daringfireball.net/projects/markdown/syntax)
|
39
|
+
for examples.
|
40
|
+
* **Raw HTML**: Markdown will pass raw HTML through unchanged, so you
|
41
|
+
can use HTML's syntax whenever Markdown doesn't provide a reasonable
|
42
|
+
alternative.
|
43
|
+
TXT
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.filtertext(text)
|
47
|
+
# FIXME: Workaround for <publify:foo> not being interpreted as an HTML tag.
|
48
|
+
escaped_macros = text.gsub(%r{(</?publify):}, '\1X')
|
49
|
+
html = CommonMarker.render_html(escaped_macros, :UNSAFE)
|
50
|
+
html.gsub(%r{(</?publify)X}, '\1:').strip
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "text_filter_plugin"
|
4
|
-
require "
|
4
|
+
require "publify_core/text_filter/markdown"
|
5
5
|
|
6
|
-
module
|
7
|
-
class MarkdownSmartquotes <
|
6
|
+
module PublifyCore::TextFilter
|
7
|
+
class MarkdownSmartquotes < PublifyCore::TextFilter::Markdown
|
8
8
|
plugin_display_name "Markdown with smart quotes"
|
9
9
|
plugin_description "Markdown markup language from" \
|
10
10
|
' <a href="http://daringfireball.com/">Daring Fireball</a>' \
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "text_filter_plugin"
|
4
|
+
|
5
|
+
module PublifyCore::TextFilter
|
6
|
+
class None < TextFilterPlugin::Markup
|
7
|
+
plugin_display_name "None"
|
8
|
+
plugin_description "Raw HTML only"
|
9
|
+
|
10
|
+
def self.filtertext(text)
|
11
|
+
text
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubypants"
|
4
|
+
|
5
|
+
module PublifyCore::TextFilter
|
6
|
+
class Smartypants < TextFilterPlugin::PostProcess
|
7
|
+
plugin_display_name "Smartypants"
|
8
|
+
plugin_description "Converts HTML to use typographically correct quotes and dashes"
|
9
|
+
|
10
|
+
def self.filtertext(text)
|
11
|
+
RubyPants.new(text).to_html
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "text_filter_plugin"
|
4
|
+
require "html/pipeline"
|
5
|
+
require "html/pipeline/hashtag/hashtag_filter"
|
6
|
+
|
7
|
+
module PublifyCore::TextFilter
|
8
|
+
class Twitterfilter < TextFilterPlugin::PostProcess
|
9
|
+
plugin_display_name "Twitter Filter"
|
10
|
+
plugin_description "Convert hashtags and mentions to links"
|
11
|
+
|
12
|
+
class TwitterHashtagFilter < HTML::Pipeline::HashtagFilter
|
13
|
+
def initialize(text)
|
14
|
+
super(text,
|
15
|
+
tag_url: "https://twitter.com/search?q=%%23%<tag>s&src=tren&mode=realtime",
|
16
|
+
tag_link_attr: "")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class TwitterMentionFilter < HTML::Pipeline::MentionFilter
|
21
|
+
def initialize(text)
|
22
|
+
super(text, base_url: "https://twitter.com")
|
23
|
+
end
|
24
|
+
|
25
|
+
# Override base mentions finder, treating @mention just like any other @foo.
|
26
|
+
def self.mentioned_logins_in(text, username_pattern = UsernamePattern)
|
27
|
+
text.gsub MentionPatterns[username_pattern] do |match|
|
28
|
+
login = Regexp.last_match(1)
|
29
|
+
yield match, login, false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Override base link creator, removing the class
|
34
|
+
def link_to_mentioned_user(login)
|
35
|
+
result[:mentioned_usernames] |= [login]
|
36
|
+
|
37
|
+
url = base_url.dup
|
38
|
+
url << "/" unless %r{[/~]\z}.match?(url)
|
39
|
+
|
40
|
+
"<a href='#{url << login}'>" \
|
41
|
+
"@#{login}" \
|
42
|
+
"</a>"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.filtertext(text)
|
47
|
+
# First, autolink
|
48
|
+
helper = PublifyCore::ContentTextHelpers.new
|
49
|
+
text = helper.auto_link(text)
|
50
|
+
|
51
|
+
text = TwitterHashtagFilter.new(text).call
|
52
|
+
TwitterMentionFilter.new(text).call.to_s
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/publify_core/version.rb
CHANGED
data/lib/publify_core.rb
CHANGED
@@ -8,6 +8,12 @@ require "publify_core/version"
|
|
8
8
|
require "publify_core/engine"
|
9
9
|
require "publify_core/lang"
|
10
10
|
require "publify_core/content_text_helpers"
|
11
|
+
require "publify_core/text_filter/none"
|
12
|
+
require "publify_core/text_filter/markdown"
|
13
|
+
require "publify_core/text_filter/markdown_smartquotes"
|
14
|
+
require "publify_core/text_filter/smartypants"
|
15
|
+
require "publify_core/text_filter/twitterfilter"
|
16
|
+
require "publify_core/string_ext"
|
11
17
|
|
12
18
|
require "carrierwave"
|
13
19
|
require "jquery-rails"
|
@@ -20,17 +26,11 @@ require "sassc-rails"
|
|
20
26
|
|
21
27
|
require "email_notify"
|
22
28
|
require "publify_guid"
|
23
|
-
require "publify_textfilter_none"
|
24
|
-
require "publify_textfilter_markdown"
|
25
|
-
require "publify_textfilter_markdown_smartquotes"
|
26
|
-
require "publify_textfilter_smartypants"
|
27
|
-
require "publify_textfilter_twitterfilter"
|
28
29
|
require "publify_time"
|
29
30
|
require "sidebar_registry"
|
30
31
|
require "spam_protection"
|
31
32
|
require "text_filter_plugin"
|
32
33
|
require "theme"
|
33
|
-
require "transforms"
|
34
34
|
|
35
35
|
module PublifyCore
|
36
36
|
Theme.register_themes File.join(Engine.root, "themes")
|
data/lib/text_filter_plugin.rb
CHANGED
@@ -13,10 +13,8 @@ class TextFilterPlugin
|
|
13
13
|
def self.inherited(sub)
|
14
14
|
super
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
@@filter_map[name] = sub
|
19
|
-
end
|
16
|
+
name = sub.short_name
|
17
|
+
@@filter_map[name] = sub
|
20
18
|
end
|
21
19
|
|
22
20
|
def self.filter_map
|
@@ -116,34 +114,40 @@ class TextFilterPlugin
|
|
116
114
|
def self.logger
|
117
115
|
@logger ||= ::Rails.logger || Logger.new($stdout)
|
118
116
|
end
|
117
|
+
|
118
|
+
def self.abstract_filter!
|
119
|
+
@@filter_map.delete short_name
|
120
|
+
end
|
119
121
|
end
|
120
122
|
|
121
123
|
class TextFilterPlugin::PostProcess < TextFilterPlugin
|
124
|
+
abstract_filter!
|
125
|
+
|
122
126
|
def self.filter_type
|
123
127
|
"postprocess"
|
124
128
|
end
|
125
129
|
end
|
126
130
|
|
127
|
-
|
131
|
+
module TextFilterPlugin::MacroMethods
|
128
132
|
# Utility function -- hand it a XML string like <a href="foo" title="bar">
|
129
133
|
# and it'll give you back { "href" => "foo", "title" => "bar" }
|
130
|
-
def
|
134
|
+
def attributes_parse(string)
|
131
135
|
attributes = {}
|
132
136
|
|
133
137
|
string.gsub(/([^ =]+="[^"]*")/) do |match|
|
134
|
-
key, value = match.split(
|
138
|
+
key, value = match.split("=", 2)
|
135
139
|
attributes[key] = value.delete('"')
|
136
140
|
end
|
137
141
|
|
138
142
|
string.gsub(/([^ =]+='[^']*')/) do |match|
|
139
|
-
key, value = match.split(
|
143
|
+
key, value = match.split("=", 2)
|
140
144
|
attributes[key] = value.delete("'")
|
141
145
|
end
|
142
146
|
|
143
147
|
attributes
|
144
148
|
end
|
145
149
|
|
146
|
-
def
|
150
|
+
def filtertext(text)
|
147
151
|
regex1 = %r{<publify:#{short_name}(?:[ \t][^>]*)?/>}
|
148
152
|
regex2 = %r{<publify:#{short_name}([ \t][^>]*)?>(.*?)</publify:#{short_name}>}m
|
149
153
|
|
@@ -157,19 +161,27 @@ class TextFilterPlugin::Macro < TextFilterPlugin
|
|
157
161
|
end
|
158
162
|
end
|
159
163
|
|
160
|
-
class TextFilterPlugin::MacroPre < TextFilterPlugin
|
164
|
+
class TextFilterPlugin::MacroPre < TextFilterPlugin
|
165
|
+
abstract_filter!
|
166
|
+
extend TextFilterPlugin::MacroMethods
|
167
|
+
|
161
168
|
def self.filter_type
|
162
169
|
"macropre"
|
163
170
|
end
|
164
171
|
end
|
165
172
|
|
166
|
-
class TextFilterPlugin::MacroPost < TextFilterPlugin
|
173
|
+
class TextFilterPlugin::MacroPost < TextFilterPlugin
|
174
|
+
abstract_filter!
|
175
|
+
extend TextFilterPlugin::MacroMethods
|
176
|
+
|
167
177
|
def self.filter_type
|
168
178
|
"macropost"
|
169
179
|
end
|
170
180
|
end
|
171
181
|
|
172
182
|
class TextFilterPlugin::Markup < TextFilterPlugin
|
183
|
+
abstract_filter!
|
184
|
+
|
173
185
|
def self.filter_type
|
174
186
|
"markup"
|
175
187
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: publify_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 10.0.
|
4
|
+
version: 10.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matijs van Zuijlen
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2023-
|
14
|
+
date: 2023-10-28 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: aasm
|
@@ -61,14 +61,14 @@ dependencies:
|
|
61
61
|
requirements:
|
62
62
|
- - "~>"
|
63
63
|
- !ruby/object:Gem::Version
|
64
|
-
version:
|
64
|
+
version: '3.0'
|
65
65
|
type: :runtime
|
66
66
|
prerelease: false
|
67
67
|
version_requirements: !ruby/object:Gem::Requirement
|
68
68
|
requirements:
|
69
69
|
- - "~>"
|
70
70
|
- !ruby/object:Gem::Version
|
71
|
-
version:
|
71
|
+
version: '3.0'
|
72
72
|
- !ruby/object:Gem::Dependency
|
73
73
|
name: commonmarker
|
74
74
|
requirement: !ruby/object:Gem::Requirement
|
@@ -191,16 +191,22 @@ dependencies:
|
|
191
191
|
name: jquery-rails
|
192
192
|
requirement: !ruby/object:Gem::Requirement
|
193
193
|
requirements:
|
194
|
-
- - "
|
194
|
+
- - ">="
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: '4.5'
|
197
|
+
- - "<"
|
195
198
|
- !ruby/object:Gem::Version
|
196
|
-
version: 4.
|
199
|
+
version: '4.7'
|
197
200
|
type: :runtime
|
198
201
|
prerelease: false
|
199
202
|
version_requirements: !ruby/object:Gem::Requirement
|
200
203
|
requirements:
|
201
|
-
- - "
|
204
|
+
- - ">="
|
202
205
|
- !ruby/object:Gem::Version
|
203
|
-
version: 4.5
|
206
|
+
version: '4.5'
|
207
|
+
- - "<"
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
version: '4.7'
|
204
210
|
- !ruby/object:Gem::Dependency
|
205
211
|
name: jquery-ui-rails
|
206
212
|
requirement: !ruby/object:Gem::Requirement
|
@@ -539,70 +545,84 @@ dependencies:
|
|
539
545
|
requirements:
|
540
546
|
- - "~>"
|
541
547
|
- !ruby/object:Gem::Version
|
542
|
-
version: 1.
|
548
|
+
version: 1.57.1
|
549
|
+
type: :development
|
550
|
+
prerelease: false
|
551
|
+
version_requirements: !ruby/object:Gem::Requirement
|
552
|
+
requirements:
|
553
|
+
- - "~>"
|
554
|
+
- !ruby/object:Gem::Version
|
555
|
+
version: 1.57.1
|
556
|
+
- !ruby/object:Gem::Dependency
|
557
|
+
name: rubocop-capybara
|
558
|
+
requirement: !ruby/object:Gem::Requirement
|
559
|
+
requirements:
|
560
|
+
- - "~>"
|
561
|
+
- !ruby/object:Gem::Version
|
562
|
+
version: 2.19.0
|
543
563
|
type: :development
|
544
564
|
prerelease: false
|
545
565
|
version_requirements: !ruby/object:Gem::Requirement
|
546
566
|
requirements:
|
547
567
|
- - "~>"
|
548
568
|
- !ruby/object:Gem::Version
|
549
|
-
version:
|
569
|
+
version: 2.19.0
|
550
570
|
- !ruby/object:Gem::Dependency
|
551
571
|
name: rubocop-factory_bot
|
552
572
|
requirement: !ruby/object:Gem::Requirement
|
553
573
|
requirements:
|
554
574
|
- - "~>"
|
555
575
|
- !ruby/object:Gem::Version
|
556
|
-
version: 2.
|
576
|
+
version: 2.24.0
|
557
577
|
type: :development
|
558
578
|
prerelease: false
|
559
579
|
version_requirements: !ruby/object:Gem::Requirement
|
560
580
|
requirements:
|
561
581
|
- - "~>"
|
562
582
|
- !ruby/object:Gem::Version
|
563
|
-
version: 2.
|
583
|
+
version: 2.24.0
|
564
584
|
- !ruby/object:Gem::Dependency
|
565
585
|
name: rubocop-performance
|
566
586
|
requirement: !ruby/object:Gem::Requirement
|
567
587
|
requirements:
|
568
588
|
- - "~>"
|
569
589
|
- !ruby/object:Gem::Version
|
570
|
-
version: 1.
|
590
|
+
version: 1.19.0
|
571
591
|
type: :development
|
572
592
|
prerelease: false
|
573
593
|
version_requirements: !ruby/object:Gem::Requirement
|
574
594
|
requirements:
|
575
595
|
- - "~>"
|
576
596
|
- !ruby/object:Gem::Version
|
577
|
-
version: 1.
|
597
|
+
version: 1.19.0
|
578
598
|
- !ruby/object:Gem::Dependency
|
579
599
|
name: rubocop-rails
|
580
600
|
requirement: !ruby/object:Gem::Requirement
|
581
601
|
requirements:
|
582
602
|
- - "~>"
|
583
603
|
- !ruby/object:Gem::Version
|
584
|
-
version: 2.
|
604
|
+
version: 2.21.1
|
585
605
|
type: :development
|
586
606
|
prerelease: false
|
587
607
|
version_requirements: !ruby/object:Gem::Requirement
|
588
608
|
requirements:
|
589
609
|
- - "~>"
|
590
610
|
- !ruby/object:Gem::Version
|
591
|
-
version: 2.
|
611
|
+
version: 2.21.1
|
592
612
|
- !ruby/object:Gem::Dependency
|
593
613
|
name: rubocop-rspec
|
594
614
|
requirement: !ruby/object:Gem::Requirement
|
595
615
|
requirements:
|
596
616
|
- - "~>"
|
597
617
|
- !ruby/object:Gem::Version
|
598
|
-
version: 2.
|
618
|
+
version: 2.24.1
|
599
619
|
type: :development
|
600
620
|
prerelease: false
|
601
621
|
version_requirements: !ruby/object:Gem::Requirement
|
602
622
|
requirements:
|
603
623
|
- - "~>"
|
604
624
|
- !ruby/object:Gem::Version
|
605
|
-
version: 2.
|
625
|
+
version: 2.24.1
|
606
626
|
- !ruby/object:Gem::Dependency
|
607
627
|
name: shoulda-matchers
|
608
628
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1103,6 +1123,7 @@ files:
|
|
1103
1123
|
- lib/publify_core/content_text_helpers.rb
|
1104
1124
|
- lib/publify_core/engine.rb
|
1105
1125
|
- lib/publify_core/lang.rb
|
1126
|
+
- lib/publify_core/string_ext.rb
|
1106
1127
|
- lib/publify_core/testing_support/dns_mock.rb
|
1107
1128
|
- lib/publify_core/testing_support/factories/articles.rb
|
1108
1129
|
- lib/publify_core/testing_support/factories/blogs.rb
|
@@ -1127,14 +1148,14 @@ files:
|
|
1127
1148
|
- lib/publify_core/testing_support/fixtures/testfile.png
|
1128
1149
|
- lib/publify_core/testing_support/fixtures/testfile.txt
|
1129
1150
|
- lib/publify_core/testing_support/upload_fixtures.rb
|
1151
|
+
- lib/publify_core/text_filter/markdown.rb
|
1152
|
+
- lib/publify_core/text_filter/markdown_smartquotes.rb
|
1153
|
+
- lib/publify_core/text_filter/none.rb
|
1154
|
+
- lib/publify_core/text_filter/smartypants.rb
|
1155
|
+
- lib/publify_core/text_filter/twitterfilter.rb
|
1130
1156
|
- lib/publify_core/version.rb
|
1131
1157
|
- lib/publify_guid.rb
|
1132
1158
|
- lib/publify_plugins.rb
|
1133
|
-
- lib/publify_textfilter_markdown.rb
|
1134
|
-
- lib/publify_textfilter_markdown_smartquotes.rb
|
1135
|
-
- lib/publify_textfilter_none.rb
|
1136
|
-
- lib/publify_textfilter_smartypants.rb
|
1137
|
-
- lib/publify_textfilter_twitterfilter.rb
|
1138
1159
|
- lib/publify_time.rb
|
1139
1160
|
- lib/sidebar_field.rb
|
1140
1161
|
- lib/sidebar_registry.rb
|
@@ -1143,7 +1164,6 @@ files:
|
|
1143
1164
|
- lib/tasks/publify_core_tasks.rake
|
1144
1165
|
- lib/text_filter_plugin.rb
|
1145
1166
|
- lib/theme.rb
|
1146
|
-
- lib/transforms.rb
|
1147
1167
|
- themes/plain/about.markdown
|
1148
1168
|
- themes/plain/javascripts/theme.js
|
1149
1169
|
- themes/plain/preview.png
|
@@ -1168,7 +1188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1168
1188
|
- !ruby/object:Gem::Version
|
1169
1189
|
version: '0'
|
1170
1190
|
requirements: []
|
1171
|
-
rubygems_version: 3.4.
|
1191
|
+
rubygems_version: 3.4.20
|
1172
1192
|
signing_key:
|
1173
1193
|
specification_version: 4
|
1174
1194
|
summary: Core engine for the Publify blogging system.
|
@@ -1,56 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "text_filter_plugin"
|
4
|
-
require "commonmarker"
|
5
|
-
|
6
|
-
# TODO: Move to a different namespace
|
7
|
-
class PublifyApp
|
8
|
-
class Textfilter
|
9
|
-
class Markdown < TextFilterPlugin::Markup
|
10
|
-
plugin_display_name "Markdown"
|
11
|
-
plugin_description "Markdown markup language from" \
|
12
|
-
' <a href="http://daringfireball.com/">Daring Fireball</a>'
|
13
|
-
|
14
|
-
def self.help_text
|
15
|
-
<<~TXT
|
16
|
-
[Markdown](http://daringfireball.net/projects/markdown/) is a simple
|
17
|
-
text-to-HTML converter that turns common text idioms into HTML. The
|
18
|
-
[full syntax](http://daringfireball.net/projects/markdown/syntax) is
|
19
|
-
available from the author's site, but here's a short summary:
|
20
|
-
|
21
|
-
* **Paragraphs**: Start a new paragraph by skipping a line.
|
22
|
-
* **Italics**: Put text in *italics* by enclosing it in either * or
|
23
|
-
_: `*italics*` turns into *italics*.
|
24
|
-
* **Bold**: Put text in **bold** by enclosing it in two *s:
|
25
|
-
`**bold**` turns into **bold**.
|
26
|
-
* **Pre-formatted text**: Enclosing a short block of text in
|
27
|
-
backquotes (`) displays it in a monospaced font and converts HTML
|
28
|
-
metacharacters so they display correctly. Example:
|
29
|
-
``<img src="foo"/>`` displays as `<img src="foo"/>`. Also,
|
30
|
-
any paragraph indented 4 or more spaces is treated as pre-formatted
|
31
|
-
text.
|
32
|
-
* **Block quotes**: Any paragraph (or line) that starts with a `>` is
|
33
|
-
treated as a blockquote.
|
34
|
-
* **Hyperlinks**: You can create links like this:
|
35
|
-
`[amazon's web site](http://www.amazon.com)`. That produces
|
36
|
-
"[amazon's web site](http://www.amazon.com)".
|
37
|
-
* **Lists**: You can create numbered or bulleted lists by ending a
|
38
|
-
paragraph with a colon (:), skipping a line, and then using asterisks
|
39
|
-
(*, for bullets) or numbers (for numbered lists). See the
|
40
|
-
[Markdown syntax page](http://daringfireball.net/projects/markdown/syntax)
|
41
|
-
for examples.
|
42
|
-
* **Raw HTML**: Markdown will pass raw HTML through unchanged, so you
|
43
|
-
can use HTML's syntax whenever Markdown doesn't provide a reasonable
|
44
|
-
alternative.
|
45
|
-
TXT
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.filtertext(text)
|
49
|
-
# FIXME: Workaround for <publify:foo> not being interpreted as an HTML tag.
|
50
|
-
escaped_macros = text.gsub(%r{(</?publify):}, '\1X')
|
51
|
-
html = CommonMarker.render_html(escaped_macros, :UNSAFE)
|
52
|
-
html.gsub(%r{(</?publify)X}, '\1:').strip
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "text_filter_plugin"
|
4
|
-
|
5
|
-
class PublifyApp
|
6
|
-
class Textfilter
|
7
|
-
class None < TextFilterPlugin::Markup
|
8
|
-
plugin_display_name "None"
|
9
|
-
plugin_description "Raw HTML only"
|
10
|
-
|
11
|
-
def self.filtertext(text)
|
12
|
-
text
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "rubypants"
|
4
|
-
|
5
|
-
class PublifyApp
|
6
|
-
class Textfilter
|
7
|
-
class Smartypants < TextFilterPlugin::PostProcess
|
8
|
-
plugin_display_name "Smartypants"
|
9
|
-
plugin_description "Converts HTML to use typographically correct quotes and dashes"
|
10
|
-
|
11
|
-
def self.filtertext(text)
|
12
|
-
RubyPants.new(text).to_html
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "text_filter_plugin"
|
4
|
-
require "html/pipeline"
|
5
|
-
require "html/pipeline/hashtag/hashtag_filter"
|
6
|
-
|
7
|
-
class PublifyApp
|
8
|
-
class Textfilter
|
9
|
-
class Twitterfilter < TextFilterPlugin::PostProcess
|
10
|
-
plugin_display_name "HTML Filter"
|
11
|
-
plugin_description "Strip HTML tags"
|
12
|
-
|
13
|
-
class TwitterHashtagFilter < HTML::Pipeline::HashtagFilter
|
14
|
-
def initialize(text)
|
15
|
-
super(text,
|
16
|
-
tag_url: "https://twitter.com/search?q=%%23%<tag>s&src=tren&mode=realtime",
|
17
|
-
tag_link_attr: "")
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
class TwitterMentionFilter < HTML::Pipeline::MentionFilter
|
22
|
-
def initialize(text)
|
23
|
-
super(text, base_url: "https://twitter.com")
|
24
|
-
end
|
25
|
-
|
26
|
-
# Override base mentions finder, treating @mention just like any other @foo.
|
27
|
-
def self.mentioned_logins_in(text, username_pattern = UsernamePattern)
|
28
|
-
text.gsub MentionPatterns[username_pattern] do |match|
|
29
|
-
login = Regexp.last_match(1)
|
30
|
-
yield match, login, false
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# Override base link creator, removing the class
|
35
|
-
def link_to_mentioned_user(login)
|
36
|
-
result[:mentioned_usernames] |= [login]
|
37
|
-
|
38
|
-
url = base_url.dup
|
39
|
-
url << "/" unless %r{[/~]\z}.match?(url)
|
40
|
-
|
41
|
-
"<a href='#{url << login}'>" \
|
42
|
-
"@#{login}" \
|
43
|
-
"</a>"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.filtertext(text)
|
48
|
-
# First, autolink
|
49
|
-
helper = PublifyCore::ContentTextHelpers.new
|
50
|
-
text = helper.auto_link(text)
|
51
|
-
|
52
|
-
text = TwitterHashtagFilter.new(text).call
|
53
|
-
TwitterMentionFilter.new(text).call.to_s
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
data/lib/transforms.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# FIXME: Replace with helpers and/or methods provided by Rails
|
4
|
-
class String
|
5
|
-
ACCENTS = { %w(á à â ä ã Ã Ä Â À) => "a",
|
6
|
-
%w(é è ê ë Ë É È Ê) => "e",
|
7
|
-
%w(í ì î ï I Î Ì) => "i",
|
8
|
-
%w(ó ò ô ö õ Õ Ö Ô Ò) => "o",
|
9
|
-
["œ"] => "oe",
|
10
|
-
["ß"] => "ss",
|
11
|
-
%w(ú ù û ü U Û Ù) => "u",
|
12
|
-
%w(ç Ç) => "c" }.freeze
|
13
|
-
|
14
|
-
def to_permalink
|
15
|
-
string = self
|
16
|
-
ACCENTS.each do |key, value|
|
17
|
-
string = string.tr(key.join, value)
|
18
|
-
end
|
19
|
-
string = string.tr("'", "-")
|
20
|
-
string.gsub(/<[^>]*>/, "").to_url
|
21
|
-
end
|
22
|
-
|
23
|
-
# Returns a-string-with-dashes when passed 'a string with dashes'.
|
24
|
-
# All special chars are stripped in the process
|
25
|
-
def to_url
|
26
|
-
return if nil?
|
27
|
-
|
28
|
-
s = downcase.tr("\"'", "")
|
29
|
-
s = s.gsub(/\P{Word}/, " ")
|
30
|
-
s.strip.tr_s(" ", "-").tr(" ", "-").sub(/^$/, "-")
|
31
|
-
end
|
32
|
-
|
33
|
-
def to_title(item, settings, params)
|
34
|
-
TitleBuilder.new(self).build(item, settings, params)
|
35
|
-
end
|
36
|
-
|
37
|
-
# Strips any html markup from a string
|
38
|
-
TYPO_TAG_KEY = TYPO_ATTRIBUTE_KEY = /[\w:_-]+/.freeze
|
39
|
-
TYPO_ATTRIBUTE_VALUE = /(?:[A-Za-z0-9]+|(?:'[^']*?'|"[^"]*?"))/.freeze
|
40
|
-
TYPO_ATTRIBUTE = /(?:#{TYPO_ATTRIBUTE_KEY}(?:\s*=\s*#{TYPO_ATTRIBUTE_VALUE})?)/.freeze
|
41
|
-
TYPO_ATTRIBUTES = /(?:#{TYPO_ATTRIBUTE}(?:\s+#{TYPO_ATTRIBUTE})*)/.freeze
|
42
|
-
TAG =
|
43
|
-
%r{<[!/?\[]?(?:#{TYPO_TAG_KEY}|--)(?:\s+#{TYPO_ATTRIBUTES})?\s*(?:[!/?\]]+|--)?>}.freeze
|
44
|
-
def strip_html
|
45
|
-
gsub(TAG, "").gsub(/\s+/, " ").strip
|
46
|
-
end
|
47
|
-
end
|