----------------------------------------------------------------------------- -- | -- Module : Static.Resources.Spec -- Copyright : (c) Scrive 2012 -- License : BSD-style (see the LICENSE file in the distribution) -- -- Maintainer : mariusz@scrive.com -- Stability : development -- Portability : portable -- -- Parsing static resources spec. -- -- * Line starting with word set is start of 'ResourceSet' definition. -- -- * Line starting css, js or jsx defines 'Resource'. -- -- * Line starting with ignore defines that some file should be ignored by checker. -- -- * ALL other lines are ignored -- -- Sample spec -- -- > ignore main.css -- > -- > set a -- > js a.js -- > css a.css -- > css common.css -- > -- > set b -- > js b.js -- > css b.css -- > css common.css -- -- module Static.Resources.Spec ( -- * Parsing parseSpec ) where import Static.Resources.Types import Data.List import Data.Char import Data.Generics.Builders setPrefix :: String setPrefix = "set" ignorePrefix :: String ignorePrefix = "ignore" typePrefix :: ResourceType -> String typePrefix CSS = "css" typePrefix JS = "js" typePrefix JSX = "jsx" typePrefix LESS = "less" parseSpec :: FilePath -> IO ResourceSpec parseSpec specPath = do c <- readFile specPath return $ foldl parse (ResourceSpec [] []) $ map trim $ lines c where trim = (reverse . dropWhile isSpace) . (reverse . dropWhile isSpace) clear pr s = trim $ drop (length pr) s parse :: ResourceSpec -> String -> ResourceSpec parse (ResourceSpec rs is) s | (ignorePrefix ++ " ") `isPrefixOf` s = ResourceSpec rs ((clear ignorePrefix s) : is) | (setPrefix ++ " ") `isPrefixOf` s = ResourceSpec ((ResourceSet (clear setPrefix s) []) : rs) is | otherwise = case find (\t -> (typePrefix t ++ " ") `isPrefixOf` s) constrs of Just rt -> case rs of (r:rs') -> ResourceSpec (r {resources = (resources r) ++ [Resource rt (clear (typePrefix rt) s )]}:rs') is _ -> error $ "Resource " ++ clear (typePrefix rt) s ++ " defined outside resource set in file " ++ specPath _ -> ResourceSpec rs is