twitter-text 2.0.2 → 2.1.0

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
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