-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | Haskell implementation of the Unicode Collation Algorithm
--   
--   This library provides a pure Haskell implementation of the Unicode
--   Collation Algorithm described at
--   http://www.unicode.org/reports/tr10/. It is not as
--   fully-featured or as performant as text-icu, but it avoids a
--   dependency on a large C library. Locale-specific tailorings are also
--   provided.
@package unicode-collation
@version 0.1.3.6

module Text.Collate.Lang

-- | Represents a BCP 47 language tag
--   (https://tools.ietf.org/html/bcp47).
data Lang
Lang :: Text -> Maybe Text -> Maybe Text -> [Text] -> [(Text, [(Text, Text)])] -> [Text] -> Lang
[langLanguage] :: Lang -> Text
[langScript] :: Lang -> Maybe Text
[langRegion] :: Lang -> Maybe Text
[langVariants] :: Lang -> [Text]
[langExtensions] :: Lang -> [(Text, [(Text, Text)])]
[langPrivateUse] :: Lang -> [Text]

-- | Parse a BCP 47 language tag as a Lang.
parseLang :: Text -> Either String Lang

-- | Render a Lang in BCP 47 form.
renderLang :: Lang -> Text

-- | Find best match for a Lang in an association list.
lookupLang :: Lang -> [(Lang, a)] -> Maybe (Lang, a)
instance Data.Binary.Class.Binary Text.Collate.Lang.Lang
instance GHC.Classes.Eq Text.Collate.Lang.Lang
instance GHC.Internal.Data.String.IsString Text.Collate.Lang.Lang
instance Language.Haskell.TH.Syntax.Lift Text.Collate.Lang.Lang
instance GHC.Classes.Ord Text.Collate.Lang.Lang
instance GHC.Internal.Show.Show Text.Collate.Lang.Lang

-- | We define our own normalization function instead of depending on
--   unicode-transforms, because we need a lazy (streaming) normalization
--   function for maximum efficiency. No point normalizing two whole
--   Texts if we can see from the first few characters how they
--   should be ordered. See https://unicode.org/reports/tr15/ for a
--   description of the algorithm implemented here.
module Text.Collate.Normalize

-- | Lazily normalize a list of code points to its canonical decomposition
--   (NFD).
toNFD :: [Int] -> [Int]

-- | This library provides a pure Haskell implementation of the Unicode
--   Collation Algorithm, allowing proper sorting of Unicode strings.
--   
--   The simplest way to use the library is to use the IsString
--   instance of Collator (together with the
--   OverloadedStrings extension):
--   
--   
--   >>> import Data.List (sortBy)
--   
--   >>> import qualified Data.Text.IO as T
--   
--   >>> mapM_ T.putStrLn $ sortBy (collate "en-US") ["𝒶bc","abC","𝕒bc","Abc","abç","äbc"]
--   abC
--   𝒶bc
--   𝕒bc
--   Abc
--   abç
--   äbc
--   
--   
--   Note the difference from the default sort:
--   
--   
--   >>> import Data.List (sort)
--   
--   >>> import qualified Data.Text.IO as T
--   
--   >>> mapM_ T.putStrLn $ sort ["𝒶bc","abC","𝕒bc","Abc","abç","äbc"]
--   Abc
--   abC
--   abç
--   äbc
--   𝒶bc
--   𝕒bc
--   
--   
--   A Collator provides a function collate that compares two
--   texts, and a function sortKey that returns the sort key. Most
--   users will just need collate.
--   
--   
--   >>> let de = collatorFor "de"
--   
--   >>> let se = collatorFor "se"
--   
--   >>> collate de "ö" "z"
--   LT
--   
--   >>> collate se "ö" "z"
--   GT
--   
--   >>> sortKey de "ö"
--   SortKey [0x213C,0x0000,0x0020,0x002B,0x0000,0x0002,0x0002]
--   
--   >>> sortKey se "ö"
--   SortKey [0x22FD,0x0000,0x0020,0x0000,0x0002]
--   
--   
--   To sort a string type other than Text, the function
--   collateWithUnpacker may be used. It takes as a parameter a
--   function that lazily unpacks the string type into a list of
--   Char.
--   
--   
--   >>> let seCollateString = collateWithUnpacker "se" id
--   
--   >>> seCollateString ("ö" :: String) ("z" :: String)
--   GT
--   
--   
--   Because Collator and Lang have IsString
--   instances, you can just specify them using string literals, as in the
--   above examples. Note, however, that you won't get any feedback if the
--   string doesn't parse correctly as a BCP47 language tag, or if no
--   collation is defined for the specified language; instead, you'll just
--   get the default (root) collator. For this reason, we don't recommend
--   relying on the IsString instance.
--   
--   If you won't know the language until run time, use parseLang to
--   parse it to a Lang, handling parse errors, and then pass the
--   Lang to collatorFor.
--   
--   
--   >>> let handleParseError = error  -- or something fancier
--   
--   >>> lang <- either handleParseError return $ parseLang "bs-Cyrl"
--   
--   >>> collate (collatorFor lang) "a" "b"
--   LT
--   
--   
--   If you know the language at compile-time, use the collator
--   quasi-quoter and you'll get compile-time errors and warnings:
--   
--   
--   >>> :set -XQuasiQuotes
--   
--   >>> let esTraditional = [collator|es-u-co-trad|]
--   
--   >>> let esStandard = [collator|es|]
--   
--   >>> collate esStandard "Co" "Ch"
--   GT
--   
--   >>> collate esTraditional "Co" "Ch"
--   LT
--   
--   
--   Note that the unicode extension syntax for BCP47 can be used to
--   specify a particular collation for the language (here, Spanish
--   "traditional" instead of the default ordering; the alias trad
--   is used because of length limits for BCP47 keywords).
--   
--   The extension syntax can also be used to set collator options. The
--   keyword kb can be used to specify the "backwards" accent
--   sorting that is sometimes used in French:
--   
--   
--   >>> collate "fr" "côte" "coté"
--   GT
--   
--   >>> collate "fr-u-kb" "côte" "coté"
--   LT
--   
--   
--   The keyword ka can be used to specify the variable weighting
--   options which affect how punctuation and whitespace are treated:
--   
--   
--   >>> collate "en-u-ka-shifted" "de-luge" "de Luge"
--   LT
--   
--   >>> collate "en-u-ka-noignore" "de-luge" "de Luge"
--   GT
--   
--   
--   The keyword kk can be used to turn off the normalization step
--   (which is required by the algorithm but can be omitted for better
--   performance if the input is already in NFD form (canonical
--   decomposition).
--   
--   
--   >>> let noNormalizeCollator = [collator|en-u-kk-false|]
--   
--   
--   The keyword kf can be used to say whether uppercase or
--   lowercase letters should be sorted first.
--   
--   
--   >>> collate "en-u-kf-upper" "A" "a"
--   LT
--   
--   >>> collate "en-u-kf-lower" "A" "a"
--   GT
--   
--   
--   These options be combined:
--   
--   
--   >>> collate "de-DE-u-co-phonebk-kb-false-ka-shifted" "Udet" "Über"
--   LT
--   
--   
--   Options can also be set using the functions
--   setVariableWeighting, setNormalization,
--   setUpperBeforeLower, and setFrenchAccents:
--   
--   
--   >>> let frC = setFrenchAccents True [collator|fr|]
--   
--   >>> collate frC "côte" "coté"
--   LT
--   
module Text.Collate
data Collator

-- | Compare two Texts
collate :: Collator -> Text -> Text -> Ordering

-- | Compare two strings of any type that can be unpacked lazily into a
--   list of Chars.
collateWithUnpacker :: Collator -> forall a. Eq a => (a -> [Char]) -> a -> a -> Ordering

-- | Returns a collator based on a BCP 47 language tag. If no exact match
--   is found, we try to find the best match (falling back to the root
--   collation if nothing else succeeds). If something other than the
--   default collation for a language is desired, the co keyword
--   of the unicode extensions can be used (e.g. es-u-co-trad for
--   traditional Spanish). Other unicode extensions affect the collator
--   options:
--   
--   
--   
- The kb keyword has the same effect as
--   setFrenchAccents (e.g. fr-FR-u-kb-true).
--   
- The ka keyword has the same effect as
--   setVariableWeight (e.g. fr-FR-u-kb-ka-shifted or
--   en-u-ka-noignore).
--   
- The kf keyword has the same effect as
--   setUpperBeforeLower (e.g. fr-u-kf-upper or
--   fr-u-kf-lower).
--   
- The kk keyword has the same effect as
--   setNormalization (e.g. fr-u-kk-false).
--   
collatorFor :: Lang -> Collator

-- | Create a collator at compile time based on a BCP 47 language tag:
--   e.g., [collator|es-u-co-trad|]. Requires the
--   QuasiQuotes extension.
collator :: QuasiQuoter

-- | Default collator based on DUCET table (allkeys.txt).
rootCollator :: Collator
newtype SortKey
SortKey :: [Word16] -> SortKey

-- | The sort key used to compare a Text
sortKey :: Collator -> Text -> SortKey

-- | Render sort key in the manner used in the CLDR collation test data:
--   the character '|' is used to separate the levels of the key and
--   corresponds to a 0 in the actual sort key.
renderSortKey :: SortKey -> String

-- | VariableWeighting affects how punctuation is treated. See
--   http://www.unicode.org/reports/tr10/#Variable_Weighting.
data VariableWeighting

-- | Don't ignore punctuation (Deluge < deluge-)
NonIgnorable :: VariableWeighting

-- | Completely ignore punctuation (Deluge = deluge-)
Blanked :: VariableWeighting

-- | Consider punctuation at lower priority (de-luge < delu-ge <
--   deluge < deluge- < Deluge)
Shifted :: VariableWeighting

-- | Variant of Shifted (deluge < de-luge < delu-ge)
ShiftTrimmed :: VariableWeighting
data CollatorOptions
CollatorOptions :: Maybe Lang -> VariableWeighting -> Bool -> Bool -> Bool -> CollatorOptions

-- | Lang used for tailoring. Note that because of fallback rules,
--   this may be somewhat different from the Lang passed to
--   collatorFor. This Lang won't contain unicode extensions
--   used to set options, but it will specify the collation if a
--   non-default collation is being used.
[optLang] :: CollatorOptions -> Maybe Lang

-- | Method for handling variable elements (see
--   http://www.unicode.org/reports/tr10/, Tables 11 and 12).
[optVariableWeighting] :: CollatorOptions -> VariableWeighting

-- | If True, secondary weights are scanned in reverse order, so we get the
--   sorting "cote côte coté côté" instead of "cote coté côte côté"
[optFrenchAccents] :: CollatorOptions -> Bool

-- | Sort uppercase letters before lower
[optUpperBeforeLower] :: CollatorOptions -> Bool

-- | If True, strings are normalized to NFD before collation elements are
--   constructed. If the input is already normalized, this option can be
--   set to False for better performance.
[optNormalize] :: CollatorOptions -> Bool

-- | The options used for this Collator
collatorOptions :: Collator -> CollatorOptions

-- | Lang used for tailoring. Because of fallback rules, this may be
--   somewhat different from the Lang passed to collatorFor.
--   This Lang won't contain unicode extensions used to set options,
--   but it will specify the collation if a non-default collation is being
--   used.

-- | Deprecated: Use (optLang . collatorOptions)
collatorLang :: Collator -> Maybe Lang

-- | Set method for handling variable elements (punctuation and spaces):
--   see http://www.unicode.org/reports/tr10/, Tables 11 and 12.
setVariableWeighting :: VariableWeighting -> Collator -> Collator

-- | The Unicode Collation Algorithm expects input to be normalized into
--   its canonical decomposition (NFD). By default, collators perform this
--   normalization. If your input is already normalized, you can increase
--   performance by disabling this step: setNormalization False.
setNormalization :: Bool -> Collator -> Collator

-- | setFrenchAccents True causes secondary weights to be scanned
--   in reverse order, so we get the sorting cote côte coté côté
--   instead of cote coté côte côté. The default is usually
--   False, except for fr-CA where it is True.
setFrenchAccents :: Bool -> Collator -> Collator

-- | Most collations default to sorting lowercase letters before uppercase
--   (exceptions: mt, da, cu). To select the
--   opposite behavior, use setUpperBeforeLower True.
setUpperBeforeLower :: Bool -> Collator -> Collator

-- | An association list matching Langs with tailored
--   Collations.
tailorings :: [(Lang, Collation)]
