i18n-0.4.0.0: src/Data/Text/I18n.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeSynonymInstances #-}
-- |
-- Module: Data.Text.I18n
-- Copyright: (c) 2011-2016 Eugene Grigoriev
-- License: BSD3
-- Maintainer: Philip Cunningham <hello@filib.io>
-- Stability: experimental
-- Portability: portable
--
-- Internationalisation support for Haskell.
module Data.Text.I18n (
-- * Internationalisation Monad Functions
gettext,
localize,
withContext,
withLocale,
-- * Re-exports
module Data.Text.I18n.Types,
) where
import Control.Monad.Identity
import Control.Monad.Reader
import qualified Data.Map as Map
import Data.Maybe
import qualified Data.Text as T
import Data.Text.I18n.Types
-- $setup
-- >>> :set -XOverloadedStrings
-- >>> import qualified Data.Text.I18n as I18n
-- >>> import qualified Data.Text.I18n.Po as I18n
-- >>> let example = I18n.gettext "Like tears in rain."
-- >>> (l10n, _) <- I18n.getL10n "./test/locale"
--
-- | The heart of I18n monad.
gettext :: T.Text -> I18n T.Text
gettext msgid = do
(loc, l10n, ctxt) <- ask
case localizeMsgid l10n loc ctxt (Msgid msgid) of
Just msgstr -> return msgstr
Nothing ->
case ctxt of
Just _ -> withContext Nothing (gettext msgid)
Nothing -> return msgid
-- | Top level localization function.
--
-- Examples:
--
-- >>> I18n.localize l10n (I18n.Locale "cym") example
-- "Fel dagrau yn y glaw."
--
-- When the translation doesn't exist:
--
-- >>> I18n.localize l10n (I18n.Locale "ru") example
-- "Like tears in rain."
localize :: L10n -- ^ Structure containing localization data
-> Locale -- ^ Locale to use
-> I18n a -- ^ Inernationalized expression
-> a -- ^ Localized expression
localize l10n loc expression = runIdentity $ runReaderT expression (loc, l10n, Nothing)
-- | Sets a local 'Context' for an internationalized expression. If there is no translation, then no
-- context version is tried.
--
-- Examples:
--
-- >>> let example2 = I18n.withContext (Just "Attack ships on fire off the shoulder of Orion.") example
-- >>> I18n.localize l10n (I18n.Locale "cym") example2
-- "Fel dagrau yn y glaw."
withContext :: Maybe Context -- ^ Context to use
-> I18n a -- ^ Internationalized expression
-> I18n a -- ^ New internationalized expression
withContext ctxt expression = do
(lang, l10n, _) <- ask
local (const (lang, l10n, ctxt)) expression
-- | Sets a local 'Locale' for an internationalized expression.
--
-- Examples:
--
-- >>> let example3 = I18n.withLocale (I18n.Locale "en") example
-- >>> I18n.localize l10n (I18n.Locale "cym") example3
-- "Like tears in rain."
withLocale :: Locale -- ^ Locale to use
-> I18n a -- ^ Internationalized expression
-> I18n a -- ^ New internationalized expression.
withLocale loc expression = do
(_, l10n, ctxt) <- ask
local (const (loc, l10n, ctxt)) expression
-- | Internal lookup function.
localizeMsgid :: L10n -> Locale -> Maybe Context -> Msgid -> Maybe T.Text
localizeMsgid l10n loc ctxt msgid = do
local' <- Map.lookup loc l10n
contextual <- Map.lookup ctxt local'
msgstrs <- Map.lookup msgid contextual
case listToMaybe msgstrs of
Nothing -> Nothing
Just "" -> Nothing
Just msgstr -> Just msgstr