-
Notifications
You must be signed in to change notification settings - Fork 0
/
linker.rb
88 lines (75 loc) · 2.4 KB
/
linker.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# Takes a block of text and converts any links into proper
# <a href="#">#</a> html links. Can also truncate long links
# to a pre-defined length if requested.
#
class Linker
attr_reader :matches, :string
@matches = Array.new
def self.make_links( str, trunc=false, length=15 )
@string = str
# Regex adapted from http://immike.net/blog/2007/04/06/5-regular-expressions-every-web-programmer-should-know/
url = %r{
\b
# Match the leading part (proto://hostname, or just hostname)
(?:
# http://, or https:// leading part
(?:https?)://[-\w]+(?:\.\w[-\w]*)+
|
# or, try to find a hostname with more specific sub-expression
(?i: [a-z0-9] (?:[-a-z0-9]*[a-z0-9])? \. )+ # sub domains
# Now ending .com, etc. For these, require lowercase
(?-i: com\b
| edu\b
| biz\b
| gov\b
| in(?:t|fo)\b # .int or .info
| mil\b
| net\b
| org\b
| [a-z][a-z]\.[a-z][a-z]\b # two-letter country code
)
)
# Allow an optional port number
(?: : \d+ )?
# The rest of the URL is optional, and begins with /
(?:
/
# The rest are heuristics for what seems to work well
[^.!,?;"\'<>()\[\]\{\}\s\x7F-\xFF]*
(?:
[.!,?]+ [^.!,?;”\’<>()\[\]\{\}\s\x7F-\xFF]+
)*
)?
}ix
@string.scan( url ).to_a.each do |match|
@matches << [match, Linker::linkify( match, trunc, length )]
end
# replace each URL with its link
@matches.each do |match|
@string.gsub!( match[0], match[1] )
end
@string
end
def self.linkify( str, trunc=false, length=nil )
out = ["<a href=\"#{str}\">"]
if trunc
out << Linker::truncate( str, length )
else
out << str
end
out << "</a>"
out.join
end
def self.truncate( str, length )
str.split("")
length -= 3
a = length / 2
b = []
b << str[0..a]
b << str[str.length-a..str.length]
b.join("...")
end
end
a = "This is a block of text with www.link.com links in it, and proper http://caius.name/ http://www.caius.com"
p Linker::make_links( a, true )
# >> "This is a block of text with <a href=\"www.link.com\">www.lin...nk.com</a> links in it, and proper <a href=\"http://caius.name/\">http://....name/</a> <a href=\"http://www.caius.com\">http://...us.com</a>"