From c28c02dd21fe5108392287504b5408e85f252e59 Mon Sep 17 00:00:00 2001 From: Artur Plysyuk Date: Fri, 16 Feb 2024 20:33:34 +0200 Subject: [PATCH] Add optional multibyte characters support, closes #21 --- README.md | 4 +++- lib/owl/data.ex | 14 ++++++++++++-- mix.exs | 1 + mix.lock | 1 + 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 29a8f36..12bc31a 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,9 @@ The package can be installed by adding `owl` to your list of dependencies in `mi ```elixir def deps do [ - {:owl, "~> 0.8"} + {:owl, "~> 0.8"}, + # ucwidth is an optional dependency, uncomment it for multibyte characters support (emoji, etc) + # {:ucwidth, "~> 0.2"} ] end ``` diff --git a/lib/owl/data.ex b/lib/owl/data.ex index 5139ccb..85dd208 100644 --- a/lib/owl/data.ex +++ b/lib/owl/data.ex @@ -171,10 +171,20 @@ defmodule Owl.Data do iex> Owl.Data.length(["222", Owl.Data.tag(["333", "444"], :green)]) 9 + + # if ucwidth dependency is present, then it is used to calculate the length of the string + iex> Owl.Data.length("😂") + 2 """ @spec length(t()) :: non_neg_integer() - def length(data) when is_binary(data) do - String.length(data) + if Code.ensure_loaded?(Ucwidth) do + def length(data) when is_binary(data) do + Ucwidth.width(data) + end + else + def length(data) when is_binary(data) do + String.length(data) + end end def length(data) when is_list(data) do diff --git a/mix.exs b/mix.exs index dc643b8..9504f68 100644 --- a/mix.exs +++ b/mix.exs @@ -47,6 +47,7 @@ defmodule Owl.MixProject do defp deps do [ + {:ucwidth, "~> 0.2", optional: true}, {:ex_doc, "~> 0.24", only: :dev, runtime: false}, {:excoveralls, "~> 0.10", only: :test}, {:dialyxir, "~> 1.0", only: :dev, runtime: false} diff --git a/mix.lock b/mix.lock index bcbe214..50b301c 100644 --- a/mix.lock +++ b/mix.lock @@ -16,5 +16,6 @@ "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, + "ucwidth": {:hex, :ucwidth, "0.2.0", "1f0a440f541d895dff142275b96355f7e91e15bca525d4a0cc788ea51f0e3441", [:mix], [], "hexpm", "c1efd1798b8eeb11fb2bec3cafa3dd9c0c3647bee020543f0340b996177355bf"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, }