commit: dd3d13561164b55a98596a30793d2b2ae16ac016
Author: Stephen M. Pallen <smpallen99@yahoo.com>
Date: Wed, 29 Mar 2017 10:11:22 -0400
create project and some linker impl
Diffstat:
7 files changed, 184 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,20 @@
+# The directory Mix will write compiled artifacts to.
+/_build
+
+# If you run "mix test --cover", coverage assets end up here.
+/cover
+
+# The directory Mix downloads your dependencies sources to.
+/deps
+
+# Where 3rd-party dependencies like ExDoc output generated docs.
+/doc
+
+# Ignore .fetch files in case you like to edit your project deps locally.
+/.fetch
+
+# If the VM crashes, it generates a dump, let's ignore it too.
+erl_crash.dump
+
+# Also ignore archive artifacts (built via "mix archive.build").
+*.ez
diff --git a/README.md b/README.md
@@ -0,0 +1,19 @@
+# AutoLinker
+
+**TODO: Add description**
+
+## Installation
+
+If [available in Hex](https://hex.pm/docs/publish), the package can be installed
+by adding `auto_linker` to your list of dependencies in `mix.exs`:
+
+```elixir
+def deps do
+ [{:auto_linker, "~> 0.1.0"}]
+end
+```
+
+Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
+and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
+be found at [https://hexdocs.pm/auto_linker](https://hexdocs.pm/auto_linker).
+
diff --git a/config/config.exs b/config/config.exs
@@ -0,0 +1,30 @@
+# This file is responsible for configuring your application
+# and its dependencies with the aid of the Mix.Config module.
+use Mix.Config
+
+# This configuration is loaded before any dependency and is restricted
+# to this project. If another project depends on this project, this
+# file won't be loaded nor affect the parent project. For this reason,
+# if you want to provide default values for your application for
+# 3rd-party users, it should be done in your "mix.exs" file.
+
+# You can configure for your application as:
+#
+# config :auto_linker, key: :value
+#
+# And access this configuration in your application as:
+#
+# Application.get_env(:auto_linker, :key)
+#
+# Or configure a 3rd-party app:
+#
+# config :logger, level: :info
+#
+
+# It is also possible to import configuration files, relative to this
+# directory. For example, you can emulate configuration per environment
+# by uncommenting the line below and defining dev.exs, test.exs and such.
+# Configuration from the imported file will override the ones defined
+# here (which is why it is important to import them last).
+#
+# import_config "#{Mix.env}.exs"
diff --git a/lib/auto_linker.ex b/lib/auto_linker.ex
@@ -0,0 +1,73 @@
+defmodule AutoLinker do
+ @moduledoc """
+ Documentation for AutoLinker.
+ """
+
+ def link(text, opts \\ []) do
+ opts =
+ :url_linker
+ |> Application.get_all_env()
+ |> Keyword.merge(opts)
+
+ # rel = opts[:rel] || "noopener noreferrer"
+ # new_window if opts[:target]
+ end
+
+ # state = {buffer, acc, state}
+ defp parse(text, opts) do
+ parse(text, Keyword.get(opts, :scheme, false), {"", "", false})
+ end
+
+ defp parse("", _scheme, opts ,{_, acc, _}), do: acc
+
+ defp parse(text, scheme, opts, {buffer, acc, state}) do
+ acc <> create_link(text, opts)
+ parse("", scheme, opts, {buffer, acc, state})
+ end
+
+ defp create_link(url, opts) do
+ []
+ |> build_attrs(url, opts, :rel)
+ |> build_attrs(url, opts, :target)
+ |> build_attrs(url, opts, :scheme)
+ |> build_url(url, opts)
+ end
+
+ defp build_attrs(attrs, _, opts, :rel) do
+ if rel = Keyword.get(opts, :rel, "noopener noreferrer"),
+ do: [{:rel, rel} | attrs], else: attrs
+ end
+ defp build_attrs(attrs, _, opts, :target) do
+ if Keyword.get(opts, :new_window, true),
+ do: [{:target, :_blank} | attrs], else: attrs
+ end
+ defp build_attrs(attrs, url, opts, :scheme) do
+ if String.starts_with?(url, ["http://", "https://"]),
+ do: [{:href, url} | attrs], else: [{:href, "http://" <> url} | attrs]
+ end
+
+ defp format_url(attrs, url, opts) do
+ url =
+ url
+ |> strip_prefix(Keyword.get(opts, :strip_prefix, true))
+ |> truncate(Keyword.get(opts, :truncate, false))
+ attrs =
+ attrs
+ |> Enum.map(fn {key, value} -> ~s(#{key}='#{value}') end)
+ |> Enum.join(" ")
+ "<a #{attrs}>" <> url <> "</a>"
+ end
+
+ defp truncate(url, false), do: url
+ defp truncate(url, len) when len < 3, do: url
+ defp truncate(url, len) do
+ if String.length(url) > len, do: String.slice(url, 0, len - 2) <> "..", else: url
+ end
+
+ defp strip_prefix(url, true) do
+ url
+ |> String.replace(~r/^https?:\/\//, "")
+ |> String.replace(~r/^www\./, "")
+ end
+ defp strip_prefix(url, _), do: url
+end
diff --git a/mix.exs b/mix.exs
@@ -0,0 +1,33 @@
+defmodule AutoLinker.Mixfile do
+ use Mix.Project
+
+ def project do
+ [app: :auto_linker,
+ version: "0.1.0",
+ elixir: "~> 1.4",
+ build_embedded: Mix.env == :prod,
+ start_permanent: Mix.env == :prod,
+ deps: deps()]
+ end
+
+ # Configuration for the OTP application
+ #
+ # Type "mix help compile.app" for more information
+ def application do
+ # Specify extra applications you'll use from Erlang/Elixir
+ [extra_applications: [:logger]]
+ end
+
+ # Dependencies can be Hex packages:
+ #
+ # {:my_dep, "~> 0.3.0"}
+ #
+ # Or git/path repositories:
+ #
+ # {:my_dep, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
+ #
+ # Type "mix help deps" for more examples and options
+ defp deps do
+ []
+ end
+end
diff --git a/test/auto_linker_test.exs b/test/auto_linker_test.exs
@@ -0,0 +1,8 @@
+defmodule AutoLinkerTest do
+ use ExUnit.Case
+ doctest AutoLinker
+
+ test "the truth" do
+ assert 1 + 1 == 2
+ end
+end
diff --git a/test/test_helper.exs b/test/test_helper.exs
@@ -0,0 +1 @@
+ExUnit.start()