    {-# LANGUAGE CPP #-}
    {-# LANGUAGE OverloadedStrings #-}
    module Citeproc.Unicode
      ( Lang(..),
        parseLang,
        renderLang,
        lookupLang,
        toUpper,
        toLower,
        comp
      )
    where
    import Text.Collate.Lang (Lang(..), parseLang, renderLang, lookupLang)
    #ifdef MIN_VERSION_text_icu
    import qualified Data.Text.ICU as ICU
    import qualified Data.Text.ICU.Collate as ICUC
    #else
    import qualified Text.Collate as U
    #endif
    import Data.Text (Text)
    import qualified Data.Text as T
    import Data.Maybe (fromMaybe)

    #ifdef MIN_VERSION_text_icu
    toICULocale :: Maybe Lang -> ICU.LocaleName
    toICULocale Nothing = ICU.Current
    toICULocale (Just l) = ICU.Locale (T.unpack (renderLang l))
    #endif

    toUpper :: Maybe Lang -> Text -> Text
    #ifdef MIN_VERSION_text_icu
    toUpper mblang =
       ICU.toUpper (toICULocale mblang)
    #else
    toUpper :: Maybe Lang -> Text -> Text
    toUpper Maybe Lang
    mblang = Text -> Text
    T.toUpper (Text -> Text) -> (Text -> Text) -> Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
      case Lang -> Text
    langLanguage (Lang -> Text) -> Maybe Lang -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Maybe Lang
    mblang of
        Just Text
    "tr" -> (Char -> Char) -> Text -> Text
    T.map (\Char
    c -> case Char
    c of
                                    Char
    'i' -> Char
    'İ'
                                    Char
    'ı' -> Char
    'I'
                                    Char
    _   -> Char
    c)
        Maybe Text
    _         -> Text -> Text
    forall a. a -> a
    id
    #endif

    toLower :: Maybe Lang -> Text -> Text
    #ifdef MIN_VERSION_text_icu
    toLower mblang =
       ICU.toLower (toICULocale mblang)
    #else
    toLower :: Maybe Lang -> Text -> Text
    toLower Maybe Lang
    mblang = Text -> Text
    T.toLower (Text -> Text) -> (Text -> Text) -> Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
      case Lang -> Text
    langLanguage (Lang -> Text) -> Maybe Lang -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Maybe Lang
    mblang of
        Just Text
    "tr" -> (Char -> Char) -> Text -> Text
    T.map (\Char
    c -> case Char
    c of
                                    Char
    'İ' -> Char
    'i'
                                    Char
    'I' -> Char
    'ı'
                                    Char
    _   -> Char
    c)
        Maybe Text
    _         -> Text -> Text
    forall a. a -> a
    id
    #endif

    comp :: Maybe Lang -> Text -> Text -> Ordering
    #ifdef MIN_VERSION_text_icu
    comp mblang = ICU.collate collator
     where
      collator = ICU.collatorWith (toICULocale mblang) [ICUC.AlternateHandling alt]
      alt = case mblang >>= lookup "u" . langExtensions >>= lookup "ka" of
              Just "noignore" -> ICUC.NonIgnorable
              _ -> ICUC.Shifted
    #else
    comp :: Maybe Lang -> Text -> Text -> Ordering
    comp Maybe Lang
    mblang = Collator -> Text -> Text -> Ordering
    U.collate Collator
    coll
     where
      lang :: Lang
    lang = Lang -> Maybe Lang -> Lang
    forall a. a -> Maybe a -> a
    fromMaybe (Text
    -> Maybe Text
    -> Maybe Text
    -> [Text]
    -> [(Text, [(Text, Text)])]
    -> [Text]
    -> Lang
    Lang Text
    "" Maybe Text
    forall a. Maybe a
    Nothing Maybe Text
    forall a. Maybe a
    Nothing [] [] []) Maybe Lang
    mblang
      coll :: Collator
    coll = case Text -> [(Text, [(Text, Text)])] -> Maybe [(Text, Text)]
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup Text
    "u" (Lang -> [(Text, [(Text, Text)])]
    langExtensions Lang
    lang) Maybe [(Text, Text)]
    -> ([(Text, Text)] -> Maybe Text) -> Maybe Text
    forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Text -> [(Text, Text)] -> Maybe Text
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup Text
    "ka" of
               -- default to Shifted variable weighting, unless a variable
               -- weighting is explicitly specified with the ka keyword:
               Maybe Text
    Nothing -> VariableWeighting -> Collator -> Collator
    U.setVariableWeighting VariableWeighting
    U.Shifted (Collator -> Collator) -> Collator -> Collator
    forall a b. (a -> b) -> a -> b
    $ Lang -> Collator
    U.collatorFor Lang
    lang
               Just Text
    _  -> Lang -> Collator
    U.collatorFor Lang
    lang
    #endif