-- | Reading language config file module Config ( LangInfo (..), loadLangs, loadLangsFrom, configFile ) where import Data.List (unfoldr) import System.IO (hPutStrLn,stderr) import System.Exit (exitFailure) -- | Path to language config file configFile :: FilePath configFile = "languages.csv" -- | Information about a language data LangInfo = LangInfo { langCode :: String -- ^ 3-letter ISO 639-2/B code , langName :: String -- ^ language name , langDir :: String -- ^ directory name , langFunctor :: Maybe String -- ^ functor (not used) , langUnlexer :: Maybe String -- ^ decoding for postprocessing linearizations , langPresent :: Bool , langAll :: Bool , langTry :: Bool , langSymbolic :: Bool , langCompatibility :: Bool , langSynopsis :: Bool -- ^ include in RGL synopsis , langMorphodict :: Bool } deriving (Show,Eq) -- | Load language information from default config file loadLangs :: IO [LangInfo] loadLangs = loadLangsFrom configFile -- | Load language information from specified config file loadLangsFrom:: FilePath -> IO [LangInfo] loadLangsFrom configFile = do lns <- readFile configFile >>= return . lines mapM mkLangInfo (tail lns) where maybeBit bits n = if length bits >= (n+1) && length (bits !! n) > 0 then Just (bits !! n) else Nothing boolBit bits n def = if length bits >= (n+1) && length (bits !! n) > 0 then (if def then bits !! n /= "n" else bits !! n == "y") else def mkLangInfo s = let bits = separateBy ',' s in if length bits < 2 then die $ "Invalid entry in " ++ configFile ++ ": " ++ s else return $ LangInfo { langCode = bits !! 0 , langName = bits !! 1 , langDir = bits !! 2 , langFunctor = maybeBit bits 3 , langUnlexer = maybeBit bits 4 , langPresent = boolBit bits 5 False , langAll = boolBit bits 6 True , langTry = boolBit bits 7 True , langSymbolic = boolBit bits 8 True , langCompatibility = boolBit bits 9 False , langSynopsis = boolBit bits 10 False , langMorphodict = boolBit bits 11 False } -- | Separate a string on a character -- Source: https://stackoverflow.com/a/4978733/98600 separateBy :: Eq a => a -> [a] -> [[a]] separateBy chr = unfoldr sep where sep [] = Nothing sep l = Just . fmap (drop 1) . break (== chr) $ l die :: String -> IO a die s = do hPutStrLn stderr s exitFailure