auto_html 2.0.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4a15b23417dc35ee0ff8097c15b5eba4847142e2
4
- data.tar.gz: b94279092cc3fcb0f60affc58a733894e6f8993c
2
+ SHA256:
3
+ metadata.gz: 1c4554b35676a92a446754ad032d363e1f4be41613ae4923f376ddbb8229a334
4
+ data.tar.gz: 32062562a065326482d93d164caa849ff81029eb872ee66d973d435e528f99bb
5
5
  SHA512:
6
- metadata.gz: aef39b00d5a58cf5b32fcdeddd42f5c5c7691dbc506ff38b0f43784339bd55eeceed67f88aefa7badd8fc61c69b922970709f4a2a2661bd49fcb39dbd2d83fb6
7
- data.tar.gz: bf49c7aa022c56fbc3b3d58b7e27d83e447dfac562c33e8bcd0a308e7180edc8c2274e326a9a88d0b83559d89af6724a650dd91e475f93091d31472e83887e2d
6
+ metadata.gz: f22718875cce1764c67e795badf8dca2596697d22e9cd3b31d08b71a2abfe0d2b1c726eefee905b263ecf7352cb2e12c5a8aae4fbc1808e1169b45e2f350e3a2
7
+ data.tar.gz: ad11106a8df96b900a20df3a0665ec7b9227ba8a92a1728725381d540a11c8df41057dba72feeb9f22fefab82749336038d74c4bd6efa718d263da440eb82452
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # AutoHtml
2
2
 
3
- AutoHtml is a collection of filters that transform plain text into HTML code.
3
+ AutoHtml is a collection of filters that transforms plain text into HTML code. See [live demo](https://autohtml.rors.org).
4
4
 
5
5
  ## Installation
6
6
 
@@ -56,17 +56,39 @@ comment_format.call("Hello!\n\n Checkout out my blog: http://rors.org :point_lef
56
56
 
57
57
  Bellow is the list of bundled filters along with their optional arguments on initialization and their default values.
58
58
 
59
- * `AutoHtml::Emoji`, width: 20, height: 20, asset_root: '/images'
59
+ * `AutoHtml::Emoji`
60
60
  * `AutoHtml::HtmlEscape`
61
61
  * `AutoHtml::Image`, proxy: nil, alt: nil
62
62
  * `AutoHtml::Link`, target: nil, rel: nil
63
63
  * `AutoHtml::Markdown`
64
64
  * `AutoHtml::SimpleFormat`
65
65
 
66
- ## Code status
66
+ ## Using AutoHtml with ActiveRecord
67
67
 
68
- [![Circle CI](https://circleci.com/gh/dejan/auto_html.svg?style=svg&circle-token=57823c8b62302106564f97b58b64643b9760ed99)](https://circleci.com/gh/dejan/auto_html)
68
+ For performance reasons it's a good idea to store the formated output in the database, in a separate column, to avoid generating the same content on each access.
69
+ This can be acomplished simply by overriding the attribute writter:
70
+
71
+ ```ruby
72
+ class Comment < ActiveRecord::Base
73
+ FORMAT = AutoHtml::Pipeline.new(
74
+ AutoHtml::HtmlEscape.new,
75
+ AutoHtml::Markdown.new
76
+ )
77
+
78
+ def text=(t)
79
+ super(t)
80
+ self[:text_html] = FORMAT.call(t)
81
+ end
82
+ end
83
+ ```
84
+
85
+ Now, every time `text` attribute is set, `text_html` will be set as well:
86
+
87
+ ```Ruby
88
+ comment = Comment.new(text: 'Hey!')
89
+ comment.text_html # => '<p>Hey!</p>'
90
+ ```
69
91
 
70
92
  ## Licence
71
93
 
72
- AutoHtml is released under the [MIT License](https://raw.githubusercontent.com/dejan/auto_html/master/MIT-LICENCE).
94
+ AutoHtml is released under the [MIT License](https://raw.githubusercontent.com/dejan/auto_html/master/MIT-LICENSE).
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rspec/core/rake_task'
3
5
  require 'rubocop/rake_task'
@@ -5,4 +7,4 @@ require 'rubocop/rake_task'
5
7
  RSpec::Core::RakeTask.new(:spec)
6
8
  RuboCop::RakeTask.new
7
9
 
8
- task default: [:rubocop, :spec]
10
+ task default: %i[rubocop spec]
@@ -1,57 +1,24 @@
1
- require 'tag_helper'
1
+ # frozen_string_literal: true
2
+
2
3
  require 'gemoji'
3
4
 
4
5
  module AutoHtml
5
6
  # Emoji filter
6
7
  class Emoji
7
- def initialize(asset_root: '/images', width: 20, height: 20)
8
- @asset_root = asset_root
9
- @width = width
10
- @height = height
11
- end
12
-
13
8
  def call(text)
14
- text.gsub(emoji_pattern) do
9
+ text.gsub(self.class.emoji_pattern) do
15
10
  name = Regexp.last_match(1)
16
- alt = ":#{name}:"
17
- html_options = {
18
- src: emoji_url(name),
19
- class: 'emoji',
20
- title: alt,
21
- alt: alt,
22
- height: @width,
23
- witdh: @height,
24
- align: 'absmiddle'
25
- }
26
- TagHelper.tag(:img, html_options)
11
+ ::Emoji.find_by_alias(name).raw
27
12
  end
28
13
  end
29
14
 
30
- private
31
-
32
- def emoji_url(name)
33
- File.join(@asset_root, asset_path(name))
34
- end
35
-
36
- def asset_path(name)
37
- File.join('emoji', emoji_filename(name))
38
- end
39
-
40
15
  def self.emoji_pattern
41
16
  @emoji_pattern ||=
42
17
  /:(#{emoji_names.map { |name| Regexp.escape(name) }.join('|')}):/
43
18
  end
44
19
 
45
- def emoji_pattern
46
- self.class.emoji_pattern
47
- end
48
-
49
20
  def self.emoji_names
50
21
  ::Emoji.all.map(&:aliases).flatten.sort
51
22
  end
52
-
53
- def emoji_filename(name)
54
- ::Emoji.find_by_alias(name).image_filename
55
- end
56
23
  end
57
24
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cgi'
2
4
 
3
5
  module AutoHtml
@@ -1,4 +1,4 @@
1
- require 'tag_helper'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module AutoHtml
4
4
  # Image filter
@@ -17,7 +17,7 @@ module AutoHtml
17
17
  private
18
18
 
19
19
  def image_pattern
20
- %r{(?<!src=")https?:\/\/.+?\.(jpg|jpeg|bmp|gif|png)(\?\S+)?}i
20
+ %r{(?<!src=")https?://.+?\.(jpg|jpeg|bmp|gif|png|svg)(\?\S+)?}i
21
21
  end
22
22
  end
23
23
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uri'
2
4
  require 'rinku'
3
5
  require 'rexml/document'
@@ -5,19 +7,20 @@ require 'rexml/document'
5
7
  module AutoHtml
6
8
  # Link filter
7
9
  class Link
8
- def initialize(target: nil, rel: nil)
10
+ def initialize(target: nil, rel: nil, short_domains: false)
9
11
  @target = target
10
12
  @rel = rel
13
+ @short_domains = short_domains
11
14
  end
12
15
 
13
16
  def call(text)
14
- Rinku.auto_link(text, :all, target_attr)
17
+ Rinku.auto_link(text, :all, attributes, nil, flags)
15
18
  end
16
19
 
17
20
  private
18
21
 
19
22
  def attributes
20
- [target_attr, rel_attr].compact.join(' ')
23
+ [target_attr, rel_attr].compact.join(' ') unless [target_attr, rel_attr].compact.empty?
21
24
  end
22
25
 
23
26
  def rel_attr
@@ -27,5 +30,9 @@ module AutoHtml
27
30
  def target_attr
28
31
  %(target="#{@target}") if @target
29
32
  end
33
+
34
+ def flags
35
+ @short_domains ? Rinku::AUTOLINK_SHORT_DOMAINS : 0
36
+ end
30
37
  end
31
38
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'redcarpet'
2
4
 
3
5
  module AutoHtml
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AutoHtml
2
4
  # Applies collection of filters to a text
3
5
  class Pipeline
@@ -7,6 +9,7 @@ module AutoHtml
7
9
 
8
10
  def call(text)
9
11
  return '' if text.nil? || text.empty?
12
+
10
13
  @filters.inject(text) do |content, filter|
11
14
  filter.call(content)
12
15
  end
@@ -1,4 +1,4 @@
1
- require 'tag_helper'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module AutoHtml
4
4
  # SimpleFormat filter
@@ -14,6 +14,7 @@ module AutoHtml
14
14
 
15
15
  def split_paragraphs(text)
16
16
  return [] if text.nil? || text.empty?
17
+
17
18
  text.to_s.gsub(/\r\n?/, "\n").split(/\n\n+/).map! do |t|
18
19
  t.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') || t
19
20
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AutoHtml
4
+ # XHTML tags builder
5
+ module TagHelper
6
+ def tag(tag_name, attrs = {})
7
+ if block_given?
8
+ content_tag(tag_name, yield, attrs)
9
+ else
10
+ unary_tag(tag_name, attrs)
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def unary_tag(tag_name, attrs = {})
17
+ "<#{tag_and_attributes(tag_name, tag_attributes(attrs))} />"
18
+ end
19
+
20
+ def content_tag(tag_name, value, attrs = {})
21
+ start_tag = "<#{tag_and_attributes(tag_name, tag_attributes(attrs))}>"
22
+ end_tag = "</#{tag_name}>"
23
+ [start_tag, value, end_tag].join
24
+ end
25
+
26
+ def tag_and_attributes(tag_name, attributes)
27
+ attributes.empty? ? tag_name : "#{tag_name} #{attributes}"
28
+ end
29
+
30
+ def tag_attributes(hash)
31
+ hash.compact
32
+ .to_a
33
+ .map { |k, v| %(#{k}="#{v}") }.join(' ')
34
+ end
35
+
36
+ extend self
37
+ end
38
+ end
data/lib/auto_html.rb CHANGED
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # AutoHtml is a collection of filters that transform plain text into HTML code.
2
4
  module AutoHtml
3
5
  autoload :Pipeline, 'auto_html/pipeline'
4
-
6
+ autoload :TagHelper, 'auto_html/tag_helper'
5
7
  autoload :Emoji, 'auto_html/emoji'
6
8
  autoload :HtmlEscape, 'auto_html/html_escape'
7
9
  autoload :Image, 'auto_html/image'
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe AutoHtml::Emoji do
6
+ it 'converts emoji to HTML' do
7
+ expect(subject.call(':joy:')).to eq('😂')
8
+ end
9
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe AutoHtml::HtmlEscape do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe AutoHtml::Image do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe AutoHtml::Link do
@@ -31,9 +33,32 @@ RSpec.describe AutoHtml::Link do
31
33
  expect(result).to eq '<a href="http://www.google.com/#q=nikola+tesla&ct=tesla09&oi=ddle&fp=Xmf0jJ9P_V0">http://www.google.com/#q=nikola+tesla&ct=tesla09&oi=ddle&fp=Xmf0jJ9P_V0</a>'
32
34
  end
33
35
 
34
- it 'transforms with options' do
36
+ it 'not transforms short domain URL' do
37
+ result = subject.call('http://localhost:3000')
38
+ expect(result).to eq 'http://localhost:3000'
39
+ end
40
+
41
+ it 'transforms with target options' do
35
42
  filter = described_class.new(target: '_blank')
36
43
  result = filter.call('http://rors.org')
37
44
  expect(result).to eq '<a href="http://rors.org" target="_blank">http://rors.org</a>'
38
45
  end
46
+
47
+ it 'transforms with rel options' do
48
+ filter = described_class.new(rel: 'nofollow')
49
+ result = filter.call('http://rors.org')
50
+ expect(result).to eq '<a href="http://rors.org" rel="nofollow">http://rors.org</a>'
51
+ end
52
+
53
+ it 'transforms with short_domains options' do
54
+ filter = described_class.new(short_domains: true)
55
+ result = filter.call('http://localhost:3000')
56
+ expect(result).to eq '<a href="http://localhost:3000">http://localhost:3000</a>'
57
+ end
58
+
59
+ it 'transforms with target and rel options' do
60
+ filter = described_class.new(target: '_blank', rel: 'nofollow')
61
+ result = filter.call('http://rors.org')
62
+ expect(result).to eq '<a href="http://rors.org" target="_blank" rel="nofollow">http://rors.org</a>'
63
+ end
39
64
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe AutoHtml::Markdown do
4
6
  it 'formats input using simple GFM rules' do
5
- expect(subject.call '*hello*').to eq "<p><em>hello</em></p>\n"
7
+ expect(subject.call('*hello*')).to eq "<p><em>hello</em></p>\n"
6
8
  end
7
9
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe AutoHtml::Pipeline do
@@ -15,10 +17,10 @@ RSpec.describe AutoHtml::Pipeline do
15
17
  end
16
18
 
17
19
  it 'is blank if input is blank' do
18
- expect(subject.call '').to eq ''
20
+ expect(subject.call('')).to eq ''
19
21
  end
20
22
 
21
23
  it 'is blank if input is nil' do
22
- expect(subject.call nil).to eq ''
24
+ expect(subject.call(nil)).to eq ''
23
25
  end
24
26
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe AutoHtml::SimpleFormat do
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe AutoHtml::TagHelper do
6
+ it 'generates tag with attributes' do
7
+ result = subject.tag(:img, src: '1.png', alt: 'number one!')
8
+ expect(result).to eq '<img src="1.png" alt="number one!" />'
9
+ end
10
+
11
+ it 'generates tag without attributes' do
12
+ result = subject.tag(:br)
13
+ expect(result).to eq '<br />'
14
+ end
15
+
16
+ it 'generates content tags' do
17
+ result = subject.tag(:label, for: 'name') { 'Name' }
18
+ expect(result).to eq '<label for="name">Name</label>'
19
+ end
20
+
21
+ it 'generates content tags without attributes' do
22
+ result = subject.tag(:label) { 'Username' }
23
+ expect(result).to eq '<label>Username</label>'
24
+ end
25
+
26
+ it 'generates nested tags' do
27
+ result = subject.tag(:form) { subject.tag(:input, type: 'text') }
28
+ expect(result).to eq '<form><input type="text" /></form>'
29
+ end
30
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'auto_html'
2
4
 
3
5
  RSpec.configure do |config|
metadata CHANGED
@@ -1,85 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: auto_html
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dejan Simic
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-19 00:00:00.000000000 Z
11
+ date: 2022-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: tag_helper
14
+ name: gemoji
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.5'
19
+ version: 4.0.0.rc2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.5'
26
+ version: 4.0.0.rc2
27
27
  - !ruby/object:Gem::Dependency
28
- name: rinku
28
+ name: redcarpet
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.7'
33
+ version: '3.5'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.7'
40
+ version: '3.5'
41
41
  - !ruby/object:Gem::Dependency
42
- name: gemoji
42
+ name: rexml
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '2.1'
47
+ version: 3.2.5
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '2.1'
54
+ version: 3.2.5
55
55
  - !ruby/object:Gem::Dependency
56
- name: redcarpet
56
+ name: rinku
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '3.3'
61
+ version: '2.0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '3.3'
68
+ version: '2.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '10.4'
75
+ version: 13.0.6
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '10.4'
82
+ version: 13.0.6
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '0.33'
117
+ version: '1.23'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '0.33'
124
+ version: '1.23'
125
125
  description: Collection of filters for transforming text into HTML code
126
126
  email: desimic@gmail.com
127
127
  executables: []
@@ -138,19 +138,22 @@ files:
138
138
  - lib/auto_html/markdown.rb
139
139
  - lib/auto_html/pipeline.rb
140
140
  - lib/auto_html/simple_format.rb
141
- - spec/emoji_spec.rb
142
- - spec/html_escape_spec.rb
143
- - spec/image_spec.rb
144
- - spec/link_spec.rb
145
- - spec/markdown_spec.rb
146
- - spec/pipeline_spec.rb
147
- - spec/simple_format_spec.rb
141
+ - lib/auto_html/tag_helper.rb
142
+ - spec/auto_html/emoji_spec.rb
143
+ - spec/auto_html/html_escape_spec.rb
144
+ - spec/auto_html/image_spec.rb
145
+ - spec/auto_html/link_spec.rb
146
+ - spec/auto_html/markdown_spec.rb
147
+ - spec/auto_html/pipeline_spec.rb
148
+ - spec/auto_html/simple_format_spec.rb
149
+ - spec/auto_html/tag_helper_spec.rb
148
150
  - spec/spec_helper.rb
149
151
  homepage: https://github.com/dejan/auto_html
150
152
  licenses:
151
153
  - MIT
152
- metadata: {}
153
- post_install_message:
154
+ metadata:
155
+ rubygems_mfa_required: 'true'
156
+ post_install_message:
154
157
  rdoc_options: []
155
158
  require_paths:
156
159
  - lib
@@ -158,17 +161,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
158
161
  requirements:
159
162
  - - ">="
160
163
  - !ruby/object:Gem::Version
161
- version: '0'
164
+ version: 2.5.0
162
165
  required_rubygems_version: !ruby/object:Gem::Requirement
163
166
  requirements:
164
167
  - - ">="
165
168
  - !ruby/object:Gem::Version
166
169
  version: '0'
167
170
  requirements: []
168
- rubyforge_project:
169
- rubygems_version: 2.4.5
170
- signing_key:
171
+ rubygems_version: 3.2.3
172
+ signing_key:
171
173
  specification_version: 4
172
174
  summary: Plain text to HTML conversion
173
175
  test_files: []
174
- has_rdoc:
data/spec/emoji_spec.rb DELETED
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe AutoHtml::Emoji do
4
- it 'converts emoji to HTML' do
5
- expect(subject.call(':joy:')).to eq(
6
- '<img src="/images/emoji/unicode/1f602.png" class="emoji" title=":joy:" '\
7
- 'alt=":joy:" height="20" witdh="20" align="absmiddle" />')
8
- end
9
- end