{-# LANGUAGE CPP #-}
module Skylighting.Loader ( loadSyntaxFromFile
, loadSyntaxesFromDir
)
where
import Control.Monad (filterM, foldM)
import Control.Monad.Except (ExceptT(ExceptT), runExceptT)
import Control.Monad.IO.Class (liftIO)
import System.Directory (listDirectory, doesFileExist)
import System.FilePath ((</>), takeExtension)
import Skylighting.Types (SyntaxMap, Syntax)
import Skylighting.Parser (addSyntaxDefinition, parseSyntaxDefinition)
#if !MIN_VERSION_base(4,11,0)
import Data.Semigroup
#endif
syntaxFileExtension :: String
syntaxFileExtension = ".xml"
isSyntaxFile :: FilePath -> Bool
isSyntaxFile = (== syntaxFileExtension) . takeExtension
loadSyntaxFromFile :: FilePath -> IO (Either String Syntax)
loadSyntaxFromFile path = do
result <- parseSyntaxDefinition path
case result of
Left e -> return $ Left $ "Error parsing file " <> show path <> ": " <> e
Right s -> return $ Right s
loadSyntaxesFromDir :: FilePath -> IO (Either String SyntaxMap)
loadSyntaxesFromDir path = runExceptT $ do
files <- liftIO $ syntaxFiles path
let loadSyntax sMap file = do
s <- ExceptT $ loadSyntaxFromFile file
return $ addSyntaxDefinition s sMap
foldM loadSyntax mempty files
syntaxFiles :: FilePath -> IO [FilePath]
syntaxFiles dir = do
entries <- listDirectory dir
let absEntries = (dir </>) <$> filter isSyntaxFile entries
filterM doesFileExist absEntries