auto_html 2.0.0 → 2.1.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.
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