Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F115982
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
22 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/auto_linker/parser.ex b/lib/auto_linker/parser.ex
index fec8f3c..3d13ec2 100644
--- a/lib/auto_linker/parser.ex
+++ b/lib/auto_linker/parser.ex
@@ -1,218 +1,223 @@
defmodule AutoLinker.Parser do
@moduledoc """
Module to handle parsing the the input string.
"""
alias AutoLinker.Builder
@doc """
Parse the given string, identifying items to link.
Parses the string, replacing the matching urls and phone numbers with an html link.
## Examples
iex> AutoLinker.Parser.parse("Check out google.com")
"Check out <a href='http://google.com' class='auto-linker' target='_blank' rel='noopener noreferrer'>google.com</a>"
iex> AutoLinker.Parser.parse("call me at x9999", phone: true)
~s{call me at <a href="#" class="phone-number" data-phone="9999">x9999</a>}
iex> AutoLinker.Parser.parse("or at home on 555.555.5555", phone: true)
~s{or at home on <a href="#" class="phone-number" data-phone="5555555555">555.555.5555</a>}
iex> AutoLinker.Parser.parse(", work (555) 555-5555", phone: true)
~s{, work <a href="#" class="phone-number" data-phone="5555555555">(555) 555-5555</a>}
"""
# @invalid_url ~r/\.\.+/
@invalid_url ~r/(\.\.+)|(^(\d+\.){1,2}\d+$)/
- @match_url ~r{^[\w\.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$}
- @match_scheme ~r{^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$}
+ @match_url ~r{^[\w\.-]+(?<tld>\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$}
+ @match_scheme ~r{^(?:http(s)?:\/\/)?[\w.-]+(?<tld>\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$}
@match_phone ~r"((?:x\d{2,7})|(?:(?:\+?1\s?(?:[.-]\s?)?)?(?:\(\s?(?:[2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s?\)|(?:[2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s?(?:[.-]\s?)?)(?:[2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s?(?:[.-]\s?)?(?:[0-9]{4}))"
@default_opts ~w(url)a
+ @tlds "./priv/tlds.txt" |> File.read!() |> String.trim() |> String.split("\n")
+
def parse(text, opts \\ %{})
def parse(text, list) when is_list(list), do: parse(text, Enum.into(list, %{}))
def parse(text, opts) do
config =
:auto_linker
|> Application.get_env(:opts, [])
|> Enum.into(%{})
|> Map.put(
:attributes,
Application.get_env(:auto_linker, :attributes, [])
)
opts =
Enum.reduce(@default_opts, opts, fn opt, acc ->
if is_nil(opts[opt]) and is_nil(config[opt]) do
Map.put(acc, opt, true)
else
acc
end
end)
do_parse(text, Map.merge(config, opts))
end
defp do_parse(text, %{phone: false} = opts), do: do_parse(text, Map.delete(opts, :phone))
defp do_parse(text, %{url: false} = opts), do: do_parse(text, Map.delete(opts, :url))
defp do_parse(text, %{phone: _} = opts) do
text
|> do_parse(false, opts, {"", "", :parsing}, &check_and_link_phone/3)
|> do_parse(Map.delete(opts, :phone))
end
defp do_parse(text, %{markdown: true} = opts) do
text
|> Builder.create_markdown_links(opts)
|> do_parse(Map.delete(opts, :markdown))
end
defp do_parse(text, %{url: _} = opts) do
if (exclude = Map.get(opts, :exclude_pattern, false)) && String.starts_with?(text, exclude) do
text
else
do_parse(text, Map.get(opts, :scheme, false), opts, {"", "", :parsing}, &check_and_link/3)
end
|> do_parse(Map.delete(opts, :url))
end
defp do_parse(text, _), do: text
defp do_parse("", _scheme, _opts, {"", acc, _}, _handler),
do: acc
defp do_parse("", scheme, opts, {buffer, acc, _}, handler),
do: acc <> handler.(buffer, scheme, opts)
defp do_parse("<a" <> text, scheme, opts, {buffer, acc, :parsing}, handler),
do: do_parse(text, scheme, opts, {"", acc <> buffer <> "<a", :skip}, handler)
defp do_parse("</a>" <> text, scheme, opts, {buffer, acc, :skip}, handler),
do: do_parse(text, scheme, opts, {"", acc <> buffer <> "</a>", :parsing}, handler)
defp do_parse("<" <> text, scheme, opts, {"", acc, :parsing}, handler),
do: do_parse(text, scheme, opts, {"<", acc, {:open, 1}}, handler)
defp do_parse(">" <> text, scheme, opts, {buffer, acc, {:attrs, level}}, handler),
do: do_parse(text, scheme, opts, {"", acc <> buffer <> ">", {:html, level}}, handler)
defp do_parse(<<ch::8>> <> text, scheme, opts, {"", acc, {:attrs, level}}, handler),
do: do_parse(text, scheme, opts, {"", acc <> <<ch::8>>, {:attrs, level}}, handler)
defp do_parse("</" <> text, scheme, opts, {buffer, acc, {:html, level}}, handler),
do:
do_parse(
text,
scheme,
opts,
{"", acc <> handler.(buffer, scheme, opts) <> "</", {:close, level}},
handler
)
defp do_parse(">" <> text, scheme, opts, {buffer, acc, {:close, 1}}, handler),
do: do_parse(text, scheme, opts, {"", acc <> buffer <> ">", :parsing}, handler)
defp do_parse(">" <> text, scheme, opts, {buffer, acc, {:close, level}}, handler),
do: do_parse(text, scheme, opts, {"", acc <> buffer <> ">", {:html, level - 1}}, handler)
defp do_parse(" " <> text, scheme, opts, {buffer, acc, {:open, level}}, handler),
do: do_parse(text, scheme, opts, {"", acc <> buffer <> " ", {:attrs, level}}, handler)
defp do_parse("\n" <> text, scheme, opts, {buffer, acc, {:open, level}}, handler),
do: do_parse(text, scheme, opts, {"", acc <> buffer <> "\n", {:attrs, level}}, handler)
# default cases where state is not important
defp do_parse(" " <> text, scheme, %{phone: _} = opts, {buffer, acc, state}, handler),
do: do_parse(text, scheme, opts, {buffer <> " ", acc, state}, handler)
defp do_parse(" " <> text, scheme, opts, {buffer, acc, state}, handler),
do:
do_parse(
text,
scheme,
opts,
{"", acc <> handler.(buffer, scheme, opts) <> " ", state},
handler
)
defp do_parse("\n" <> text, scheme, opts, {buffer, acc, state}, handler),
do:
do_parse(
text,
scheme,
opts,
{"", acc <> handler.(buffer, scheme, opts) <> "\n", state},
handler
)
defp do_parse(<<ch::8>>, scheme, opts, {buffer, acc, state}, handler),
do:
do_parse(
"",
scheme,
opts,
{"", acc <> handler.(buffer <> <<ch::8>>, scheme, opts), state},
handler
)
defp do_parse(<<ch::8>> <> text, scheme, opts, {buffer, acc, state}, handler),
do: do_parse(text, scheme, opts, {buffer <> <<ch::8>>, acc, state}, handler)
def check_and_link(buffer, scheme, opts) do
buffer
|> is_url?(scheme)
|> link_url(buffer, opts)
end
def check_and_link_phone(buffer, _, opts) do
buffer
|> match_phone
|> link_phone(buffer, opts)
end
@doc false
def is_url?(buffer, true) do
if Regex.match?(@invalid_url, buffer) do
false
else
- Regex.match?(@match_scheme, buffer)
+ Regex.run(@match_scheme, buffer, capture: [:tld]) |> is_valid_tld?()
end
end
def is_url?(buffer, _) do
if Regex.match?(@invalid_url, buffer) do
false
else
- Regex.match?(@match_url, buffer)
+ Regex.run(@match_url, buffer, capture: [:tld]) |> is_valid_tld?()
end
end
+ def is_valid_tld?(["." <> tld]), do: tld in @tlds
+ def is_valid_tld?(_), do: false
+
@doc false
def match_phone(buffer) do
case Regex.scan(@match_phone, buffer) do
[] -> nil
other -> other
end
end
def link_phone(nil, buffer, _), do: buffer
def link_phone(list, buffer, opts) do
Builder.create_phone_link(list, buffer, opts)
end
@doc false
def link_url(true, buffer, opts) do
Builder.create_link(buffer, opts)
end
def link_url(_, buffer, _opts), do: buffer
end
diff --git a/priv/tlds.txt b/priv/tlds.txt
new file mode 100644
index 0000000..6c87fa5
--- /dev/null
+++ b/priv/tlds.txt
@@ -0,0 +1,1543 @@
+aaa
+aarp
+abarth
+abb
+abbott
+abbvie
+abc
+able
+abogado
+abudhabi
+ac
+academy
+accenture
+accountant
+accountants
+aco
+active
+actor
+ad
+adac
+ads
+adult
+ae
+aeg
+aero
+aetna
+af
+afamilycompany
+afl
+africa
+ag
+agakhan
+agency
+ai
+aig
+aigo
+airbus
+airforce
+airtel
+akdn
+al
+alfaromeo
+alibaba
+alipay
+allfinanz
+allstate
+ally
+alsace
+alstom
+am
+americanexpress
+americanfamily
+amex
+amfam
+amica
+amsterdam
+analytics
+android
+anquan
+anz
+ao
+aol
+apartments
+app
+apple
+aq
+aquarelle
+ar
+arab
+aramco
+archi
+army
+arpa
+art
+arte
+as
+asda
+asia
+associates
+at
+athleta
+attorney
+au
+auction
+audi
+audible
+audio
+auspost
+author
+auto
+autos
+avianca
+aw
+aws
+ax
+axa
+az
+azure
+ba
+baby
+baidu
+banamex
+bananarepublic
+band
+bank
+bar
+barcelona
+barclaycard
+barclays
+barefoot
+bargains
+baseball
+basketball
+bauhaus
+bayern
+bb
+bbc
+bbt
+bbva
+bcg
+bcn
+bd
+be
+beats
+beauty
+beer
+bentley
+berlin
+best
+bestbuy
+bet
+bf
+bg
+bh
+bharti
+bi
+bible
+bid
+bike
+bing
+bingo
+bio
+biz
+bj
+black
+blackfriday
+blanco
+blockbuster
+blog
+bloomberg
+blue
+bm
+bms
+bmw
+bn
+bnl
+bnpparibas
+bo
+boats
+boehringer
+bofa
+bom
+bond
+boo
+book
+booking
+boots
+bosch
+bostik
+boston
+bot
+boutique
+box
+br
+bradesco
+bridgestone
+broadway
+broker
+brother
+brussels
+bs
+bt
+budapest
+bugatti
+build
+builders
+business
+buy
+buzz
+bv
+bw
+by
+bz
+bzh
+ca
+cab
+cafe
+cal
+call
+calvinklein
+cam
+camera
+camp
+cancerresearch
+canon
+capetown
+capital
+capitalone
+car
+caravan
+cards
+care
+career
+careers
+cars
+cartier
+casa
+case
+caseih
+cash
+casino
+cat
+catering
+catholic
+cba
+cbn
+cbre
+cbs
+cc
+cd
+ceb
+center
+ceo
+cern
+cf
+cfa
+cfd
+cg
+ch
+chanel
+channel
+chase
+chat
+cheap
+chintai
+chloe
+christmas
+chrome
+chrysler
+church
+ci
+cipriani
+circle
+cisco
+citadel
+citi
+citic
+city
+cityeats
+ck
+cl
+claims
+cleaning
+click
+clinic
+clinique
+clothing
+cloud
+club
+clubmed
+cm
+cn
+co
+coach
+codes
+coffee
+college
+cologne
+com
+comcast
+commbank
+community
+company
+compare
+computer
+comsec
+condos
+construction
+consulting
+contact
+contractors
+cooking
+cookingchannel
+cool
+coop
+corsica
+country
+coupon
+coupons
+courses
+cr
+credit
+creditcard
+creditunion
+cricket
+crown
+crs
+cruise
+cruises
+csc
+cu
+cuisinella
+cv
+cw
+cx
+cy
+cymru
+cyou
+cz
+dabur
+dad
+dance
+data
+date
+dating
+datsun
+day
+dclk
+dds
+de
+deal
+dealer
+deals
+degree
+delivery
+dell
+deloitte
+delta
+democrat
+dental
+dentist
+desi
+design
+dev
+dhl
+diamonds
+diet
+digital
+direct
+directory
+discount
+discover
+dish
+diy
+dj
+dk
+dm
+dnp
+do
+docs
+doctor
+dodge
+dog
+doha
+domains
+dot
+download
+drive
+dtv
+dubai
+duck
+dunlop
+duns
+dupont
+durban
+dvag
+dvr
+dz
+earth
+eat
+ec
+eco
+edeka
+edu
+education
+ee
+eg
+email
+emerck
+energy
+engineer
+engineering
+enterprises
+epost
+epson
+equipment
+er
+ericsson
+erni
+es
+esq
+estate
+esurance
+et
+etisalat
+eu
+eurovision
+eus
+events
+everbank
+exchange
+expert
+exposed
+express
+extraspace
+fage
+fail
+fairwinds
+faith
+family
+fan
+fans
+farm
+farmers
+fashion
+fast
+fedex
+feedback
+ferrari
+ferrero
+fi
+fiat
+fidelity
+fido
+film
+final
+finance
+financial
+fire
+firestone
+firmdale
+fish
+fishing
+fit
+fitness
+fj
+fk
+flickr
+flights
+flir
+florist
+flowers
+fly
+fm
+fo
+foo
+food
+foodnetwork
+football
+ford
+forex
+forsale
+forum
+foundation
+fox
+fr
+free
+fresenius
+frl
+frogans
+frontdoor
+frontier
+ftr
+fujitsu
+fujixerox
+fun
+fund
+furniture
+futbol
+fyi
+ga
+gal
+gallery
+gallo
+gallup
+game
+games
+gap
+garden
+gb
+gbiz
+gd
+gdn
+ge
+gea
+gent
+genting
+george
+gf
+gg
+ggee
+gh
+gi
+gift
+gifts
+gives
+giving
+gl
+glade
+glass
+gle
+global
+globo
+gm
+gmail
+gmbh
+gmo
+gmx
+gn
+godaddy
+gold
+goldpoint
+golf
+goo
+goodhands
+goodyear
+goog
+google
+gop
+got
+gov
+gp
+gq
+gr
+grainger
+graphics
+gratis
+green
+gripe
+grocery
+group
+gs
+gt
+gu
+guardian
+gucci
+guge
+guide
+guitars
+guru
+gw
+gy
+hair
+hamburg
+hangout
+haus
+hbo
+hdfc
+hdfcbank
+health
+healthcare
+help
+helsinki
+here
+hermes
+hgtv
+hiphop
+hisamitsu
+hitachi
+hiv
+hk
+hkt
+hm
+hn
+hockey
+holdings
+holiday
+homedepot
+homegoods
+homes
+homesense
+honda
+honeywell
+horse
+hospital
+host
+hosting
+hot
+hoteles
+hotels
+hotmail
+house
+how
+hr
+hsbc
+ht
+htc
+hu
+hughes
+hyatt
+hyundai
+ibm
+icbc
+ice
+icu
+id
+ie
+ieee
+ifm
+ikano
+il
+im
+imamat
+imdb
+immo
+immobilien
+in
+industries
+infiniti
+info
+ing
+ink
+institute
+insurance
+insure
+int
+intel
+international
+intuit
+investments
+io
+ipiranga
+iq
+ir
+irish
+is
+iselect
+ismaili
+ist
+istanbul
+it
+itau
+itv
+iveco
+iwc
+jaguar
+java
+jcb
+jcp
+je
+jeep
+jetzt
+jewelry
+jio
+jlc
+jll
+jm
+jmp
+jnj
+jo
+jobs
+joburg
+jot
+joy
+jp
+jpmorgan
+jprs
+juegos
+juniper
+kaufen
+kddi
+ke
+kerryhotels
+kerrylogistics
+kerryproperties
+kfh
+kg
+kh
+ki
+kia
+kim
+kinder
+kindle
+kitchen
+kiwi
+km
+kn
+koeln
+komatsu
+kosher
+kp
+kpmg
+kpn
+kr
+krd
+kred
+kuokgroup
+kw
+ky
+kyoto
+kz
+la
+lacaixa
+ladbrokes
+lamborghini
+lamer
+lancaster
+lancia
+lancome
+land
+landrover
+lanxess
+lasalle
+lat
+latino
+latrobe
+law
+lawyer
+lb
+lc
+lds
+lease
+leclerc
+lefrak
+legal
+lego
+lexus
+lgbt
+li
+liaison
+lidl
+life
+lifeinsurance
+lifestyle
+lighting
+like
+lilly
+limited
+limo
+lincoln
+linde
+link
+lipsy
+live
+living
+lixil
+lk
+loan
+loans
+locker
+locus
+loft
+lol
+london
+lotte
+lotto
+love
+lpl
+lplfinancial
+lr
+ls
+lt
+ltd
+ltda
+lu
+lundbeck
+lupin
+luxe
+luxury
+lv
+ly
+ma
+macys
+madrid
+maif
+maison
+makeup
+man
+management
+mango
+map
+market
+marketing
+markets
+marriott
+marshalls
+maserati
+mattel
+mba
+mc
+mckinsey
+md
+me
+med
+media
+meet
+melbourne
+meme
+memorial
+men
+menu
+meo
+merckmsd
+metlife
+mg
+mh
+miami
+microsoft
+mil
+mini
+mint
+mit
+mitsubishi
+mk
+ml
+mlb
+mls
+mm
+mma
+mn
+mo
+mobi
+mobile
+mobily
+moda
+moe
+moi
+mom
+monash
+money
+monster
+mopar
+mormon
+mortgage
+moscow
+moto
+motorcycles
+mov
+movie
+movistar
+mp
+mq
+mr
+ms
+msd
+mt
+mtn
+mtr
+mu
+museum
+mutual
+mv
+mw
+mx
+my
+mz
+na
+nab
+nadex
+nagoya
+name
+nationwide
+natura
+navy
+nba
+nc
+ne
+nec
+net
+netbank
+netflix
+network
+neustar
+new
+newholland
+news
+next
+nextdirect
+nexus
+nf
+nfl
+ng
+ngo
+nhk
+ni
+nico
+nike
+nikon
+ninja
+nissan
+nissay
+nl
+no
+nokia
+northwesternmutual
+norton
+now
+nowruz
+nowtv
+np
+nr
+nra
+nrw
+ntt
+nu
+nyc
+nz
+obi
+observer
+off
+office
+okinawa
+olayan
+olayangroup
+oldnavy
+ollo
+om
+omega
+one
+ong
+onl
+online
+onyourside
+ooo
+open
+oracle
+orange
+org
+organic
+origins
+osaka
+otsuka
+ott
+ovh
+pa
+page
+panasonic
+panerai
+paris
+pars
+partners
+parts
+party
+passagens
+pay
+pccw
+pe
+pet
+pf
+pfizer
+pg
+ph
+pharmacy
+phd
+philips
+phone
+photo
+photography
+photos
+physio
+piaget
+pics
+pictet
+pictures
+pid
+pin
+ping
+pink
+pioneer
+pizza
+pk
+pl
+place
+play
+playstation
+plumbing
+plus
+pm
+pn
+pnc
+pohl
+poker
+politie
+porn
+post
+pr
+pramerica
+praxi
+press
+prime
+pro
+prod
+productions
+prof
+progressive
+promo
+properties
+property
+protection
+pru
+prudential
+ps
+pt
+pub
+pw
+pwc
+py
+qa
+qpon
+quebec
+quest
+qvc
+racing
+radio
+raid
+re
+read
+realestate
+realtor
+realty
+recipes
+red
+redstone
+redumbrella
+rehab
+reise
+reisen
+reit
+reliance
+ren
+rent
+rentals
+repair
+report
+republican
+rest
+restaurant
+review
+reviews
+rexroth
+rich
+richardli
+ricoh
+rightathome
+ril
+rio
+rip
+rmit
+ro
+rocher
+rocks
+rodeo
+rogers
+room
+rs
+rsvp
+ru
+rugby
+ruhr
+run
+rw
+rwe
+ryukyu
+sa
+saarland
+safe
+safety
+sakura
+sale
+salon
+samsclub
+samsung
+sandvik
+sandvikcoromant
+sanofi
+sap
+sapo
+sarl
+sas
+save
+saxo
+sb
+sbi
+sbs
+sc
+sca
+scb
+schaeffler
+schmidt
+scholarships
+school
+schule
+schwarz
+science
+scjohnson
+scor
+scot
+sd
+se
+search
+seat
+secure
+security
+seek
+select
+sener
+services
+ses
+seven
+sew
+sex
+sexy
+sfr
+sg
+sh
+shangrila
+sharp
+shaw
+shell
+shia
+shiksha
+shoes
+shop
+shopping
+shouji
+show
+showtime
+shriram
+si
+silk
+sina
+singles
+site
+sj
+sk
+ski
+skin
+sky
+skype
+sl
+sling
+sm
+smart
+smile
+sn
+sncf
+so
+soccer
+social
+softbank
+software
+sohu
+solar
+solutions
+song
+sony
+soy
+space
+spiegel
+spot
+spreadbetting
+sr
+srl
+srt
+st
+stada
+staples
+star
+starhub
+statebank
+statefarm
+statoil
+stc
+stcgroup
+stockholm
+storage
+store
+stream
+studio
+study
+style
+su
+sucks
+supplies
+supply
+support
+surf
+surgery
+suzuki
+sv
+swatch
+swiftcover
+swiss
+sx
+sy
+sydney
+symantec
+systems
+sz
+tab
+taipei
+talk
+taobao
+target
+tatamotors
+tatar
+tattoo
+tax
+taxi
+tc
+tci
+td
+tdk
+team
+tech
+technology
+tel
+telecity
+telefonica
+temasek
+tennis
+teva
+tf
+tg
+th
+thd
+theater
+theatre
+tiaa
+tickets
+tienda
+tiffany
+tips
+tires
+tirol
+tj
+tjmaxx
+tjx
+tk
+tkmaxx
+tl
+tm
+tmall
+tn
+to
+today
+tokyo
+tools
+top
+toray
+toshiba
+total
+tours
+town
+toyota
+toys
+tr
+trade
+trading
+training
+travel
+travelchannel
+travelers
+travelersinsurance
+trust
+trv
+tt
+tube
+tui
+tunes
+tushu
+tv
+tvs
+tw
+tz
+ua
+ubank
+ubs
+uconnect
+ug
+uk
+unicom
+university
+uno
+uol
+ups
+us
+uy
+uz
+va
+vacations
+vana
+vanguard
+vc
+ve
+vegas
+ventures
+verisign
+versicherung
+vet
+vg
+vi
+viajes
+video
+vig
+viking
+villas
+vin
+vip
+virgin
+visa
+vision
+vista
+vistaprint
+viva
+vivo
+vlaanderen
+vn
+vodka
+volkswagen
+volvo
+vote
+voting
+voto
+voyage
+vu
+vuelos
+wales
+walmart
+walter
+wang
+wanggou
+warman
+watch
+watches
+weather
+weatherchannel
+webcam
+weber
+website
+wed
+wedding
+weibo
+weir
+wf
+whoswho
+wien
+wiki
+williamhill
+win
+windows
+wine
+winners
+wme
+wolterskluwer
+woodside
+work
+works
+world
+wow
+ws
+wtc
+wtf
+xbox
+xerox
+xfinity
+xihuan
+xin
+xn--11b4c3d
+xn--1ck2e1b
+xn--1qqw23a
+xn--2scrj9c
+xn--30rr7y
+xn--3bst00m
+xn--3ds443g
+xn--3e0b707e
+xn--3hcrj9c
+xn--3oq18vl8pn36a
+xn--3pxu8k
+xn--42c2d9a
+xn--45br5cyl
+xn--45brj9c
+xn--45q11c
+xn--4gbrim
+xn--54b7fta0cc
+xn--55qw42g
+xn--55qx5d
+xn--5su34j936bgsg
+xn--5tzm5g
+xn--6frz82g
+xn--6qq986b3xl
+xn--80adxhks
+xn--80ao21a
+xn--80aqecdr1a
+xn--80asehdb
+xn--80aswg
+xn--8y0a063a
+xn--90a3ac
+xn--90ae
+xn--90ais
+xn--9dbq2a
+xn--9et52u
+xn--9krt00a
+xn--b4w605ferd
+xn--bck1b9a5dre4c
+xn--c1avg
+xn--c2br7g
+xn--cck2b3b
+xn--cg4bki
+xn--clchc0ea0b2g2a9gcd
+xn--czr694b
+xn--czrs0t
+xn--czru2d
+xn--d1acj3b
+xn--d1alf
+xn--e1a4c
+xn--eckvdtc9d
+xn--efvy88h
+xn--estv75g
+xn--fct429k
+xn--fhbei
+xn--fiq228c5hs
+xn--fiq64b
+xn--fiqs8s
+xn--fiqz9s
+xn--fjq720a
+xn--flw351e
+xn--fpcrj9c3d
+xn--fzc2c9e2c
+xn--fzys8d69uvgm
+xn--g2xx48c
+xn--gckr3f0f
+xn--gecrj9c
+xn--gk3at1e
+xn--h2breg3eve
+xn--h2brj9c
+xn--h2brj9c8c
+xn--hxt814e
+xn--i1b6b1a6a2e
+xn--imr513n
+xn--io0a7i
+xn--j1aef
+xn--j1amh
+xn--j6w193g
+xn--jlq61u9w7b
+xn--jvr189m
+xn--kcrx77d1x4a
+xn--kprw13d
+xn--kpry57d
+xn--kpu716f
+xn--kput3i
+xn--l1acc
+xn--lgbbat1ad8j
+xn--mgb9awbf
+xn--mgba3a3ejt
+xn--mgba3a4f16a
+xn--mgba7c0bbn0a
+xn--mgbaakc7dvf
+xn--mgbaam7a8h
+xn--mgbab2bd
+xn--mgbai9azgqp6j
+xn--mgbayh7gpa
+xn--mgbb9fbpob
+xn--mgbbh1a
+xn--mgbbh1a71e
+xn--mgbc0a9azcg
+xn--mgbca7dzdo
+xn--mgberp4a5d4ar
+xn--mgbgu82a
+xn--mgbi4ecexp
+xn--mgbpl2fh
+xn--mgbt3dhd
+xn--mgbtx2b
+xn--mgbx4cd0ab
+xn--mix891f
+xn--mk1bu44c
+xn--mxtq1m
+xn--ngbc5azd
+xn--ngbe9e0a
+xn--ngbrx
+xn--node
+xn--nqv7f
+xn--nqv7fs00ema
+xn--nyqy26a
+xn--o3cw4h
+xn--ogbpf8fl
+xn--p1acf
+xn--p1ai
+xn--pbt977c
+xn--pgbs0dh
+xn--pssy2u
+xn--q9jyb4c
+xn--qcka1pmc
+xn--qxam
+xn--rhqv96g
+xn--rovu88b
+xn--rvc1e0am3e
+xn--s9brj9c
+xn--ses554g
+xn--t60b56a
+xn--tckwe
+xn--tiq49xqyj
+xn--unup4y
+xn--vermgensberater-ctb
+xn--vermgensberatung-pwb
+xn--vhquv
+xn--vuq861b
+xn--w4r85el8fhu5dnra
+xn--w4rs40l
+xn--wgbh1c
+xn--wgbl6a
+xn--xhq521b
+xn--xkc2al3hye2a
+xn--xkc2dl3a5ee0h
+xn--y9a3aq
+xn--yfro4i67o
+xn--ygbi2ammx
+xn--zfr164b
+xperia
+xxx
+xyz
+yachts
+yahoo
+yamaxun
+yandex
+ye
+yodobashi
+yoga
+yokohama
+you
+youtube
+yt
+yun
+za
+zappos
+zara
+zero
+zip
+zippo
+zm
+zone
+zuerich
+zw
diff --git a/test/auto_linker_test.exs b/test/auto_linker_test.exs
index ee1e7c0..bddf6dd 100644
--- a/test/auto_linker_test.exs
+++ b/test/auto_linker_test.exs
@@ -1,30 +1,84 @@
defmodule AutoLinkerTest do
use ExUnit.Case
doctest AutoLinker
test "phone number" do
assert AutoLinker.link(", work (555) 555-5555", phone: true) ==
~s{, work <a href="#" class="phone-number" data-phone="5555555555">(555) 555-5555</a>}
end
test "default link" do
assert AutoLinker.link("google.com") ==
"<a href='http://google.com' class='auto-linker' target='_blank' rel='noopener noreferrer'>google.com</a>"
end
test "markdown" do
assert AutoLinker.link("[google.com](http://google.com)", markdown: true) ==
"<a href='http://google.com' class='auto-linker' target='_blank' rel='noopener noreferrer'>google.com</a>"
end
test "does on link existing links" do
assert AutoLinker.link("<a href='http://google.com'>google.com</a>") ==
"<a href='http://google.com'>google.com</a>"
end
test "phone number and markdown link" do
assert AutoLinker.link("888 888-8888 [ab](a.com)", phone: true, markdown: true) ==
"<a href=\"#\" class=\"phone-number\" data-phone=\"8888888888\">888 888-8888</a>" <>
" <a href='a.com' class='auto-linker' target='_blank' rel='noopener noreferrer'>ab</a>"
end
+
+ describe "TLDs" do
+ test "parse with scheme" do
+ text = "https://google.com"
+
+ expected =
+ "<a href='https://google.com' class='auto-linker' target='_blank' rel='noopener noreferrer'>google.com</a>"
+
+ assert AutoLinker.link(text, scheme: true) == expected
+ end
+
+ test "only existing TLDs with scheme" do
+ text = "this url https://google.foobar.blah11blah/ has invalid TLD"
+
+ expected = "this url https://google.foobar.blah11blah/ has invalid TLD"
+ assert AutoLinker.link(text, scheme: true) == expected
+
+ text = "this url https://google.foobar.com/ has valid TLD"
+
+ expected =
+ "this url <a href='https://google.foobar.com/' class='auto-linker' target='_blank' rel='noopener noreferrer'>google.foobar.com/</a> has valid TLD"
+
+ assert AutoLinker.link(text, scheme: true) == expected
+ end
+
+ test "only existing TLDs without scheme" do
+ text = "this url google.foobar.blah11blah/ has invalid TLD"
+ expected = "this url google.foobar.blah11blah/ has invalid TLD"
+ assert AutoLinker.link(text, scheme: false) == expected
+
+ text = "this url google.foobar.com/ has valid TLD"
+
+ expected =
+ "this url <a href='http://google.foobar.com/' class='auto-linker' target='_blank' rel='noopener noreferrer'>google.foobar.com/</a> has valid TLD"
+
+ assert AutoLinker.link(text, scheme: false) == expected
+ end
+
+ test "only existing TLDs with and without scheme" do
+ text = "this url http://google.foobar.com/ has valid TLD"
+
+ expected =
+ "this url <a href='http://google.foobar.com/' class='auto-linker' target='_blank' rel='noopener noreferrer'>google.foobar.com/</a> has valid TLD"
+
+ assert AutoLinker.link(text, scheme: true) == expected
+
+ text = "this url google.foobar.com/ has valid TLD"
+
+ expected =
+ "this url <a href='http://google.foobar.com/' class='auto-linker' target='_blank' rel='noopener noreferrer'>google.foobar.com/</a> has valid TLD"
+
+ assert AutoLinker.link(text, scheme: true) == expected
+ end
+ end
end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Nov 29, 9:34 PM (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41308
Default Alt Text
(22 KB)
Attached To
Mode
R19 linkify
Attached
Detach File
Event Timeline
Log In to Comment