added support for markdown style links
This commit is contained in:
parent
6c56eb91ef
commit
4d5182ec1f
6 changed files with 60 additions and 9 deletions
|
@ -45,6 +45,9 @@ iex> AutoLinker.link("or at home on 555.555.5555")
|
|||
iex> AutoLinker.link(", work (555) 555-5555")
|
||||
~s{, work <a href="" class="phone-number" data-number="5555555555">(555) 555-5555</a>}
|
||||
|
||||
iex> AutoLinker.link("[Google Search](http://google.com)", markdown: true)
|
||||
"<a href='http://google.com' class='auto-linker' target='_blank' rel='noopener noreferrer'>Google Search</a>"
|
||||
|
||||
See the [Docs](https://hexdocs.pm/auto_linker/) for more examples
|
||||
|
||||
## Configuration
|
||||
|
|
|
@ -15,6 +15,12 @@ defmodule AutoLinker do
|
|||
|
||||
iex> AutoLinker.link("google.com", new_window: false, rel: false, class: false)
|
||||
"<a href='http://google.com'>google.com</a>"
|
||||
|
||||
iex> AutoLinker.link("[Google](http://google.com)", markdown: true, new_window: false, rel: false, class: false)
|
||||
"<a href='http://google.com'>Google</a>"
|
||||
|
||||
iex> AutoLinker.link("[Google Search](http://google.com)", markdown: true)
|
||||
"<a href='http://google.com' class='auto-linker' target='_blank' rel='noopener noreferrer'>Google Search</a>"
|
||||
"""
|
||||
|
||||
import AutoLinker.Parser
|
||||
|
@ -33,6 +39,7 @@ defmodule AutoLinker do
|
|||
* `exclude_class: false` - Set to a class name when you don't want urls auto linked in the html of the give class
|
||||
* `exclude_id: false` - Set to an element id when you don't want urls auto linked in the html of the give element
|
||||
* `exclude_patterns: ["```"] - Don't link anything between the the pattern
|
||||
* `markdown: false` - link markdown style links
|
||||
|
||||
Each of the above options can be specified when calling `link(text, opts)`
|
||||
or can be set in the `:auto_linker's configuration. For example:
|
||||
|
|
|
@ -15,6 +15,14 @@ defmodule AutoLinker.Builder do
|
|||
|> format_url(url, opts)
|
||||
end
|
||||
|
||||
def create_markdown_links(text, opts) do
|
||||
[]
|
||||
|> build_attrs(text, opts, :rel)
|
||||
|> build_attrs(text, opts, :target)
|
||||
|> build_attrs(text, opts, :class)
|
||||
|> format_markdown(text, opts)
|
||||
end
|
||||
|
||||
defp build_attrs(attrs, _, opts, :rel) do
|
||||
if rel = Map.get(opts, :rel, "noopener noreferrer"),
|
||||
do: [{:rel, rel} | attrs], else: attrs
|
||||
|
@ -37,13 +45,25 @@ defmodule AutoLinker.Builder do
|
|||
url
|
||||
|> strip_prefix(Map.get(opts, :strip_prefix, true))
|
||||
|> truncate(Map.get(opts, :truncate, false))
|
||||
attrs =
|
||||
attrs
|
||||
|> Enum.map(fn {key, value} -> ~s(#{key}='#{value}') end)
|
||||
|> Enum.join(" ")
|
||||
attrs = format_attrs(attrs)
|
||||
"<a #{attrs}>" <> url <> "</a>"
|
||||
end
|
||||
|
||||
defp format_attrs(attrs) do
|
||||
attrs
|
||||
|> Enum.map(fn {key, value} -> ~s(#{key}='#{value}') end)
|
||||
|> Enum.join(" ")
|
||||
end
|
||||
|
||||
defp format_markdown(attrs, text, _opts) do
|
||||
attrs =
|
||||
case format_attrs(attrs) do
|
||||
"" -> ""
|
||||
attrs -> " " <> attrs
|
||||
end
|
||||
Regex.replace(~r/\[(.+?)\]\((.+?)\)/, text, "<a href='\\2'#{attrs}>\\1</a>")
|
||||
end
|
||||
|
||||
defp truncate(url, false), do: url
|
||||
defp truncate(url, len) when len < 3, do: url
|
||||
defp truncate(url, len) do
|
||||
|
|
|
@ -62,6 +62,11 @@ defmodule AutoLinker.Parser do
|
|||
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, %{markdown: true} = opts) do
|
||||
text
|
||||
|> Builder.create_markdown_links(opts)
|
||||
|> do_parse(Map.delete(opts, :markdown))
|
||||
end
|
||||
defp do_parse(text, %{phone: _} = opts) do
|
||||
text
|
||||
|> do_parse(false, opts, {"", "", :parsing}, &check_and_link_phone/3)
|
||||
|
@ -79,13 +84,16 @@ defmodule AutoLinker.Parser do
|
|||
|
||||
defp do_parse(text, _), do: text
|
||||
|
||||
# state = {buffer, acc, state}
|
||||
|
||||
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)
|
||||
|
@ -131,7 +139,6 @@ defmodule AutoLinker.Parser do
|
|||
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)
|
||||
|
@ -154,7 +161,6 @@ defmodule AutoLinker.Parser do
|
|||
end
|
||||
|
||||
def is_url?(buffer, _) do
|
||||
# IO.puts "..... '#{buffer}'"
|
||||
if Regex.match? @invalid_url, buffer do
|
||||
false
|
||||
else
|
||||
|
|
2
mix.exs
2
mix.exs
|
@ -1,7 +1,7 @@
|
|||
defmodule AutoLinker.Mixfile do
|
||||
use Mix.Project
|
||||
|
||||
@version "0.2.1"
|
||||
@version "0.2.2"
|
||||
|
||||
def project do
|
||||
[
|
||||
|
|
|
@ -8,4 +8,19 @@ defmodule AutoLinkerTest do
|
|||
~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
|
||||
|
||||
end
|
||||
|
|
Reference in a new issue