# `GoSaveTool.Text`

Word, character and reading-time counts, social media character limits, case changes, URL slugs and
whitespace cleanup. The Elixir version of `@gosavetool/text`.

Online counter: https://www.gosavetool.com/character-counter

    iex> GoSaveTool.Text.title("the lord of the rings: return of the king")
    "The Lord of the Rings: Return of the King"

    iex> GoSaveTool.Text.slug("Ölçü Birimi & Çeviri!")
    "olcu-birimi-ceviri"

Characters are Unicode code points, so an emoji counts as one (not graphemes, as `String.length/1` counts).

# `camel`

```elixir
@spec camel(String.t()) :: String.t()
```

# `check_limits`

```elixir
@spec check_limits(String.t(), [String.t()] | nil) :: %{required(String.t()) =&gt; map()}
```

How the text meets each limit: `%{"x-post" => %{limit: 280, used: 120, left: 160, fits: true}, ...}`.
Pass a list of fields to check only those.

# `clean`

```elixir
@spec clean(String.t()) :: String.t()
```

Removes trailing spaces, runs of spaces and more than one blank line in a row.

# `kebab`

```elixir
@spec kebab(String.t()) :: String.t()
```

# `limits`

```elixir
@spec limits() :: [{String.t(), pos_integer()}]
```

Character limits of common fields, in display order. SEO values are the length search results show before
cutting.

# `lower`

```elixir
@spec lower(String.t()) :: String.t()
```

# `sentence`

```elixir
@spec sentence(String.t()) :: String.t()
```

Sentence case.

    iex> GoSaveTool.Text.sentence("HELLO WORLD. how ARE you?")
    "Hello world. How are you?"

# `slug`

```elixir
@spec slug(String.t()) :: String.t()
```

URL slug, with Turkish and accented letters.

# `snake`

```elixir
@spec snake(String.t()) :: String.t()
```

# `stats`

```elixir
@spec stats(String.t()) :: map()
```

Words, characters, lines, sentences and reading time (238 words a minute) of a text.

    iex> GoSaveTool.Text.stats("Hello world. It’s 2026!")
    %{words: 4, chars: 23, chars_no_spaces: 20, lines: 1, sentences: 2, read_seconds: 1}

# `title`

```elixir
@spec title(String.t()) :: String.t()
```

Title Case. Short words (a, of, the, and...) stay in lower case unless they start the text or follow a colon.

# `upper`

```elixir
@spec upper(String.t()) :: String.t()
```

# `words`

```elixir
@spec words(String.t()) :: [String.t()]
```

Words for camelCase and the like.

    iex> GoSaveTool.Text.words("bestPostingTime 2")
    ["best", "Posting", "Time", "2"]

---

*Consult [api-reference.md](api-reference.md) for complete listing*
