packages feed

countable-inflections 0.1.0 → 0.2.0

raw patch · 5 files changed

+81/−78 lines, 5 filesdep +pcre-utilsdep +regex-pcre-builtindep −pcre-lightPVP ok

version bump matches the API change (PVP)

Dependencies added: pcre-utils, regex-pcre-builtin

Dependencies removed: pcre-light

API changes (from Hackage documentation)

Files

README.md view
@@ -26,16 +26,18 @@  These can also be given custom inflection matchers -```+```haskell λ: :t singularizeWith [Inflection] -> Text -> Text ```  There are 3 different types of transformations: -Match (takes a PCRE regex and a replacement string)+### Match -```+Takes a PCRE regex and a replacement string.++```haskell λ: :t makeMatchMapping [(RegexPattern, RegexReplace)] -> [Inflection] @@ -44,9 +46,11 @@ "octopi" ``` -Irregular (from singular to plural with no greater pattern)+### Irregular -```+From singular to plural with no greater pattern.++```haskell λ: :t makeIrregularMapping [(Singular, Plural)] -> [Inflection] @@ -55,8 +59,11 @@ "zombies" ``` -Uncountable (doesn't have a mapping, word stays the same) so it has the type:-```+### Uncountable++Doesn't have a mapping, word stays the same) so it has the type:++```haskell [Text] -> [Inflection] ``` 
Text/Countable.hs view
@@ -22,12 +22,13 @@   ) where -import Data.Maybe (catMaybes, fromMaybe)-import Data.Monoid ((<>))+import Data.Maybe (catMaybes, fromMaybe, isNothing) import Data.Text as T import Data.Text.Encoding (decodeUtf8, encodeUtf8) import Text.Countable.Data-import Text.Regex.PCRE.Light+import Text.Regex.PCRE.ByteString+import Text.Regex.PCRE.ByteString.Utils (substitute')+import System.IO.Unsafe  type RegexPattern = T.Text type RegexReplace = T.Text@@ -38,6 +39,8 @@   = Simple (Singular, Plural)   | Match (Maybe Regex, RegexReplace) +data MatchType = HasMatch | HasNoMatch+ -- | pluralize a word given a default mapping pluralize :: T.Text -> T.Text pluralize = pluralizeWith mapping@@ -108,34 +111,23 @@ runSub (Just reg, rep) t = matchWithReplace (reg, rep) t  matchWithReplace :: (Regex, RegexReplace) -> T.Text -> Maybe T.Text-matchWithReplace (reg, rep) t = do-  matched : grouping <- regexMatch t reg-  return $ (t `without` matched) <> groupReplace grouping rep+matchWithReplace (reg, rep) t = case regexMatch t reg of+  HasNoMatch -> Nothing+  HasMatch   -> toMaybe $ substitute' reg (encodeUtf8 t) (encodeUtf8 rep)   where-    without t1 t2 = if t2 == "" then t1 else T.replace t2 "" t1--groupReplace :: [T.Text] -> T.Text -> T.Text-groupReplace g rep =-  case g of-    [] -> rep-    (g':_) -> g' <> additions-    where-      rep' = tailMaybe $ T.split ((==) '\1') rep-      additions = T.concat $ fromMaybe [] rep'+    toMaybe = either (const Nothing) (Just . decodeUtf8) -regexMatch :: T.Text -> Regex -> Maybe [T.Text]-regexMatch t r = do-  bs <- match r (encodeUtf8 t) []-  return $ fmap decodeUtf8 bs+regexMatch :: T.Text -> Regex -> MatchType+regexMatch t r = case match of+                   Left _ -> HasNoMatch+                   Right m -> if isNothing m then HasNoMatch else HasMatch+  where match = unsafePerformIO $ execute r (encodeUtf8 t)  regexPattern :: T.Text -> Maybe Regex-regexPattern pat = toMaybe $ compileM (encodeUtf8 pat) [caseless]+regexPattern pat = toMaybe reg   where toMaybe = either (const Nothing) Just+        reg = unsafePerformIO $ compile compCaseless execBlank (encodeUtf8 pat)  headMaybe :: [a] -> Maybe a headMaybe [] = Nothing headMaybe (x:_) = Just x--tailMaybe :: [a] -> Maybe [a]-tailMaybe [] = Nothing-tailMaybe (_:xs) = Just xs
Text/Countable/Data.hs view
@@ -20,25 +20,25 @@ defaultPlurals' =   [ ("$", "s")   , ("s$", "s")-  , ("^(ax|test)is$", "\1es")-  , ("(octop|vir)us$", "\1i")-  , ("(octop|vir)i$", "\1i")-  , ("(alias|status)$", "\1es")-  , ("(bu)s$", "\1ses")-  , ("(buffal|tomat)o$", "\1oes")-  , ("([ti])um$", "\1a")-  , ("([ti])a$", "\1a")+  , ("^(ax|test)is$", "\\1es")+  , ("(octop|vir)us$", "\\1i")+  , ("(octop|vir)i$", "\\1i")+  , ("(alias|status)$", "\\1es")+  , ("(bu)s$", "\\1ses")+  , ("(buffal|tomat)o$", "\\1oes")+  , ("([ti])um$", "\\1a")+  , ("([ti])a$", "\\1a")   , ("sis$", "ses")-  , ("(?:([^f])fe|([lr])f)$", "\1\2ves")-  , ("(hive)$", "\1s")-  , ("([^aeiouy]|qu)y$", "\1ies")-  , ("(x|ch|ss|sh)$", "\1es")-  , ("(matr|vert|ind)(?:ix|ex)$", "\1ices")-  , ("^(m|l)ouse$", "\1ice")-  , ("^(m|l)ice$", "\1ice")-  , ("^(ox)$", "\1en")-  , ("^(oxen)$", "\1")-  , ("(quiz)$", "\1zes")+  , ("(?:([^f])fe|([lr])f)$", "\\1\2ves")+  , ("(hive)$", "\\1s")+  , ("([^aeiouy]|qu)y$", "\\1ies")+  , ("(x|ch|ss|sh)$", "\\1es")+  , ("(matr|vert|ind)(?:ix|ex)$", "\\1ices")+  , ("^(m|l)ouse$", "\\1ice")+  , ("^(m|l)ice$", "\\1ice")+  , ("^(ox)$", "\\1en")+  , ("^(oxen)$", "\\1")+  , ("(quiz)$", "\\1zes")   ]  -- |These default inflections stolen from the Ruby inflection library - see@@ -46,32 +46,32 @@ defaultSingulars' :: [(Text, Text)] defaultSingulars' =   [ ("s$", "")-  , ("(ss)$", "\1")-  , ("(n)ews$", "\1ews")-  , ("([ti])a$", "\1um")-  , ("((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$", "\1sis")-  , ("(^analy)(sis|ses)$", "\1sis")-  , ("([^f])ves$", "\1fe")-  , ("(hive)s$", "\1")-  , ("(tive)s$", "\1")-  , ("([lr])ves$", "\1f")-  , ("([^aeiouy]|qu)ies$", "\1y")-  , ("(s)eries$", "\1eries")-  , ("(m)ovies$", "\1ovie")-  , ("(x|ch|ss|sh)es$", "\1")-  , ("^(m|l)ice$", "\1ouse")-  , ("(bus)(es)?$", "\1")-  , ("(o)es$", "\1")-  , ("(shoe)s$", "\1")-  , ("(cris|test)(is|es)$", "\1is")-  , ("^(a)x[ie]s$", "\1xis")-  , ("(octop|vir)(us|i)$", "\1us")-  , ("(alias|status)(es)?$", "\1")-  , ("^(ox)en", "\1")-  , ("(vert|ind)ices$", "\1ex")-  , ("(matr)ices$", "\1ix")-  , ("(quiz)zes$", "\1")-  , ("(database)s$", "\1")+  , ("(ss)$", "\\1")+  , ("(n)ews$", "\\1ews")+  , ("([ti])a$", "\\1um")+  , ("((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$", "\\1sis")+  , ("(^analy)(sis|ses)$", "\\1sis")+  , ("([^f])ves$", "\\1fe")+  , ("(hive)s$", "\\1")+  , ("(tive)s$", "\\1")+  , ("([lr])ves$", "\\1f")+  , ("([^aeiouy]|qu)ies$", "\\1y")+  , ("(s)eries$", "\\1eries")+  , ("(m)ovies$", "\\1ovie")+  , ("(x|ch|ss|sh)es$", "\\1")+  , ("^(m|l)ice$", "\\1ouse")+  , ("(bus)(es)?$", "\\1")+  , ("(o)es$", "\\1")+  , ("(shoe)s$", "\\1")+  , ("(cris|test)(is|es)$", "\\1is")+  , ("^(a)x[ie]s$", "\\1xis")+  , ("(octop|vir)(us|i)$", "\\1us")+  , ("(alias|status)(es)?$", "\\1")+  , ("^(ox)en", "\\1")+  , ("(vert|ind)ices$", "\\1ex")+  , ("(matr)ices$", "\\1ix")+  , ("(quiz)zes$", "\\1")+  , ("(database)s$", "\\1")   ]  -- |These default irregular inflections stolen from the Ruby inflection library - see
countable-inflections.cabal view
@@ -1,5 +1,5 @@ name:                countable-inflections-version:             0.1.0+version:             0.2.0 synopsis:            Countable Text Inflections description:   Provides methods for singularizing and pluralizing text.@@ -35,7 +35,8 @@       base         >= 4.6   && < 4.10     , exceptions   >= 0.6   && < 0.9     , text         >= 0.2   && < 1.3-    , pcre-light+    , regex-pcre-builtin+    , pcre-utils     , bytestring   default-language:    Haskell2010 
test/Text/CountableSpec.hs view
@@ -36,6 +36,9 @@       singularize "mice" `shouldBe` "mouse"       singularize "oxen" `shouldBe` "ox"       singularize "branches" `shouldBe` "branch"+      singularize "transactions" `shouldBe` "transaction"+      singularize "sessions" `shouldBe` "session"+      singularize "users" `shouldBe` "user"   irregularCases :: Spec