twitter-text 2.0.2 → 2.1.0

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
2
  SHA256:
3
- metadata.gz: cce08cbad9e2bf18a22065095b1c21c6414e547596784225f8b6e6f4b507c8ff
4
- data.tar.gz: f06f63918fe569ef840d51ce7c7bbf34133605be5d4d6398afd7fcf65c3e31a2
3
+ metadata.gz: 3f7622cf10e3345995a426a4e371acef2e6eaa7344c430d9c5f944ba9f822d98
4
+ data.tar.gz: 1c70f9348e8a801f1df6eaeac98f98c7c2cca685354cc06181ac081acdcfd304
5
5
  SHA512:
6
- metadata.gz: f1ae97907d881a5c99cd5e2ad332a74c7f6e7b3e81eef07b69367b50415fd46745814771289fb9af1e6157698a2bd110cb5de3aa297be290ec36df107f29725c
7
- data.tar.gz: 6952cfab0c380d23e7b56c8e8bf56272b849982e28f01c8853c27c9803d3d7a610aa2b1f5c140a7ff2362aa2d035e1bb4e7da943bbdf576282495401372b2d93
6
+ metadata.gz: 5ab02e8044a6d8fd1c25dc70a53d5b981b37c3b5c1458d193c090e401a4822349c99463946827101d27ee4156bcf98597be54990026145c820dedecda1d9b675
7
+ data.tar.gz: b3163606bd143c4d13efbc1aab07cea05ad03d2e26f319c053662a758a44f990d132a3579fa5a0cc8f0023cdfdcf3584fb1bfe23d63c3636b276c02efdb38049
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ ## [Unreleased]
5
+
6
+ ## [2.1] - 2017-12-20
7
+ ### Added
8
+ - This CHANGELOG.md file
9
+
10
+ ### Changed
11
+ - Top-level namespace changed from `Twitter` to `Twitter::TwitterText`. This
12
+ resolves a namespace collision with the popular
13
+ [twitter gem](https://github.com/sferik/twitter). This is considered
14
+ a breaking change, so the version has been bumped to 2.1. This fixes
15
+ issue [#221](https://github.com/twitter/twitter-text/issues/221),
16
+ "NoMethodError Exception: undefined method `[]' for nil:NilClasswhen
17
+ using gem in rails app"
18
+
19
+ ## [2.0.2] - 2017-12-18
20
+ ### Changed
21
+ - Resolved issue
22
+ [#211](https://github.com/twitter/twitter-text/issues/211), "gem
23
+ breaks, asset file is a dangling symlink"
24
+ - config files, tld_lib.yml files now copied into the right place
25
+ - Rakefile now included `prebuild`, `clean` tasks
data/README.md CHANGED
@@ -50,7 +50,7 @@ def parse_tweet(text, options = {}) { ... }
50
50
 
51
51
  This method takes a string as input and returns a results object that
52
52
  contains information about the
53
- string. `Twitter::Validation::ParseResults` object includes:
53
+ string. `Twitter::TwitterText::Validation::ParseResults` object includes:
54
54
 
55
55
  * `:weighted_length`: the overall length of the tweet with code points
56
56
  weighted per the ranges defined in the configuration file.
@@ -78,7 +78,7 @@ payload see [Tweet updates](https://developer.twitter.com/en/docs/tweets/tweet-u
78
78
  # Extraction
79
79
  ```ruby
80
80
  class MyClass
81
- include Twitter::Extractor
81
+ include Twitter::TwitterText::Extractor
82
82
  usernames = extract_mentioned_screen_names("Mentioning @twitter and @jack")
83
83
  # usernames = ["twitter", "jack"]
84
84
  end
@@ -88,7 +88,7 @@ end
88
88
 
89
89
  ```ruby
90
90
  class MyClass
91
- include Twitter::Extractor
91
+ include Twitter::TwitterText::Extractor
92
92
  extract_reply_screen_name("@twitter are you hiring?").do |username|
93
93
  # username = "twitter"
94
94
  end
@@ -101,7 +101,7 @@ end
101
101
 
102
102
  ```ruby
103
103
  class MyClass
104
- include Twitter::Autolink
104
+ include Twitter::TwitterText::Autolink
105
105
 
106
106
  html = auto_link("link @user, please #request")
107
107
  end
@@ -110,7 +110,7 @@ end
110
110
  ### For Ruby on Rails you want to add this to app/helpers/application_helper.rb
111
111
  ```ruby
112
112
  module ApplicationHelper
113
- include Twitter::Autolink
113
+ include Twitter::TwitterText::Autolink
114
114
  end
115
115
  ```
116
116
 
@@ -4,445 +4,446 @@ require 'set'
4
4
  require 'twitter-text/hash_helper'
5
5
 
6
6
  module Twitter
7
- # A module for including Tweet auto-linking in a class. The primary use of this is for helpers/views so they can auto-link
8
- # usernames, lists, hashtags and URLs.
9
- module Autolink extend self
10
- # Default CSS class for auto-linked lists
11
- DEFAULT_LIST_CLASS = "tweet-url list-slug".freeze
12
- # Default CSS class for auto-linked usernames
13
- DEFAULT_USERNAME_CLASS = "tweet-url username".freeze
14
- # Default CSS class for auto-linked hashtags
15
- DEFAULT_HASHTAG_CLASS = "tweet-url hashtag".freeze
16
- # Default CSS class for auto-linked cashtags
17
- DEFAULT_CASHTAG_CLASS = "tweet-url cashtag".freeze
18
-
19
- # Default URL base for auto-linked usernames
20
- DEFAULT_USERNAME_URL_BASE = "https://twitter.com/".freeze
21
- # Default URL base for auto-linked lists
22
- DEFAULT_LIST_URL_BASE = "https://twitter.com/".freeze
23
- # Default URL base for auto-linked hashtags
24
- DEFAULT_HASHTAG_URL_BASE = "https://twitter.com/search?q=%23".freeze
25
- # Default URL base for auto-linked cashtags
26
- DEFAULT_CASHTAG_URL_BASE = "https://twitter.com/search?q=%24".freeze
27
-
28
- # Default attributes for invisible span tag
29
- DEFAULT_INVISIBLE_TAG_ATTRS = "style='position:absolute;left:-9999px;'".freeze
30
-
31
- DEFAULT_OPTIONS = {
32
- :list_class => DEFAULT_LIST_CLASS,
33
- :username_class => DEFAULT_USERNAME_CLASS,
34
- :hashtag_class => DEFAULT_HASHTAG_CLASS,
35
- :cashtag_class => DEFAULT_CASHTAG_CLASS,
36
-
37
- :username_url_base => DEFAULT_USERNAME_URL_BASE,
38
- :list_url_base => DEFAULT_LIST_URL_BASE,
39
- :hashtag_url_base => DEFAULT_HASHTAG_URL_BASE,
40
- :cashtag_url_base => DEFAULT_CASHTAG_URL_BASE,
41
-
42
- :invisible_tag_attrs => DEFAULT_INVISIBLE_TAG_ATTRS
43
- }.freeze
44
-
45
- def auto_link_with_json(text, json, options = {})
46
- # concatenate entities
47
- entities = json.values().flatten()
48
-
49
- # map JSON entity to twitter-text entity
50
- # be careful not to alter arguments received
51
- entities.map! do |entity|
52
- entity = HashHelper.symbolize_keys(entity)
53
- # hashtag
54
- entity[:hashtag] = entity[:text] if entity[:text]
55
- entity
56
- end
7
+ module TwitterText
8
+ # A module for including Tweet auto-linking in a class. The primary use of this is for helpers/views so they can auto-link
9
+ # usernames, lists, hashtags and URLs.
10
+ module Autolink extend self
11
+ # Default CSS class for auto-linked lists
12
+ DEFAULT_LIST_CLASS = "tweet-url list-slug".freeze
13
+ # Default CSS class for auto-linked usernames
14
+ DEFAULT_USERNAME_CLASS = "tweet-url username".freeze
15
+ # Default CSS class for auto-linked hashtags
16
+ DEFAULT_HASHTAG_CLASS = "tweet-url hashtag".freeze
17
+ # Default CSS class for auto-linked cashtags
18
+ DEFAULT_CASHTAG_CLASS = "tweet-url cashtag".freeze
19
+
20
+ # Default URL base for auto-linked usernames
21
+ DEFAULT_USERNAME_URL_BASE = "https://twitter.com/".freeze
22
+ # Default URL base for auto-linked lists
23
+ DEFAULT_LIST_URL_BASE = "https://twitter.com/".freeze
24
+ # Default URL base for auto-linked hashtags
25
+ DEFAULT_HASHTAG_URL_BASE = "https://twitter.com/search?q=%23".freeze
26
+ # Default URL base for auto-linked cashtags
27
+ DEFAULT_CASHTAG_URL_BASE = "https://twitter.com/search?q=%24".freeze
28
+
29
+ # Default attributes for invisible span tag
30
+ DEFAULT_INVISIBLE_TAG_ATTRS = "style='position:absolute;left:-9999px;'".freeze
31
+
32
+ DEFAULT_OPTIONS = {
33
+ :list_class => DEFAULT_LIST_CLASS,
34
+ :username_class => DEFAULT_USERNAME_CLASS,
35
+ :hashtag_class => DEFAULT_HASHTAG_CLASS,
36
+ :cashtag_class => DEFAULT_CASHTAG_CLASS,
37
+
38
+ :username_url_base => DEFAULT_USERNAME_URL_BASE,
39
+ :list_url_base => DEFAULT_LIST_URL_BASE,
40
+ :hashtag_url_base => DEFAULT_HASHTAG_URL_BASE,
41
+ :cashtag_url_base => DEFAULT_CASHTAG_URL_BASE,
42
+
43
+ :invisible_tag_attrs => DEFAULT_INVISIBLE_TAG_ATTRS
44
+ }.freeze
45
+
46
+ def auto_link_with_json(text, json, options = {})
47
+ # concatenate entities
48
+ entities = json.values().flatten()
49
+
50
+ # map JSON entity to twitter-text entity
51
+ # be careful not to alter arguments received
52
+ entities.map! do |entity|
53
+ entity = HashHelper.symbolize_keys(entity)
54
+ # hashtag
55
+ entity[:hashtag] = entity[:text] if entity[:text]
56
+ entity
57
+ end
57
58
 
58
- auto_link_entities(text, entities, options)
59
- end
59
+ auto_link_entities(text, entities, options)
60
+ end
60
61
 
61
- def auto_link_entities(text, entities, options = {}, &block)
62
- return text if entities.empty?
63
-
64
- # NOTE deprecate these attributes not options keys in options hash, then use html_attrs
65
- options = DEFAULT_OPTIONS.merge(options)
66
- options[:html_attrs] = extract_html_attrs_from_options!(options)
67
- options[:html_attrs][:rel] ||= "nofollow" unless options[:suppress_no_follow]
68
- options[:html_attrs][:target] = "_blank" if options[:target_blank] == true
69
-
70
- Twitter::Rewriter.rewrite_entities(text.dup, entities) do |entity, chars|
71
- if entity[:url]
72
- link_to_url(entity, chars, options, &block)
73
- elsif entity[:hashtag]
74
- link_to_hashtag(entity, chars, options, &block)
75
- elsif entity[:screen_name]
76
- link_to_screen_name(entity, chars, options, &block)
77
- elsif entity[:cashtag]
78
- link_to_cashtag(entity, chars, options, &block)
62
+ def auto_link_entities(text, entities, options = {}, &block)
63
+ return text if entities.empty?
64
+
65
+ # NOTE deprecate these attributes not options keys in options hash, then use html_attrs
66
+ options = DEFAULT_OPTIONS.merge(options)
67
+ options[:html_attrs] = extract_html_attrs_from_options!(options)
68
+ options[:html_attrs][:rel] ||= "nofollow" unless options[:suppress_no_follow]
69
+ options[:html_attrs][:target] = "_blank" if options[:target_blank] == true
70
+
71
+ Twitter::TwitterText::Rewriter.rewrite_entities(text.dup, entities) do |entity, chars|
72
+ if entity[:url]
73
+ link_to_url(entity, chars, options, &block)
74
+ elsif entity[:hashtag]
75
+ link_to_hashtag(entity, chars, options, &block)
76
+ elsif entity[:screen_name]
77
+ link_to_screen_name(entity, chars, options, &block)
78
+ elsif entity[:cashtag]
79
+ link_to_cashtag(entity, chars, options, &block)
80
+ end
79
81
  end
80
82
  end
81
- end
82
83
 
83
- # Add <tt><a></a></tt> tags around the usernames, lists, hashtags and URLs in the provided <tt>text</tt>.
84
- # The <tt><a></tt> tags can be controlled with the following entries in the <tt>options</tt> hash:
85
- # Also any elements in the <tt>options</tt> hash will be converted to HTML attributes
86
- # and place in the <tt><a></tt> tag.
87
- #
88
- # <tt>:url_class</tt>:: class to add to url <tt><a></tt> tags
89
- # <tt>:list_class</tt>:: class to add to list <tt><a></tt> tags
90
- # <tt>:username_class</tt>:: class to add to username <tt><a></tt> tags
91
- # <tt>:hashtag_class</tt>:: class to add to hashtag <tt><a></tt> tags
92
- # <tt>:cashtag_class</tt>:: class to add to cashtag <tt><a></tt> tags
93
- # <tt>:username_url_base</tt>:: the value for <tt>href</tt> attribute on username links. The <tt>@username</tt> (minus the <tt>@</tt>) will be appended at the end of this.
94
- # <tt>:list_url_base</tt>:: the value for <tt>href</tt> attribute on list links. The <tt>@username/list</tt> (minus the <tt>@</tt>) will be appended at the end of this.
95
- # <tt>:hashtag_url_base</tt>:: the value for <tt>href</tt> attribute on hashtag links. The <tt>#hashtag</tt> (minus the <tt>#</tt>) will be appended at the end of this.
96
- # <tt>:cashtag_url_base</tt>:: the value for <tt>href</tt> attribute on cashtag links. The <tt>$cashtag</tt> (minus the <tt>$</tt>) will be appended at the end of this.
97
- # <tt>:invisible_tag_attrs</tt>:: HTML attribute to add to invisible span tags
98
- # <tt>:username_include_symbol</tt>:: place the <tt>@</tt> symbol within username and list links
99
- # <tt>:suppress_lists</tt>:: disable auto-linking to lists
100
- # <tt>:suppress_no_follow</tt>:: do not add <tt>rel="nofollow"</tt> to auto-linked items
101
- # <tt>:symbol_tag</tt>:: tag to apply around symbol (@, #, $) in username / hashtag / cashtag links
102
- # <tt>:text_with_symbol_tag</tt>:: tag to apply around text part in username / hashtag / cashtag links
103
- # <tt>:url_target</tt>:: the value for <tt>target</tt> attribute on URL links.
104
- # <tt>:target_blank</tt>:: adds <tt>target="_blank"</tt> to all auto_linked items username / hashtag / cashtag links / urls
105
- # <tt>:link_attribute_block</tt>:: function to modify the attributes of a link based on the entity. called with |entity, attributes| params, and should modify the attributes hash.
106
- # <tt>:link_text_block</tt>:: function to modify the text of a link based on the entity. called with |entity, text| params, and should return a modified text.
107
- def auto_link(text, options = {}, &block)
108
- auto_link_entities(text, Extractor.extract_entities_with_indices(text, :extract_url_without_protocol => false), options, &block)
109
- end
110
-
111
- # Add <tt><a></a></tt> tags around the usernames and lists in the provided <tt>text</tt>. The
112
- # <tt><a></tt> tags can be controlled with the following entries in the <tt>options</tt> hash.
113
- # Also any elements in the <tt>options</tt> hash will be converted to HTML attributes
114
- # and place in the <tt><a></tt> tag.
115
- #
116
- # <tt>:list_class</tt>:: class to add to list <tt><a></tt> tags
117
- # <tt>:username_class</tt>:: class to add to username <tt><a></tt> tags
118
- # <tt>:username_url_base</tt>:: the value for <tt>href</tt> attribute on username links. The <tt>@username</tt> (minus the <tt>@</tt>) will be appended at the end of this.
119
- # <tt>:list_url_base</tt>:: the value for <tt>href</tt> attribute on list links. The <tt>@username/list</tt> (minus the <tt>@</tt>) will be appended at the end of this.
120
- # <tt>:username_include_symbol</tt>:: place the <tt>@</tt> symbol within username and list links
121
- # <tt>:suppress_lists</tt>:: disable auto-linking to lists
122
- # <tt>:suppress_no_follow</tt>:: do not add <tt>rel="nofollow"</tt> to auto-linked items
123
- # <tt>:symbol_tag</tt>:: tag to apply around symbol (@, #, $) in username / hashtag / cashtag links
124
- # <tt>:text_with_symbol_tag</tt>:: tag to apply around text part in username / hashtag / cashtag links
125
- # <tt>:link_attribute_block</tt>:: function to modify the attributes of a link based on the entity. called with |entity, attributes| params, and should modify the attributes hash.
126
- # <tt>:link_text_block</tt>:: function to modify the text of a link based on the entity. called with |entity, text| params, and should return a modified text.
127
- def auto_link_usernames_or_lists(text, options = {}, &block) # :yields: list_or_username
128
- auto_link_entities(text, Extractor.extract_mentions_or_lists_with_indices(text), options, &block)
129
- end
84
+ # Add <tt><a></a></tt> tags around the usernames, lists, hashtags and URLs in the provided <tt>text</tt>.
85
+ # The <tt><a></tt> tags can be controlled with the following entries in the <tt>options</tt> hash:
86
+ # Also any elements in the <tt>options</tt> hash will be converted to HTML attributes
87
+ # and place in the <tt><a></tt> tag.
88
+ #
89
+ # <tt>:url_class</tt>:: class to add to url <tt><a></tt> tags
90
+ # <tt>:list_class</tt>:: class to add to list <tt><a></tt> tags
91
+ # <tt>:username_class</tt>:: class to add to username <tt><a></tt> tags
92
+ # <tt>:hashtag_class</tt>:: class to add to hashtag <tt><a></tt> tags
93
+ # <tt>:cashtag_class</tt>:: class to add to cashtag <tt><a></tt> tags
94
+ # <tt>:username_url_base</tt>:: the value for <tt>href</tt> attribute on username links. The <tt>@username</tt> (minus the <tt>@</tt>) will be appended at the end of this.
95
+ # <tt>:list_url_base</tt>:: the value for <tt>href</tt> attribute on list links. The <tt>@username/list</tt> (minus the <tt>@</tt>) will be appended at the end of this.
96
+ # <tt>:hashtag_url_base</tt>:: the value for <tt>href</tt> attribute on hashtag links. The <tt>#hashtag</tt> (minus the <tt>#</tt>) will be appended at the end of this.
97
+ # <tt>:cashtag_url_base</tt>:: the value for <tt>href</tt> attribute on cashtag links. The <tt>$cashtag</tt> (minus the <tt>$</tt>) will be appended at the end of this.
98
+ # <tt>:invisible_tag_attrs</tt>:: HTML attribute to add to invisible span tags
99
+ # <tt>:username_include_symbol</tt>:: place the <tt>@</tt> symbol within username and list links
100
+ # <tt>:suppress_lists</tt>:: disable auto-linking to lists
101
+ # <tt>:suppress_no_follow</tt>:: do not add <tt>rel="nofollow"</tt> to auto-linked items
102
+ # <tt>:symbol_tag</tt>:: tag to apply around symbol (@, #, $) in username / hashtag / cashtag links
103
+ # <tt>:text_with_symbol_tag</tt>:: tag to apply around text part in username / hashtag / cashtag links
104
+ # <tt>:url_target</tt>:: the value for <tt>target</tt> attribute on URL links.
105
+ # <tt>:target_blank</tt>:: adds <tt>target="_blank"</tt> to all auto_linked items username / hashtag / cashtag links / urls
106
+ # <tt>:link_attribute_block</tt>:: function to modify the attributes of a link based on the entity. called with |entity, attributes| params, and should modify the attributes hash.
107
+ # <tt>:link_text_block</tt>:: function to modify the text of a link based on the entity. called with |entity, text| params, and should return a modified text.
108
+ def auto_link(text, options = {}, &block)
109
+ auto_link_entities(text, Extractor.extract_entities_with_indices(text, :extract_url_without_protocol => false), options, &block)
110
+ end
130
111
 
131
- # Add <tt><a></a></tt> tags around the hashtags in the provided <tt>text</tt>.
132
- # The <tt><a></tt> tags can be controlled with the following entries in the <tt>options</tt> hash.
133
- # Also any elements in the <tt>options</tt> hash will be converted to HTML attributes
134
- # and place in the <tt><a></tt> tag.
135
- #
136
- # <tt>:hashtag_class</tt>:: class to add to hashtag <tt><a></tt> tags
137
- # <tt>:hashtag_url_base</tt>:: the value for <tt>href</tt> attribute. The hashtag text (minus the <tt>#</tt>) will be appended at the end of this.
138
- # <tt>:suppress_no_follow</tt>:: do not add <tt>rel="nofollow"</tt> to auto-linked items
139
- # <tt>:symbol_tag</tt>:: tag to apply around symbol (@, #, $) in username / hashtag / cashtag links
140
- # <tt>:text_with_symbol_tag</tt>:: tag to apply around text part in username / hashtag / cashtag links
141
- # <tt>:link_attribute_block</tt>:: function to modify the attributes of a link based on the entity. called with |entity, attributes| params, and should modify the attributes hash.
142
- # <tt>:link_text_block</tt>:: function to modify the text of a link based on the entity. called with |entity, text| params, and should return a modified text.
143
- def auto_link_hashtags(text, options = {}, &block) # :yields: hashtag_text
144
- auto_link_entities(text, Extractor.extract_hashtags_with_indices(text), options, &block)
145
- end
112
+ # Add <tt><a></a></tt> tags around the usernames and lists in the provided <tt>text</tt>. The
113
+ # <tt><a></tt> tags can be controlled with the following entries in the <tt>options</tt> hash.
114
+ # Also any elements in the <tt>options</tt> hash will be converted to HTML attributes
115
+ # and place in the <tt><a></tt> tag.
116
+ #
117
+ # <tt>:list_class</tt>:: class to add to list <tt><a></tt> tags
118
+ # <tt>:username_class</tt>:: class to add to username <tt><a></tt> tags
119
+ # <tt>:username_url_base</tt>:: the value for <tt>href</tt> attribute on username links. The <tt>@username</tt> (minus the <tt>@</tt>) will be appended at the end of this.
120
+ # <tt>:list_url_base</tt>:: the value for <tt>href</tt> attribute on list links. The <tt>@username/list</tt> (minus the <tt>@</tt>) will be appended at the end of this.
121
+ # <tt>:username_include_symbol</tt>:: place the <tt>@</tt> symbol within username and list links
122
+ # <tt>:suppress_lists</tt>:: disable auto-linking to lists
123
+ # <tt>:suppress_no_follow</tt>:: do not add <tt>rel="nofollow"</tt> to auto-linked items
124
+ # <tt>:symbol_tag</tt>:: tag to apply around symbol (@, #, $) in username / hashtag / cashtag links
125
+ # <tt>:text_with_symbol_tag</tt>:: tag to apply around text part in username / hashtag / cashtag links
126
+ # <tt>:link_attribute_block</tt>:: function to modify the attributes of a link based on the entity. called with |entity, attributes| params, and should modify the attributes hash.
127
+ # <tt>:link_text_block</tt>:: function to modify the text of a link based on the entity. called with |entity, text| params, and should return a modified text.
128
+ def auto_link_usernames_or_lists(text, options = {}, &block) # :yields: list_or_username
129
+ auto_link_entities(text, Extractor.extract_mentions_or_lists_with_indices(text), options, &block)
130
+ end
146
131
 
147
- # Add <tt><a></a></tt> tags around the cashtags in the provided <tt>text</tt>.
148
- # The <tt><a></tt> tags can be controlled with the following entries in the <tt>options</tt> hash.
149
- # Also any elements in the <tt>options</tt> hash will be converted to HTML attributes
150
- # and place in the <tt><a></tt> tag.
151
- #
152
- # <tt>:cashtag_class</tt>:: class to add to cashtag <tt><a></tt> tags
153
- # <tt>:cashtag_url_base</tt>:: the value for <tt>href</tt> attribute. The cashtag text (minus the <tt>$</tt>) will be appended at the end of this.
154
- # <tt>:suppress_no_follow</tt>:: do not add <tt>rel="nofollow"</tt> to auto-linked items
155
- # <tt>:symbol_tag</tt>:: tag to apply around symbol (@, #, $) in username / hashtag / cashtag links
156
- # <tt>:text_with_symbol_tag</tt>:: tag to apply around text part in username / hashtag / cashtag links
157
- # <tt>:link_attribute_block</tt>:: function to modify the attributes of a link based on the entity. called with |entity, attributes| params, and should modify the attributes hash.
158
- # <tt>:link_text_block</tt>:: function to modify the text of a link based on the entity. called with |entity, text| params, and should return a modified text.
159
- def auto_link_cashtags(text, options = {}, &block) # :yields: cashtag_text
160
- auto_link_entities(text, Extractor.extract_cashtags_with_indices(text), options, &block)
161
- end
132
+ # Add <tt><a></a></tt> tags around the hashtags in the provided <tt>text</tt>.
133
+ # The <tt><a></tt> tags can be controlled with the following entries in the <tt>options</tt> hash.
134
+ # Also any elements in the <tt>options</tt> hash will be converted to HTML attributes
135
+ # and place in the <tt><a></tt> tag.
136
+ #
137
+ # <tt>:hashtag_class</tt>:: class to add to hashtag <tt><a></tt> tags
138
+ # <tt>:hashtag_url_base</tt>:: the value for <tt>href</tt> attribute. The hashtag text (minus the <tt>#</tt>) will be appended at the end of this.
139
+ # <tt>:suppress_no_follow</tt>:: do not add <tt>rel="nofollow"</tt> to auto-linked items
140
+ # <tt>:symbol_tag</tt>:: tag to apply around symbol (@, #, $) in username / hashtag / cashtag links
141
+ # <tt>:text_with_symbol_tag</tt>:: tag to apply around text part in username / hashtag / cashtag links
142
+ # <tt>:link_attribute_block</tt>:: function to modify the attributes of a link based on the entity. called with |entity, attributes| params, and should modify the attributes hash.
143
+ # <tt>:link_text_block</tt>:: function to modify the text of a link based on the entity. called with |entity, text| params, and should return a modified text.
144
+ def auto_link_hashtags(text, options = {}, &block) # :yields: hashtag_text
145
+ auto_link_entities(text, Extractor.extract_hashtags_with_indices(text), options, &block)
146
+ end
162
147
 
163
- # Add <tt><a></a></tt> tags around the URLs in the provided <tt>text</tt>.
164
- # The <tt><a></tt> tags can be controlled with the following entries in the <tt>options</tt> hash.
165
- # Also any elements in the <tt>options</tt> hash will be converted to HTML attributes
166
- # and place in the <tt><a></tt> tag.
167
- #
168
- # <tt>:url_class</tt>:: class to add to url <tt><a></tt> tags
169
- # <tt>:invisible_tag_attrs</tt>:: HTML attribute to add to invisible span tags
170
- # <tt>:suppress_no_follow</tt>:: do not add <tt>rel="nofollow"</tt> to auto-linked items
171
- # <tt>:symbol_tag</tt>:: tag to apply around symbol (@, #, $) in username / hashtag / cashtag links
172
- # <tt>:text_with_symbol_tag</tt>:: tag to apply around text part in username / hashtag / cashtag links
173
- # <tt>:url_target</tt>:: the value for <tt>target</tt> attribute on URL links.
174
- # <tt>:link_attribute_block</tt>:: function to modify the attributes of a link based on the entity. called with |entity, attributes| params, and should modify the attributes hash.
175
- # <tt>:link_text_block</tt>:: function to modify the text of a link based on the entity. called with |entity, text| params, and should return a modified text.
176
- def auto_link_urls(text, options = {}, &block)
177
- auto_link_entities(text, Extractor.extract_urls_with_indices(text, :extract_url_without_protocol => false), options, &block)
178
- end
148
+ # Add <tt><a></a></tt> tags around the cashtags in the provided <tt>text</tt>.
149
+ # The <tt><a></tt> tags can be controlled with the following entries in the <tt>options</tt> hash.
150
+ # Also any elements in the <tt>options</tt> hash will be converted to HTML attributes
151
+ # and place in the <tt><a></tt> tag.
152
+ #
153
+ # <tt>:cashtag_class</tt>:: class to add to cashtag <tt><a></tt> tags
154
+ # <tt>:cashtag_url_base</tt>:: the value for <tt>href</tt> attribute. The cashtag text (minus the <tt>$</tt>) will be appended at the end of this.
155
+ # <tt>:suppress_no_follow</tt>:: do not add <tt>rel="nofollow"</tt> to auto-linked items
156
+ # <tt>:symbol_tag</tt>:: tag to apply around symbol (@, #, $) in username / hashtag / cashtag links
157
+ # <tt>:text_with_symbol_tag</tt>:: tag to apply around text part in username / hashtag / cashtag links
158
+ # <tt>:link_attribute_block</tt>:: function to modify the attributes of a link based on the entity. called with |entity, attributes| params, and should modify the attributes hash.
159
+ # <tt>:link_text_block</tt>:: function to modify the text of a link based on the entity. called with |entity, text| params, and should return a modified text.
160
+ def auto_link_cashtags(text, options = {}, &block) # :yields: cashtag_text
161
+ auto_link_entities(text, Extractor.extract_cashtags_with_indices(text), options, &block)
162
+ end
179
163
 
180
- # These methods are deprecated, will be removed in future.
181
- extend Deprecation
182
-
183
- # <b>Deprecated</b>: Please use auto_link_urls instead.
184
- # Add <tt><a></a></tt> tags around the URLs in the provided <tt>text</tt>.
185
- # Any elements in the <tt>href_options</tt> hash will be converted to HTML attributes
186
- # and place in the <tt><a></tt> tag.
187
- # Unless <tt>href_options</tt> contains <tt>:suppress_no_follow</tt>
188
- # the <tt>rel="nofollow"</tt> attribute will be added.
189
- alias :auto_link_urls_custom :auto_link_urls
190
- deprecate :auto_link_urls_custom, :auto_link_urls
191
-
192
- private
193
-
194
- HTML_ENTITIES = {
195
- '&' => '&amp;',
196
- '>' => '&gt;',
197
- '<' => '&lt;',
198
- '"' => '&quot;',
199
- "'" => '&#39;'
200
- }
201
-
202
- def html_escape(text)
203
- text && text.to_s.gsub(/[&"'><]/) do |character|
204
- HTML_ENTITIES[character]
164
+ # Add <tt><a></a></tt> tags around the URLs in the provided <tt>text</tt>.
165
+ # The <tt><a></tt> tags can be controlled with the following entries in the <tt>options</tt> hash.
166
+ # Also any elements in the <tt>options</tt> hash will be converted to HTML attributes
167
+ # and place in the <tt><a></tt> tag.
168
+ #
169
+ # <tt>:url_class</tt>:: class to add to url <tt><a></tt> tags
170
+ # <tt>:invisible_tag_attrs</tt>:: HTML attribute to add to invisible span tags
171
+ # <tt>:suppress_no_follow</tt>:: do not add <tt>rel="nofollow"</tt> to auto-linked items
172
+ # <tt>:symbol_tag</tt>:: tag to apply around symbol (@, #, $) in username / hashtag / cashtag links
173
+ # <tt>:text_with_symbol_tag</tt>:: tag to apply around text part in username / hashtag / cashtag links
174
+ # <tt>:url_target</tt>:: the value for <tt>target</tt> attribute on URL links.
175
+ # <tt>:link_attribute_block</tt>:: function to modify the attributes of a link based on the entity. called with |entity, attributes| params, and should modify the attributes hash.
176
+ # <tt>:link_text_block</tt>:: function to modify the text of a link based on the entity. called with |entity, text| params, and should return a modified text.
177
+ def auto_link_urls(text, options = {}, &block)
178
+ auto_link_entities(text, Extractor.extract_urls_with_indices(text, :extract_url_without_protocol => false), options, &block)
205
179
  end
206
- end
207
180
 
208
- # NOTE We will make this private in future.
209
- public :html_escape
210
-
211
- # Options which should not be passed as HTML attributes
212
- OPTIONS_NOT_ATTRIBUTES = Set.new([
213
- :url_class, :list_class, :username_class, :hashtag_class, :cashtag_class,
214
- :username_url_base, :list_url_base, :hashtag_url_base, :cashtag_url_base,
215
- :username_url_block, :list_url_block, :hashtag_url_block, :cashtag_url_block, :link_url_block,
216
- :username_include_symbol, :suppress_lists, :suppress_no_follow, :url_entities,
217
- :invisible_tag_attrs, :symbol_tag, :text_with_symbol_tag, :url_target, :target_blank,
218
- :link_attribute_block, :link_text_block
219
- ]).freeze
220
-
221
- def extract_html_attrs_from_options!(options)
222
- html_attrs = {}
223
- options.reject! do |key, value|
224
- unless OPTIONS_NOT_ATTRIBUTES.include?(key)
225
- html_attrs[key] = value
226
- true
181
+ # These methods are deprecated, will be removed in future.
182
+ extend Deprecation
183
+
184
+ # <b>Deprecated</b>: Please use auto_link_urls instead.
185
+ # Add <tt><a></a></tt> tags around the URLs in the provided <tt>text</tt>.
186
+ # Any elements in the <tt>href_options</tt> hash will be converted to HTML attributes
187
+ # and place in the <tt><a></tt> tag.
188
+ # Unless <tt>href_options</tt> contains <tt>:suppress_no_follow</tt>
189
+ # the <tt>rel="nofollow"</tt> attribute will be added.
190
+ alias :auto_link_urls_custom :auto_link_urls
191
+ deprecate :auto_link_urls_custom, :auto_link_urls
192
+
193
+ private
194
+
195
+ HTML_ENTITIES = {
196
+ '&' => '&amp;',
197
+ '>' => '&gt;',
198
+ '<' => '&lt;',
199
+ '"' => '&quot;',
200
+ "'" => '&#39;'
201
+ }
202
+
203
+ def html_escape(text)
204
+ text && text.to_s.gsub(/[&"'><]/) do |character|
205
+ HTML_ENTITIES[character]
227
206
  end
228
207
  end
229
- html_attrs
230
- end
231
208
 
232
- def url_entities_hash(url_entities)
233
- (url_entities || {}).inject({}) do |entities, entity|
234
- # be careful not to alter arguments received
235
- _entity = HashHelper.symbolize_keys(entity)
236
- entities[_entity[:url]] = _entity
237
- entities
209
+ # NOTE We will make this private in future.
210
+ public :html_escape
211
+
212
+ # Options which should not be passed as HTML attributes
213
+ OPTIONS_NOT_ATTRIBUTES = Set.new([
214
+ :url_class, :list_class, :username_class, :hashtag_class, :cashtag_class,
215
+ :username_url_base, :list_url_base, :hashtag_url_base, :cashtag_url_base,
216
+ :username_url_block, :list_url_block, :hashtag_url_block, :cashtag_url_block, :link_url_block,
217
+ :username_include_symbol, :suppress_lists, :suppress_no_follow, :url_entities,
218
+ :invisible_tag_attrs, :symbol_tag, :text_with_symbol_tag, :url_target, :target_blank,
219
+ :link_attribute_block, :link_text_block
220
+ ]).freeze
221
+
222
+ def extract_html_attrs_from_options!(options)
223
+ html_attrs = {}
224
+ options.reject! do |key, value|
225
+ unless OPTIONS_NOT_ATTRIBUTES.include?(key)
226
+ html_attrs[key] = value
227
+ true
228
+ end
229
+ end
230
+ html_attrs
238
231
  end
239
- end
240
-
241
- def link_to_url(entity, chars, options = {})
242
- url = entity[:url]
243
232
 
244
- href = if options[:link_url_block]
245
- options[:link_url_block].call(url)
246
- else
247
- url
233
+ def url_entities_hash(url_entities)
234
+ (url_entities || {}).inject({}) do |entities, entity|
235
+ # be careful not to alter arguments received
236
+ _entity = HashHelper.symbolize_keys(entity)
237
+ entities[_entity[:url]] = _entity
238
+ entities
239
+ end
248
240
  end
249
241
 
250
- # NOTE auto link to urls do not use any default values and options
251
- # like url_class but use suppress_no_follow.
252
- html_attrs = options[:html_attrs].dup
253
- html_attrs[:class] = options[:url_class] if options.key?(:url_class)
242
+ def link_to_url(entity, chars, options = {})
243
+ url = entity[:url]
254
244
 
255
- # add target attribute only if :url_target is specified
256
- html_attrs[:target] = options[:url_target] if options.key?(:url_target)
245
+ href = if options[:link_url_block]
246
+ options[:link_url_block].call(url)
247
+ else
248
+ url
249
+ end
257
250
 
258
- url_entities = url_entities_hash(options[:url_entities])
251
+ # NOTE auto link to urls do not use any default values and options
252
+ # like url_class but use suppress_no_follow.
253
+ html_attrs = options[:html_attrs].dup
254
+ html_attrs[:class] = options[:url_class] if options.key?(:url_class)
259
255
 
260
- # use entity from urlEntities if available
261
- url_entity = url_entities[url] || entity
262
- link_text = if url_entity[:display_url]
263
- html_attrs[:title] ||= url_entity[:expanded_url]
264
- link_url_with_entity(url_entity, options)
265
- else
266
- html_escape(url)
267
- end
256
+ # add target attribute only if :url_target is specified
257
+ html_attrs[:target] = options[:url_target] if options.key?(:url_target)
268
258
 
269
- link_to_text(entity, link_text, href, html_attrs, options)
270
- end
259
+ url_entities = url_entities_hash(options[:url_entities])
271
260
 
272
- def link_url_with_entity(entity, options)
273
- display_url = entity[:display_url]
274
- expanded_url = entity[:expanded_url]
275
- invisible_tag_attrs = options[:invisible_tag_attrs] || DEFAULT_INVISIBLE_TAG_ATTRS
261
+ # use entity from urlEntities if available
262
+ url_entity = url_entities[url] || entity
263
+ link_text = if url_entity[:display_url]
264
+ html_attrs[:title] ||= url_entity[:expanded_url]
265
+ link_url_with_entity(url_entity, options)
266
+ else
267
+ html_escape(url)
268
+ end
276
269
 
277
- # Goal: If a user copies and pastes a tweet containing t.co'ed link, the resulting paste
278
- # should contain the full original URL (expanded_url), not the display URL.
279
- #
280
- # Method: Whenever possible, we actually emit HTML that contains expanded_url, and use
281
- # font-size:0 to hide those parts that should not be displayed (because they are not part of display_url).
282
- # Elements with font-size:0 get copied even though they are not visible.
283
- # Note that display:none doesn't work here. Elements with display:none don't get copied.
284
- #
285
- # Additionally, we want to *display* ellipses, but we don't want them copied. To make this happen we
286
- # wrap the ellipses in a tco-ellipsis class and provide an onCopy handler that sets display:none on
287
- # everything with the tco-ellipsis class.
288
- #
289
- # Exception: pic.twitter.com images, for which expandedUrl = "https://twitter.com/username/status/1234/photo/1
290
- # For those URLs, display_url is not a substring of expanded_url, so we don't do anything special to render the elided parts.
291
- # For a pic.twitter.com URL, the only elided part will be the "https://", so this is fine.
292
- display_url_sans_ellipses = display_url.gsub("…", "")
293
-
294
- if expanded_url.include?(display_url_sans_ellipses)
295
- before_display_url, after_display_url = expanded_url.split(display_url_sans_ellipses, 2)
296
- preceding_ellipsis = /\A…/.match(display_url).to_s
297
- following_ellipsis = /…\z/.match(display_url).to_s
298
-
299
- # As an example: The user tweets "hi http://longdomainname.com/foo"
300
- # This gets shortened to "hi http://t.co/xyzabc", with display_url = "…nname.com/foo"
301
- # This will get rendered as:
302
- # <span class='tco-ellipsis'> <!-- This stuff should get displayed but not copied -->
303
- # …
304
- # <!-- There's a chance the onCopy event handler might not fire. In case that happens,
305
- # we include an &nbsp; here so that the … doesn't bump up against the URL and ruin it.
306
- # The &nbsp; is inside the tco-ellipsis span so that when the onCopy handler *does*
307
- # fire, it doesn't get copied. Otherwise the copied text would have two spaces in a row,
308
- # e.g. "hi http://longdomainname.com/foo".
309
- # <span style='font-size:0'>&nbsp;</span>
310
- # </span>
311
- # <span style='font-size:0'> <!-- This stuff should get copied but not displayed -->
312
- # http://longdomai
313
- # </span>
314
- # <span class='js-display-url'> <!-- This stuff should get displayed *and* copied -->
315
- # nname.com/foo
316
- # </span>
317
- # <span class='tco-ellipsis'> <!-- This stuff should get displayed but not copied -->
318
- # <span style='font-size:0'>&nbsp;</span>
319
- # …
320
- # </span>
321
- %(<span class="tco-ellipsis">#{preceding_ellipsis}<span #{invisible_tag_attrs}>&nbsp;</span></span>) <<
322
- %(<span #{invisible_tag_attrs}>#{html_escape(before_display_url)}</span>) <<
323
- %(<span class="js-display-url">#{html_escape(display_url_sans_ellipses)}</span>) <<
324
- %(<span #{invisible_tag_attrs}>#{html_escape(after_display_url)}</span>) <<
325
- %(<span class="tco-ellipsis"><span #{invisible_tag_attrs}>&nbsp;</span>#{following_ellipsis}</span>)
326
- else
327
- html_escape(display_url)
270
+ link_to_text(entity, link_text, href, html_attrs, options)
328
271
  end
329
- end
330
272
 
331
- def link_to_hashtag(entity, chars, options = {})
332
- hash = chars[entity[:indices].first]
333
- hashtag = entity[:hashtag]
334
- hashtag = yield(hashtag) if block_given?
335
- hashtag_class = options[:hashtag_class].to_s
336
-
337
- if hashtag.match Twitter::Regex::REGEXEN[:rtl_chars]
338
- hashtag_class += ' rtl'
273
+ def link_url_with_entity(entity, options)
274
+ display_url = entity[:display_url]
275
+ expanded_url = entity[:expanded_url]
276
+ invisible_tag_attrs = options[:invisible_tag_attrs] || DEFAULT_INVISIBLE_TAG_ATTRS
277
+
278
+ # Goal: If a user copies and pastes a tweet containing t.co'ed link, the resulting paste
279
+ # should contain the full original URL (expanded_url), not the display URL.
280
+ #
281
+ # Method: Whenever possible, we actually emit HTML that contains expanded_url, and use
282
+ # font-size:0 to hide those parts that should not be displayed (because they are not part of display_url).
283
+ # Elements with font-size:0 get copied even though they are not visible.
284
+ # Note that display:none doesn't work here. Elements with display:none don't get copied.
285
+ #
286
+ # Additionally, we want to *display* ellipses, but we don't want them copied. To make this happen we
287
+ # wrap the ellipses in a tco-ellipsis class and provide an onCopy handler that sets display:none on
288
+ # everything with the tco-ellipsis class.
289
+ #
290
+ # Exception: pic.twitter.com images, for which expandedUrl = "https://twitter.com/username/status/1234/photo/1
291
+ # For those URLs, display_url is not a substring of expanded_url, so we don't do anything special to render the elided parts.
292
+ # For a pic.twitter.com URL, the only elided part will be the "https://", so this is fine.
293
+ display_url_sans_ellipses = display_url.gsub("…", "")
294
+
295
+ if expanded_url.include?(display_url_sans_ellipses)
296
+ before_display_url, after_display_url = expanded_url.split(display_url_sans_ellipses, 2)
297
+ preceding_ellipsis = /\A…/.match(display_url).to_s
298
+ following_ellipsis = /…\z/.match(display_url).to_s
299
+
300
+ # As an example: The user tweets "hi http://longdomainname.com/foo"
301
+ # This gets shortened to "hi http://t.co/xyzabc", with display_url = "…nname.com/foo"
302
+ # This will get rendered as:
303
+ # <span class='tco-ellipsis'> <!-- This stuff should get displayed but not copied -->
304
+ # …
305
+ # <!-- There's a chance the onCopy event handler might not fire. In case that happens,
306
+ # we include an &nbsp; here so that the … doesn't bump up against the URL and ruin it.
307
+ # The &nbsp; is inside the tco-ellipsis span so that when the onCopy handler *does*
308
+ # fire, it doesn't get copied. Otherwise the copied text would have two spaces in a row,
309
+ # e.g. "hi http://longdomainname.com/foo".
310
+ # <span style='font-size:0'>&nbsp;</span>
311
+ # </span>
312
+ # <span style='font-size:0'> <!-- This stuff should get copied but not displayed -->
313
+ # http://longdomai
314
+ # </span>
315
+ # <span class='js-display-url'> <!-- This stuff should get displayed *and* copied -->
316
+ # nname.com/foo
317
+ # </span>
318
+ # <span class='tco-ellipsis'> <!-- This stuff should get displayed but not copied -->
319
+ # <span style='font-size:0'>&nbsp;</span>
320
+ # …
321
+ # </span>
322
+ %(<span class="tco-ellipsis">#{preceding_ellipsis}<span #{invisible_tag_attrs}>&nbsp;</span></span>) <<
323
+ %(<span #{invisible_tag_attrs}>#{html_escape(before_display_url)}</span>) <<
324
+ %(<span class="js-display-url">#{html_escape(display_url_sans_ellipses)}</span>) <<
325
+ %(<span #{invisible_tag_attrs}>#{html_escape(after_display_url)}</span>) <<
326
+ %(<span class="tco-ellipsis"><span #{invisible_tag_attrs}>&nbsp;</span>#{following_ellipsis}</span>)
327
+ else
328
+ html_escape(display_url)
329
+ end
339
330
  end
340
331
 
341
- href = if options[:hashtag_url_block]
342
- options[:hashtag_url_block].call(hashtag)
343
- else
344
- "#{options[:hashtag_url_base]}#{hashtag}"
345
- end
332
+ def link_to_hashtag(entity, chars, options = {})
333
+ hash = chars[entity[:indices].first]
334
+ hashtag = entity[:hashtag]
335
+ hashtag = yield(hashtag) if block_given?
336
+ hashtag_class = options[:hashtag_class].to_s
346
337
 
347
- html_attrs = {
348
- :class => hashtag_class,
349
- # FIXME As our conformance test, hash in title should be half-width,
350
- # this should be bug of conformance data.
351
- :title => "##{hashtag}"
352
- }.merge(options[:html_attrs])
338
+ if hashtag.match Twitter::TwitterText::Regex::REGEXEN[:rtl_chars]
339
+ hashtag_class += ' rtl'
340
+ end
353
341
 
354
- link_to_text_with_symbol(entity, hash, hashtag, href, html_attrs, options)
355
- end
342
+ href = if options[:hashtag_url_block]
343
+ options[:hashtag_url_block].call(hashtag)
344
+ else
345
+ "#{options[:hashtag_url_base]}#{hashtag}"
346
+ end
356
347
 
357
- def link_to_cashtag(entity, chars, options = {})
358
- dollar = chars[entity[:indices].first]
359
- cashtag = entity[:cashtag]
360
- cashtag = yield(cashtag) if block_given?
348
+ html_attrs = {
349
+ :class => hashtag_class,
350
+ # FIXME As our conformance test, hash in title should be half-width,
351
+ # this should be bug of conformance data.
352
+ :title => "##{hashtag}"
353
+ }.merge(options[:html_attrs])
361
354
 
362
- href = if options[:cashtag_url_block]
363
- options[:cashtag_url_block].call(cashtag)
364
- else
365
- "#{options[:cashtag_url_base]}#{cashtag}"
355
+ link_to_text_with_symbol(entity, hash, hashtag, href, html_attrs, options)
366
356
  end
367
357
 
368
- html_attrs = {
369
- :class => "#{options[:cashtag_class]}",
370
- :title => "$#{cashtag}"
371
- }.merge(options[:html_attrs])
358
+ def link_to_cashtag(entity, chars, options = {})
359
+ dollar = chars[entity[:indices].first]
360
+ cashtag = entity[:cashtag]
361
+ cashtag = yield(cashtag) if block_given?
372
362
 
373
- link_to_text_with_symbol(entity, dollar, cashtag, href, html_attrs, options)
374
- end
363
+ href = if options[:cashtag_url_block]
364
+ options[:cashtag_url_block].call(cashtag)
365
+ else
366
+ "#{options[:cashtag_url_base]}#{cashtag}"
367
+ end
368
+
369
+ html_attrs = {
370
+ :class => "#{options[:cashtag_class]}",
371
+ :title => "$#{cashtag}"
372
+ }.merge(options[:html_attrs])
375
373
 
376
- def link_to_screen_name(entity, chars, options = {})
377
- name = "#{entity[:screen_name]}#{entity[:list_slug]}"
374
+ link_to_text_with_symbol(entity, dollar, cashtag, href, html_attrs, options)
375
+ end
378
376
 
379
- chunk = name.dup
380
- chunk = yield(chunk) if block_given?
377
+ def link_to_screen_name(entity, chars, options = {})
378
+ name = "#{entity[:screen_name]}#{entity[:list_slug]}"
381
379
 
382
- at = chars[entity[:indices].first]
380
+ chunk = name.dup
381
+ chunk = yield(chunk) if block_given?
383
382
 
384
- html_attrs = options[:html_attrs].dup
383
+ at = chars[entity[:indices].first]
385
384
 
386
- if entity[:list_slug] && !entity[:list_slug].empty? && !options[:suppress_lists]
387
- href = if options[:list_url_block]
388
- options[:list_url_block].call(name)
385
+ html_attrs = options[:html_attrs].dup
386
+
387
+ if entity[:list_slug] && !entity[:list_slug].empty? && !options[:suppress_lists]
388
+ href = if options[:list_url_block]
389
+ options[:list_url_block].call(name)
390
+ else
391
+ "#{options[:list_url_base]}#{name}"
392
+ end
393
+ html_attrs[:class] ||= "#{options[:list_class]}"
389
394
  else
390
- "#{options[:list_url_base]}#{name}"
395
+ href = if options[:username_url_block]
396
+ options[:username_url_block].call(chunk)
397
+ else
398
+ "#{options[:username_url_base]}#{name}"
399
+ end
400
+ html_attrs[:class] ||= "#{options[:username_class]}"
391
401
  end
392
- html_attrs[:class] ||= "#{options[:list_class]}"
393
- else
394
- href = if options[:username_url_block]
395
- options[:username_url_block].call(chunk)
402
+
403
+ link_to_text_with_symbol(entity, at, chunk, href, html_attrs, options)
404
+ end
405
+
406
+ def link_to_text_with_symbol(entity, symbol, text, href, attributes = {}, options = {})
407
+ tagged_symbol = options[:symbol_tag] ? "<#{options[:symbol_tag]}>#{symbol}</#{options[:symbol_tag]}>" : symbol
408
+ text = html_escape(text)
409
+ tagged_text = options[:text_with_symbol_tag] ? "<#{options[:text_with_symbol_tag]}>#{text}</#{options[:text_with_symbol_tag]}>" : text
410
+ if options[:username_include_symbol] || symbol !~ Twitter::TwitterText::Regex::REGEXEN[:at_signs]
411
+ "#{link_to_text(entity, tagged_symbol + tagged_text, href, attributes, options)}"
396
412
  else
397
- "#{options[:username_url_base]}#{name}"
413
+ "#{tagged_symbol}#{link_to_text(entity, tagged_text, href, attributes, options)}"
398
414
  end
399
- html_attrs[:class] ||= "#{options[:username_class]}"
400
415
  end
401
416
 
402
- link_to_text_with_symbol(entity, at, chunk, href, html_attrs, options)
403
- end
404
-
405
- def link_to_text_with_symbol(entity, symbol, text, href, attributes = {}, options = {})
406
- tagged_symbol = options[:symbol_tag] ? "<#{options[:symbol_tag]}>#{symbol}</#{options[:symbol_tag]}>" : symbol
407
- text = html_escape(text)
408
- tagged_text = options[:text_with_symbol_tag] ? "<#{options[:text_with_symbol_tag]}>#{text}</#{options[:text_with_symbol_tag]}>" : text
409
- if options[:username_include_symbol] || symbol !~ Twitter::Regex::REGEXEN[:at_signs]
410
- "#{link_to_text(entity, tagged_symbol + tagged_text, href, attributes, options)}"
411
- else
412
- "#{tagged_symbol}#{link_to_text(entity, tagged_text, href, attributes, options)}"
417
+ def link_to_text(entity, text, href, attributes = {}, options = {})
418
+ attributes[:href] = href
419
+ options[:link_attribute_block].call(entity, attributes) if options[:link_attribute_block]
420
+ text = options[:link_text_block].call(entity, text) if options[:link_text_block]
421
+ %(<a#{tag_attrs(attributes)}>#{text}</a>)
413
422
  end
414
- end
415
423
 
416
- def link_to_text(entity, text, href, attributes = {}, options = {})
417
- attributes[:href] = href
418
- options[:link_attribute_block].call(entity, attributes) if options[:link_attribute_block]
419
- text = options[:link_text_block].call(entity, text) if options[:link_text_block]
420
- %(<a#{tag_attrs(attributes)}>#{text}</a>)
421
- end
422
-
423
- BOOLEAN_ATTRIBUTES = Set.new([:disabled, :readonly, :multiple, :checked]).freeze
424
+ BOOLEAN_ATTRIBUTES = Set.new([:disabled, :readonly, :multiple, :checked]).freeze
424
425
 
425
- def tag_attrs(attributes)
426
- attributes.keys.sort_by{|k| k.to_s}.inject("") do |attrs, key|
427
- value = attributes[key]
426
+ def tag_attrs(attributes)
427
+ attributes.keys.sort_by{|k| k.to_s}.inject("") do |attrs, key|
428
+ value = attributes[key]
428
429
 
429
- if BOOLEAN_ATTRIBUTES.include?(key)
430
- value = value ? key : nil
431
- end
430
+ if BOOLEAN_ATTRIBUTES.include?(key)
431
+ value = value ? key : nil
432
+ end
432
433
 
433
- unless value.nil?
434
- value = case value
435
- when Array
436
- value.compact.join(" ")
437
- else
438
- value
434
+ unless value.nil?
435
+ value = case value
436
+ when Array
437
+ value.compact.join(" ")
438
+ else
439
+ value
440
+ end
441
+ attrs << %( #{html_escape(key)}="#{html_escape(value)}")
439
442
  end
440
- attrs << %( #{html_escape(key)}="#{html_escape(value)}")
441
- end
442
443
 
443
- attrs
444
+ attrs
445
+ end
444
446
  end
445
447
  end
446
-
447
448
  end
448
449
  end