Current section
Files
Jump to
Current section
Files
src/glugify.erl
-module(glugify).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/glugify.gleam").
-export([slugify_with/2, try_slugify/1, slugify/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-file("src/glugify.gleam", 144).
-spec apply_preserve_options(binary(), binary(), glugify@config:config()) -> binary().
apply_preserve_options(Slug, Input, Config) ->
Slug@1 = case (erlang:element(9, Config) andalso gleam_stdlib:string_starts_with(
Input,
<<"_"/utf8>>
))
andalso not gleam_stdlib:string_starts_with(Slug, <<"_"/utf8>>) of
true ->
<<"_"/utf8, Slug/binary>>;
false ->
Slug
end,
case ((erlang:element(10, Config) andalso gleam_stdlib:string_ends_with(
Input,
<<"-"/utf8>>
))
andalso (erlang:element(2, Config) /= <<""/utf8>>))
andalso not gleam_stdlib:string_ends_with(Slug@1, erlang:element(2, Config)) of
true ->
<<Slug@1/binary, (erlang:element(2, Config))/binary>>;
false ->
Slug@1
end.
-file("src/glugify.gleam", 70).
?DOC(
" Converts text to a URL-friendly slug using custom configuration.\n"
" This is the most flexible API that allows full control over the slugification process.\n"
" \n"
" ## Examples\n"
" \n"
" ```gleam\n"
" import glugify/config\n"
" \n"
" let custom_config = config.default()\n"
" |> config.with_separator(\"_\")\n"
" |> config.with_max_length(20)\n"
" \n"
" slugify_with(\"A Very Long Title\", custom_config)\n"
" // -> Ok(\"a_very_long_title\")\n"
" ```\n"
" \n"
" ## Errors\n"
" \n"
" - `EmptyInput`: When the input text is empty\n"
" - `ConfigurationError`: When the configuration is invalid\n"
" - `TransliterationFailed`: When a character cannot be transliterated\n"
).
-spec slugify_with(binary(), glugify@config:config()) -> {ok, binary()} |
{error, glugify@errors:slugify_error()}.
slugify_with(Text, Config) ->
gleam@result:'try'(case glugify@config:validate_config(Config) of
{ok, _} ->
{ok, nil};
{error, Msg} ->
{error, {configuration_error, Msg}}
end, fun(_) ->
gleam@result:'try'(
glugify@internal@validators:validate_input(Text),
fun(Validated) ->
Decoded = case erlang:element(15, Config) of
true ->
glugify@internal@entities:decode(Validated);
false ->
Validated
end,
gleam@result:'try'(
glugify@internal@processors:normalize_whitespace(
Decoded
),
fun(Normalized) ->
gleam@result:'try'(
case erlang:element(14, Config) of
true ->
glugify@internal@processors:decamelize(
Normalized
);
false ->
{ok, Normalized}
end,
fun(Decamelized) ->
gleam@result:'try'(
glugify@internal@processors:apply_custom_replacements(
Decamelized,
erlang:element(8, Config)
),
fun(With_custom_replacements) ->
gleam@result:'try'(
case erlang:element(6, Config) of
true ->
glugify@unicode:transliterate_text_with(
With_custom_replacements,
erlang:element(
13,
Config
),
erlang:element(
16,
Config
)
);
false ->
glugify@unicode:validate_ascii_or_unicode(
With_custom_replacements,
erlang:element(
7,
Config
),
erlang:element(
16,
Config
)
)
end,
fun(Transliterated) ->
gleam@result:'try'(
glugify@internal@processors:normalize_whitespace(
Transliterated
),
fun(
Normalized_after_transliteration
) ->
gleam@result:'try'(
begin
Result = case erlang:element(
3,
Config
) of
true ->
string:lowercase(
Normalized_after_transliteration
);
false ->
Normalized_after_transliteration
end,
{ok, Result}
end,
fun(Lowercased) ->
gleam@result:'try'(
glugify@internal@processors:apply_separators(
Lowercased,
Config
),
fun(
Separated
) ->
gleam@result:'try'(
glugify@internal@processors:remove_invalid_chars(
Separated,
Config
),
fun(
Cleaned
) ->
gleam@result:'try'(
glugify@internal@processors:collapse_separators(
Cleaned,
Config
),
fun(
Collapsed
) ->
gleam@result:'try'(
glugify@internal@processors:filter_stop_words(
Collapsed,
erlang:element(
11,
Config
),
erlang:element(
2,
Config
)
),
fun(
Without_stop_words
) ->
gleam@result:'try'(
glugify@internal@processors:trim_separators(
Without_stop_words,
Config
),
fun(
Trimmed
) ->
gleam@result:'try'(
case erlang:element(
4,
Config
) of
{some,
Len} ->
glugify@internal@processors:truncate_slug(
Trimmed,
Len,
erlang:element(
5,
Config
),
erlang:element(
2,
Config
)
);
none ->
{ok,
Trimmed}
end,
fun(
Truncated
) ->
{ok,
apply_preserve_options(
Truncated,
Text,
Config
)}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end).
-file("src/glugify.gleam", 45).
?DOC(
" Converts text to a URL-friendly slug with explicit error handling.\n"
" Returns `Result(String, SlugifyError)` for cases where you need to handle errors.\n"
" \n"
" ## Examples\n"
" \n"
" ```gleam\n"
" try_slugify(\"My Blog Post\")\n"
" // -> Ok(\"my-blog-post\")\n"
" \n"
" try_slugify(\"\")\n"
" // -> Error(EmptyInput)\n"
" ```\n"
).
-spec try_slugify(binary()) -> {ok, binary()} |
{error, glugify@errors:slugify_error()}.
try_slugify(Text) ->
slugify_with(Text, glugify@config:default()).
-file("src/glugify.gleam", 26).
?DOC(
" Converts text to a URL-friendly slug using default configuration.\n"
" This is the simplest API that always returns a string.\n"
" \n"
" ## Examples\n"
" \n"
" ```gleam\n"
" slugify(\"Hello, World!\")\n"
" // -> \"hello-world\"\n"
" \n"
" slugify(\"Café & Restaurant\")\n"
" // -> \"cafe-and-restaurant\"\n"
" ```\n"
" \n"
" If the input cannot be processed, returns an empty string.\n"
" For error handling, use `try_slugify` instead.\n"
).
-spec slugify(binary()) -> binary().
slugify(Text) ->
case try_slugify(Text) of
{ok, Slug} ->
Slug;
{error, _} ->
<<""/utf8>>
end.