Current section
Files
Jump to
Current section
Files
lib/fermo_slugger.ex
defmodule FermoSlugger do
@moduledoc """
Create slugs from id and text
"""
@doc ~S"""
Returns a slug, combining id and title.
## Example
iex> FermoSlugger.slug(123, "ciao")
"123-ciao"
## Normalization
Punctuation is replaced by '-':
iex> FermoSlugger.slug(123, "S&P")
"123-s-p"
The text is downcased:
iex> FermoSlugger.slug(123, "AAAAA")
"123-aaaaa"
Non-Latin characters are transliterated:
iex> FermoSlugger.slug(123, "andò")
"123-ando"
Separator characters are converted to '-':
iex> FermoSlugger.slug(123, "R&R")
"123-r-r"
Leading '-' is removed:
iex> FermoSlugger.slug(123, "-1")
"123-1"
Trailing '-' is removed:
iex> FermoSlugger.slug(123, "1-")
"123-1"
The text part is capped at 51 characters:
iex> FermoSlugger.slug(123, String.duplicate("a", 100))
"123-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"""
@max_text 51
@transform_to_hyphen ~r([‐' ’,&+.#/@!:°])u
def slug(id, title, options \\ []) do
max_text = options[:max_text] || @max_text
clean =
:unicode.characters_to_nfd_binary(title)
|> String.replace(@transform_to_hyphen, "-")
|> String.replace("ø", "o")
|> String.replace(~r/[^0-9\-A-z]/u, "")
|> String.downcase
stripped =
String.replace_leading(clean, "-", "")
|> String.replace_trailing("-", "")
deduped = String.replace(stripped, ~r/\-\-+/u, "-")
sliced = String.slice(deduped, 0, max_text)
"#{id}-#{sliced}"
end
end