glugify/slugger
A stateful slugger that guarantees unique slugs across a batch of inputs — the building block for tables of contents, static site generators and CMS imports, where two posts titled “Hello” must not share a URL.
The state is an immutable value threaded through each call, so it works naturally in folds and works identically on the Erlang and JavaScript targets:
import glugify/slugger
let s = slugger.new()
let #(s, a) = slugger.slug(s, "Hello World")
let #(s, b) = slugger.slug(s, "Hello World")
let #(_, c) = slugger.slug(s, "Hello World")
// a -> "hello-world"
// b -> "hello-world-1"
// c -> "hello-world-2"
Types
Values
pub fn slug(slugger: Slugger, text: String) -> #(Slugger, String)
Slugifies text with the default configuration and makes the result
unique against everything this slugger has produced before, by
appending -1, -2, … to duplicates.
Unlike github-slugger, a suffixed slug never collides with a slug
produced from genuinely suffixed input: "foo", "foo", "foo-1"
yields "foo", "foo-1", "foo-1-1".
Empty results (e.g. from symbol-only input) bypass uniqueness and are returned as-is.
Examples
let #(slugger, first) = slug(new(), "My Post")
let #(_, second) = slug(slugger, "My Post")
// first -> "my-post"
// second -> "my-post-1"
pub fn slug_with(
slugger: Slugger,
text: String,
config: config.Config,
) -> Result(#(Slugger, String), errors.SlugifyError)
Like slug, but slugifies with a custom configuration.
Examples
import glugify/config
let cfg = config.default() |> config.with_separator("_")
slug_with(new(), "My Post", cfg)
// -> Ok(#(slugger, "my_post"))