linkup 1.0.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.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg
2
+
data/README.markdown ADDED
@@ -0,0 +1,44 @@
1
+ linkup
2
+ ===
3
+
4
+ A Ruby Gem. It will add link tags to url-like string embedded in text, without re-linking existing links.
5
+
6
+ Caveat: If the text contains already linked urls, then the original string will be returned. It's not smart about telling which urls are already linked or not linked, and so just returns the original string if it sees any href='s in the passed string.
7
+
8
+ Background
9
+ ---
10
+
11
+ Based on this regex by John Gruber: http://daringfireball.net/2009/11/liberal_regex_for_matching_urls
12
+
13
+ Provide hyperlinks for plain text urls.
14
+
15
+ From the link:
16
+
17
+ "It makes no attempt to parse URLs according to any official specification. It isn’t limited to predefined URL protocols. It should be clever about things like parentheses and trailing punctuation."
18
+
19
+ Usage
20
+ ---
21
+
22
+ The sane, non-object-space-polluting way:
23
+
24
+ Linkup.linkify('string with url http://example.com')
25
+ #=> 'string with url <a href="http://example.com">http://example.com</a>'
26
+
27
+ Or, include it in the String class To add a method called 'linkup' to every string object:
28
+
29
+ class String; include Linkup; end
30
+
31
+ 'string with url http://example.com'.linkup
32
+ #=> 'string with url <a href="http://example.com">http://example.com</a>'
33
+
34
+ As per the warning above, strings already containing href='s will not be re-linked:
35
+
36
+ s = '<a href="http://example.com">http://foo.com</a>, http://bar.net/'
37
+ Linkup.linkify(s)
38
+ #=> '<a href="http://example.com">http://foo.com</a>, http://bar.net/'
39
+
40
+ Installation
41
+ ---
42
+
43
+ gem install linkup
44
+
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = "linkup"
5
+ gemspec.summary = "Link bare urls in text."
6
+ gemspec.description = "From: http://daringfireball.net/2009/11/liberal_regex_for_matching_urls"
7
+ gemspec.email = "jim@jimlindley.com"
8
+ gemspec.homepage = "http://github.com/jlindley/linkup"
9
+ gemspec.authors = ["Jim Lindley"]
10
+ end
11
+ Jeweler::GemcutterTasks.new
12
+ rescue LoadError
13
+ puts "Jeweler not available. Install it with: gem install jeweler"
14
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/doc/ruby_regex.rb ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ r = /\b(([\w-]+:\/\/?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/)))/
4
+
5
+ s1 = "Blah blah http://blah.com blah http://foo.com/alsdkjf.html"
6
+ s2 = "blah blah blah blah"
7
+
8
+ m1 = s1.scan(r)
9
+ puts m1.map{|m| m[0] }.join(" ")
10
+
11
+ m2 = s2.scan(r)
12
+
13
+ puts m2.map{|m| m[0] }.join(" ")
14
+
15
+ s1_linked = s1.gsub(r) do |url|
16
+ %Q[<a href="#{url}">#{url}</a>]
17
+ end
18
+
19
+ puts s1_linked
@@ -0,0 +1,26 @@
1
+ # from http://daringfireball.net/2009/11/liberal_regex_for_matching_urls
2
+
3
+ http://foo.com/blah_blah
4
+ http://foo.com/blah_blah/
5
+ (Something like http://foo.com/blah_blah)
6
+ http://foo.com/blah_blah_(wikipedia)
7
+ (Something like http://foo.com/blah_blah_(wikipedia))
8
+ http://foo.com/blah_blah.
9
+ http://foo.com/blah_blah/.
10
+ <http://foo.com/blah_blah>
11
+ <http://foo.com/blah_blah/>
12
+ http://foo.com/blah_blah,
13
+ http://www.example.com/wpstyle/?p=364.
14
+ http://✪df.ws/123
15
+ rdar://1234
16
+ rdar:/1234
17
+ http://userid:password@example.com:8080
18
+ http://userid@example.com
19
+ http://userid@example.com:8080
20
+ http://userid:password@example.com
21
+ http://example.com:8080 x-yojimbo-item://6303E4C1-xxxx-45A6-AB9D-3A908F59AE0E
22
+ message://%3c330e7f8409726r6a4ba78dkf1fd71420c1bf6ff@mail.gmail.com%3e
23
+ http://➡.ws/䨹
24
+ www.➡.ws/䨹
25
+ <tag>http://example.com</tag>
26
+ Just a www.example.com link.
data/lib/linkup.rb ADDED
@@ -0,0 +1,41 @@
1
+ module Linkup
2
+
3
+ # for inclusion in String class
4
+ def linkup
5
+ Linkup.linkify(self)
6
+ end
7
+
8
+ def self.linkify(string)
9
+ Linker.new(string).to_s
10
+ end
11
+
12
+ class Linker
13
+
14
+ attr_accessor :original
15
+
16
+ LINK_REGEX = /\b(([\w-]+:\/\/?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/)))/u
17
+
18
+ def initialize(string)
19
+ self.original = string
20
+ end
21
+
22
+ def already_linked?
23
+ original.match(/href=/)
24
+ end
25
+
26
+ def linkify_text(text)
27
+ text.gsub(LINK_REGEX) do |match|
28
+ prefix = if (match =~/\Awww\./)
29
+ prefix = 'http://'
30
+ end
31
+ %Q[<a href="#{prefix}#{match}">#{match}</a>]
32
+ end
33
+ end
34
+
35
+ def to_s
36
+ already_linked? ? original : linkify_text(original)
37
+ end
38
+
39
+ end
40
+
41
+ end
data/linkup.gemspec ADDED
@@ -0,0 +1,49 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{linkup}
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jim Lindley"]
12
+ s.date = %q{2010-01-20}
13
+ s.description = %q{From: http://daringfireball.net/2009/11/liberal_regex_for_matching_urls}
14
+ s.email = %q{jim@jimlindley.com}
15
+ s.extra_rdoc_files = [
16
+ "README.markdown"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "README.markdown",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "doc/ruby_regex.rb",
24
+ "doc/sample_lines.txt",
25
+ "lib/linkup.rb",
26
+ "linkup.gemspec",
27
+ "test/test_helper.rb",
28
+ "test/test_linkup.rb"
29
+ ]
30
+ s.homepage = %q{http://github.com/jlindley/linkup}
31
+ s.rdoc_options = ["--charset=UTF-8"]
32
+ s.require_paths = ["lib"]
33
+ s.rubygems_version = %q{1.3.5}
34
+ s.summary = %q{Link bare urls in text.}
35
+ s.test_files = [
36
+ "test/test_helper.rb",
37
+ "test/test_linkup.rb"
38
+ ]
39
+
40
+ if s.respond_to? :specification_version then
41
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
42
+ s.specification_version = 3
43
+
44
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
45
+ else
46
+ end
47
+ else
48
+ end
49
+ end
@@ -0,0 +1,7 @@
1
+ require 'test/unit'
2
+ require 'shoulda'
3
+ require 'lib/linkup'
4
+
5
+ class String
6
+ include Linkup
7
+ end
@@ -0,0 +1,185 @@
1
+ require 'test/test_helper'
2
+
3
+ class TestLinkup < Test::Unit::TestCase
4
+
5
+ context "from daringfireball" do
6
+
7
+ should "link plain url" do
8
+ input = 'http://foo.com/blah_blah'
9
+ expected = '<a href="http://foo.com/blah_blah">http://foo.com/blah_blah</a>'
10
+ assert_equal expected, input.linkup
11
+ end
12
+
13
+ should "link plain url with trailing slash" do
14
+ input = 'http://foo.com/blah_blah/'
15
+ expected = '<a href="http://foo.com/blah_blah/">http://foo.com/blah_blah/</a>'
16
+ assert_equal expected, input.linkup
17
+ end
18
+
19
+ should "not link dot after url with" do
20
+ input = 'http://foo.com/blah_blah.'
21
+ expected = '<a href="http://foo.com/blah_blah">http://foo.com/blah_blah</a>.'
22
+ assert_equal expected, input.linkup
23
+ end
24
+
25
+ should "link plain url with trailing slash, but not trailing dot" do
26
+ input = 'http://foo.com/blah_blah/.'
27
+ expected = '<a href="http://foo.com/blah_blah/">http://foo.com/blah_blah/</a>.'
28
+ assert_equal expected, input.linkup
29
+ end
30
+
31
+ should "not link link-adjacent parens" do
32
+ input = '(Something like http://foo.com/blah_blah)'
33
+ expected = '(Something like <a href="http://foo.com/blah_blah">http://foo.com/blah_blah</a>)'
34
+ assert_equal expected, input.linkup
35
+ end
36
+
37
+ should "link paren-containing link" do
38
+ input = 'http://foo.com/blah_blah_(wikipedia)'
39
+ expected = '<a href="http://foo.com/blah_blah_(wikipedia)">http://foo.com/blah_blah_(wikipedia)</a>'
40
+ assert_equal expected, input.linkup
41
+ end
42
+
43
+ should "handle mixed link and non-link parens" do
44
+ input = '(Something like http://foo.com/blah_blah_(wikipedia))'
45
+ expected = '(Something like <a href="http://foo.com/blah_blah_(wikipedia)">http://foo.com/blah_blah_(wikipedia)</a>)'
46
+ assert_equal expected, input.linkup
47
+ end
48
+
49
+ should "not link link-adjacent angle brackets" do
50
+ input = '<http://foo.com/blah_blah>'
51
+ expected = '<<a href="http://foo.com/blah_blah">http://foo.com/blah_blah</a>>'
52
+ assert_equal expected, input.linkup
53
+ end
54
+
55
+ should "handle link-adjacent angle brackets with trailing slash" do
56
+ input = '<http://foo.com/blah_blah/>'
57
+ expected = '<<a href="http://foo.com/blah_blah/">http://foo.com/blah_blah/</a>>'
58
+ assert_equal expected, input.linkup
59
+ end
60
+
61
+ should "not link comma after url" do
62
+ input = 'http://foo.com/blah_blah,'
63
+ expected = '<a href="http://foo.com/blah_blah">http://foo.com/blah_blah</a>,'
64
+ assert_equal expected, input.linkup
65
+ end
66
+
67
+ should "not link urls with params" do
68
+ input = 'http://www.example.com/wpstyle/?p=364.'
69
+ expected = '<a href="http://www.example.com/wpstyle/?p=364">http://www.example.com/wpstyle/?p=364</a>.'
70
+ assert_equal expected, input.linkup
71
+ end
72
+
73
+ should "link non-protocol specifying, but www-subdomained urls" do
74
+ input = "www.example.com"
75
+ expected = '<a href="http://www.example.com">www.example.com</a>'
76
+ assert_equal expected, input.linkup
77
+ end
78
+
79
+ should "link utf-8 IDN domains" do
80
+ input = 'http://✪df.ws/123'
81
+ expected = '<a href="http://✪df.ws/123">http://✪df.ws/123</a>'
82
+ assert_equal expected, input.linkup
83
+ end
84
+
85
+ should "link non-standard non-x-prefixed protocols" do
86
+ input = 'rdar://1234'
87
+ expected = '<a href="rdar://1234">rdar://1234</a>'
88
+ assert_equal expected, input.linkup
89
+ end
90
+
91
+ should "link link urls-like strings with only one slash" do
92
+ input = 'rdar:/1234'
93
+ expected = '<a href="rdar:/1234">rdar:/1234</a>'
94
+ assert_equal expected, input.linkup
95
+ end
96
+
97
+ should "link urls with port" do
98
+ input = 'http://example.com:8080'
99
+ expected = '<a href="http://example.com:8080">http://example.com:8080</a>'
100
+ assert_equal expected, input.linkup
101
+ end
102
+
103
+ should "link urls with username" do
104
+ input = 'http://userid@example.com'
105
+ expected = '<a href="http://userid@example.com">http://userid@example.com</a>'
106
+ assert_equal expected, input.linkup
107
+ end
108
+
109
+ should "link urls with username and password" do
110
+ input = 'http://userid:password@example.com'
111
+ expected = '<a href="http://userid:password@example.com">http://userid:password@example.com</a>'
112
+ assert_equal expected, input.linkup
113
+ end
114
+
115
+ should "link urls with username and port" do
116
+ input = 'http://userid@example.com:8080'
117
+ expected = '<a href="http://userid@example.com:8080">http://userid@example.com:8080</a>'
118
+ assert_equal expected, input.linkup
119
+ end
120
+
121
+ should "link urls with username and password and port" do
122
+ input = 'http://userid:password@example.com:8080'
123
+ expected = '<a href="http://userid:password@example.com:8080">http://userid:password@example.com:8080</a>'
124
+ assert_equal expected, input.linkup
125
+ end
126
+
127
+ should "link urls with custom x- prefixed protocols" do
128
+ input = 'x-yojimbo-item://6303E4C1-xxxx-45A6-AB9D-3A908F59AE0E'
129
+ expected = '<a href="x-yojimbo-item://6303E4C1-xxxx-45A6-AB9D-3A908F59AE0E">x-yojimbo-item://6303E4C1-xxxx-45A6-AB9D-3A908F59AE0E</a>'
130
+ assert_equal expected, input.linkup
131
+ end
132
+
133
+ should "link mail message urls" do
134
+ input = 'message://%3c330e7f8409726r6a4ba78dkf1fd71420c1bf6ff@mail.gmail.com%3e'
135
+ expected = '<a href="message://%3c330e7f8409726r6a4ba78dkf1fd71420c1bf6ff@mail.gmail.com%3e">message://%3c330e7f8409726r6a4ba78dkf1fd71420c1bf6ff@mail.gmail.com%3e</a>'
136
+ assert_equal expected, input.linkup
137
+ end
138
+
139
+ should "link urls with UTF-8 domain and path components" do
140
+ input = "http://➡.ws/䨹"
141
+ expected = '<a href="http://➡.ws/䨹">http://➡.ws/䨹</a>'
142
+ assert_equal expected, input.linkup
143
+ end
144
+
145
+ should "link urls with UTF-8 domain and path components, www subdomain, but no protocol" do
146
+ input = "www.➡.ws/䨹"
147
+ expected = '<a href="http://www.➡.ws/䨹">www.➡.ws/䨹</a>'
148
+ assert_equal expected, input.linkup
149
+ end
150
+
151
+ should "link urls inside existing xml tags" do
152
+ input = "<tag>http://example.com</tag>"
153
+ expected = '<tag><a href="http://example.com">http://example.com</a></tag>'
154
+ assert_equal expected, input.linkup
155
+ end
156
+
157
+ end
158
+
159
+ context "already-linked urls" do
160
+ should "not re-link urls inside link tags" do
161
+ input = '<a href="http://example.com">http://example.com</a>'
162
+ expected = '<a href="http://example.com">http://example.com</a>'
163
+ assert_equal expected, input.linkup
164
+ end
165
+ should "not re-link urls inside link tags with surrounding text" do
166
+ input = '<a href="http://example.com">click http://example.com to go there</a>'
167
+ expected = '<a href="http://example.com">click http://example.com to go there</a>'
168
+ assert_equal expected, input.linkup
169
+ end
170
+ should "not re-link urls inside link tags, even with intervening tags" do
171
+ input = '<a href="http://example.com"><i>http://example.com</i></a>'
172
+ expected = '<a href="http://example.com"><i>http://example.com</i></a>'
173
+ assert_equal expected, input.linkup
174
+ end
175
+ end
176
+
177
+ context "badly handled scenarios" do
178
+ should "but doesn't, link non-linked urls next to linked urls" do
179
+ input = '<a href="http://example.com"><i>http://example.com</i></a>, and also http://example.net/ too'
180
+ expected = '<a href="http://example.com"><i>http://example.com</i></a>, and also http://example.net/ too'
181
+ assert_equal expected, input.linkup
182
+ end
183
+ end
184
+
185
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: linkup
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jim Lindley
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-20 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: "From: http://daringfireball.net/2009/11/liberal_regex_for_matching_urls"
17
+ email: jim@jimlindley.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.markdown
24
+ files:
25
+ - .gitignore
26
+ - README.markdown
27
+ - Rakefile
28
+ - VERSION
29
+ - doc/ruby_regex.rb
30
+ - doc/sample_lines.txt
31
+ - lib/linkup.rb
32
+ - linkup.gemspec
33
+ - test/test_helper.rb
34
+ - test/test_linkup.rb
35
+ has_rdoc: true
36
+ homepage: http://github.com/jlindley/linkup
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options:
41
+ - --charset=UTF-8
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.3.5
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Link bare urls in text.
63
+ test_files:
64
+ - test/test_helper.rb
65
+ - test/test_linkup.rb