module System.Console.Docopt.ParseUtils
(
module System.Console.Docopt.ParseUtils,
module System.Console.Docopt.ApplicativeParsec,
module Data.Char,
)
where
import System.Console.Docopt.ApplicativeParsec
import Data.Map (Map)
import qualified Data.Map as M
import Data.Char (isSpace, toUpper, toLower)
lowers = ['a'..'z']
uppers = ['A'..'Z']
letters = lowers++uppers
numerics = ['0'..'9']++"-_"
specialChars = " :/"
alphanumerics = letters++numerics
alphanumSpecial = alphanumerics ++ specialChars
caseInsensitive :: String -> CharParser u String
caseInsensitive = sequence . (map (\c -> (char $ toLower c) <|> (char $ toUpper c)))
lookAhead_ :: CharParser u a -> CharParser u ()
lookAhead_ p = do lookAhead p
return ()
isNotFollowedBy :: Show a => CharParser u a -> CharParser u Bool
isNotFollowedBy p = option False (notFollowedBy p >> return True)
isInlineSpace :: Char -> Bool
isInlineSpace c = not (c `elem` "\n\r")
&& (isSpace c)
inlineSpace :: CharParser u Char
inlineSpace = satisfy isInlineSpace
<?> "inline-space"
inlineSpaces :: CharParser u ()
inlineSpaces = skipMany (satisfy isInlineSpace)
<?> "inline-spaces"
inlineSpaces1 :: CharParser u ()
inlineSpaces1 = skipMany1 (satisfy isInlineSpace)
<?> "1+ inline-spaces"
spaces1 :: CharParser u ()
spaces1 = skipMany1 (satisfy isSpace)
<?> ">=1 spaces"
endline = inlineSpaces >> newline
optionalEndline = inlineSpaces >> (optional newline)
pipe = char '|' <?> "'|'"
ellipsis :: CharParser u String
ellipsis = inlineSpaces >> string "..."
<?> "'...'"
manyTill1 p end = do
first <- p
rest <- manyTill p end
return $ first : rest
skipUntil :: Show a => CharParser u a -> CharParser u ()
skipUntil p = skipMany (notFollowedBy p >> anyChar)
pGroup :: Char -> CharParser u a -> Char -> CharParser u [a]
pGroup beg elemParser end = between (char beg) (inlineSpaces >> char end)
$ (inlineSpaces >> notFollowedBy pipe >> elemParser)
`sepBy`
(inlineSpaces >> pipe)
betweenS :: String -> String -> CharParser u a -> CharParser u [a]
betweenS b e p = between begin end manyP
where begin = try $ string b
end = try $ inlineSpaces >> (string e)
manyP = p `sepBy` inlineSpaces1
alterAllWithKey :: Ord k => (k -> Maybe a -> Maybe a) -> [k] -> Map k a -> Map k a
alterAllWithKey f ks m = foldl (\m' k -> M.alter (f k) k m') m ks