module Text.Localize.Load
(
LocatePolicy (..), Facet,
loadTranslations, locateTranslations,
linuxLocation, localLocation
) where
import Control.Monad
import Control.Monad.Trans
import Data.Default
import qualified Data.Map as M
import qualified Data.Text.Lazy as T
import qualified Data.Gettext as Gettext
import Data.Text.Format.Heavy
import System.Directory
import System.FilePath
import System.FilePath.Glob
import Text.Localize.Types
loadTranslations :: [(LanguageId, FilePath)] -> IO Translations
loadTranslations pairs = do
res <- forM pairs $ \(lang, path) -> do
gmo <- Gettext.loadCatalog path
return (lang, gmo)
return $ Translations $ M.fromList res
type Facet = String
data LocatePolicy = LocatePolicy {
lcBasePaths :: [FilePath]
, lcName :: String
, lcFacet :: Facet
, lcFormat :: Format
}
deriving (Show)
instance Default LocatePolicy where
def = LocatePolicy {
lcBasePaths = ["locale"],
lcName = "messages",
lcFacet = "LC_MESSAGES",
lcFormat = "{base}/{language}/{facet}/{name}.mo"
}
linuxLocation :: String
-> LocatePolicy
linuxLocation name = def {lcBasePaths = ["/usr/share/locale", "/usr/local/share/locale"], lcName = name}
localLocation :: FilePath
-> LocatePolicy
localLocation base = def {lcBasePaths = [base], lcFormat = "{base}/{language}.mo"}
locateTranslations :: MonadIO m => LocatePolicy -> m Translations
locateTranslations (LocatePolicy {..}) = liftIO $ do
basePaths <- mapM makeAbsolute lcBasePaths
pairs <- forM basePaths $ \basePath -> do
let vars = M.fromList $
[("base", basePath),
("language", "*"),
("facet", lcFacet),
("name", lcName)] :: M.Map T.Text String
Format fmtItems = lcFormat
(fmtBase, fmtTail) = breakFormat fmtItems
pathGlob = T.unpack (format lcFormat vars)
pathBaseLen = fromIntegral $ T.length (format (Format fmtBase) vars)
pathTailLen = fromIntegral $ T.length (format (Format fmtTail) vars)
paths <- glob pathGlob
forM paths $ \path -> do
let pathWithoutBase = drop pathBaseLen path
languageLen = length pathWithoutBase pathTailLen
language = take languageLen pathWithoutBase
return (language, path)
loadTranslations $ concat pairs
where
breakFormat items =
let (hd, tl) = break isLanguage items
in case tl of
[] -> (hd, [])
_ -> (hd, tail tl)
isLanguage (FVariable name _) = name == "language"
isLanguage _ = False