cake 1.0.0 → 1.1.0.1
raw patch · 9 files changed
+226/−745 lines, 9 filesdep +parsekdep ~arraydep ~basedep ~binaryPVP ok
version bump matches the API change (PVP)
Dependencies added: parsek
Dependency ranges changed: array, base, binary, bytestring, cmdargs, containers, derive, directory, filepath, mtl, process, pureMD5, regex-tdfa, split
API changes (from Hackage documentation)
- Cake.Actions: _bibtex :: String -> Act ()
- Cake.Actions: _lhs2TeX :: String -> String -> Act ()
- Cake.Actions: _pdflatex :: String -> Act ()
- Cake.Actions: argsOf :: [Char] -> [[Char]] -> [[Char]]
- Cake.Actions: getBibFiles :: String -> Act Answer
- Cake.Actions: graphviz :: String -> [Char] -> [Char] -> [String] -> Act ()
- Cake.Actions: includedLhs :: FilePath -> Act [[Char]]
- Cake.Actions: includedTex :: FilePath -> Act [[Char]]
- Cake.Actions: lhs2tex :: [Char] -> Act ()
- Cake.Actions: pandoc :: [Char] -> [Char] -> [String] -> Act ()
- Cake.Actions: pdflatexBibtex :: [Char] -> Act ()
- Cake.Core: instance Alternative P
- Cake.Core: instance Applicative P
- Cake.Marxup: ghcMake :: FilePath -> Act ()
- Cake.Marxup: marxup :: FilePath -> Act ()
- Cake.Marxup: mpost :: String -> Act ()
- Cake.Marxup: pdf_marxup :: FilePath -> Act ()
- Cake.Marxup: remove :: String -> Act ()
- Parsek: (<<|>) :: Parser s a -> Parser s a -> Parser s a
- Parsek: (<?>) :: Parser s a -> String -> Parser s a
- Parsek: (<|>) :: Parser s a -> Parser s a -> Parser s a
- Parsek: allResults :: ParseMethod s a (Maybe s) [a]
- Parsek: allResultsStaged :: ParseMethod s a (Maybe s) [[a]]
- Parsek: allResultsWithLeftover :: ParseMethod s a (Maybe s) [(a, [s])]
- Parsek: alphaNum :: Parser Char Char
- Parsek: anyChar :: Parser s s
- Parsek: anySymbol :: Parser s s
- Parsek: between :: Parser s open -> Parser s close -> Parser s a -> Parser s a
- Parsek: chainl :: Parser s a -> Parser s (a -> a -> a) -> a -> Parser s a
- Parsek: chainl1 :: Parser s a -> Parser s (a -> a -> a) -> Parser s a
- Parsek: chainr :: Parser s a -> Parser s (a -> a -> a) -> a -> Parser s a
- Parsek: chainr1 :: Parser s a -> Parser s (a -> a -> a) -> Parser s a
- Parsek: char :: (Eq t, Show t) => t -> Parser t t
- Parsek: choice :: [Parser s a] -> Parser s a
- Parsek: completeResults :: ParseMethod s a (Maybe s) [a]
- Parsek: completeResultsWithLine :: ParseMethod Char a Int [a]
- Parsek: count :: Int -> Parser s a -> Parser s [a]
- Parsek: data Parser s a
- Parsek: digit :: Parser Char Char
- Parsek: hexDigit :: Parser Char Char
- Parsek: instance Functor (Parser s)
- Parsek: instance Monad (Parser s)
- Parsek: instance MonadPlus (Parser s)
- Parsek: label :: Parser s a -> String -> Parser s a
- Parsek: letter :: Parser Char Char
- Parsek: longestResult :: ParseMethod s a (Maybe s) a
- Parsek: longestResultWithLeftover :: ParseMethod s a (Maybe s) (a, [s])
- Parsek: longestResults :: ParseMethod s a (Maybe s) [a]
- Parsek: longestResultsWithLeftover :: ParseMethod s a (Maybe s) ([a], Maybe [s])
- Parsek: look :: Parser s [s]
- Parsek: lower :: Parser Char Char
- Parsek: many :: Parser s a -> Parser s [a]
- Parsek: many1 :: Parser s a -> Parser s [a]
- Parsek: munch :: (s -> Bool) -> Parser s [s]
- Parsek: munch1 :: Show s => (s -> Bool) -> Parser s [s]
- Parsek: newline :: Parser Char Char
- Parsek: noneOf :: (Eq a, Show a) => [a] -> Parser a a
- Parsek: octDigit :: Parser Char Char
- Parsek: oneOf :: (Eq a, Show a) => [a] -> Parser a a
- Parsek: option :: a -> Parser s a -> Parser s a
- Parsek: optional :: Parser s a -> Parser s ()
- Parsek: parse :: Parser s a -> ParseMethod s a e r -> [s] -> ParseResult e r
- Parsek: parseFromFile :: Parser Char a -> ParseMethod Char a e r -> FilePath -> IO (ParseResult e r)
- Parsek: pzero :: Parser s a
- Parsek: satisfy :: Show s => (s -> Bool) -> Parser s s
- Parsek: sepBy :: Parser s a -> Parser s sep -> Parser s [a]
- Parsek: sepBy1 :: Parser s a -> Parser s sep -> Parser s [a]
- Parsek: shortestResult :: ParseMethod s a (Maybe s) a
- Parsek: shortestResultWithLeftover :: ParseMethod s a (Maybe s) (a, [s])
- Parsek: skipMany :: Parser s a -> Parser s ()
- Parsek: skipMany1 :: Parser s a -> Parser s ()
- Parsek: space :: Parser Char Char
- Parsek: spaces :: Parser Char ()
- Parsek: string :: (Eq s, Show s) => [s] -> Parser s [s]
- Parsek: succeeds :: Parser s a -> Parser s (Maybe a)
- Parsek: tab :: Parser Char Char
- Parsek: try :: Parser s a -> Parser s a
- Parsek: type Expect = [String]
- Parsek: type ParseMethod s a e r = P s a -> [s] -> ParseResult e r
- Parsek: type ParseResult e r = Either (e, Expect, Unexpect) r
- Parsek: type Unexpect = [String]
- Parsek: upper :: Parser Char Char
+ Cake.Actions: chaseSoftDeps :: (String -> [FilePath]) -> FilePath -> Act ()
+ Cake.Actions: remove :: String -> Act ()
+ Cake.Haskell: ghcMake :: FilePath -> Act ()
+ Cake.Haskell: importedHaskell :: String -> [FilePath]
+ Cake.MarXup: marxup :: FilePath -> Act ()
+ Cake.MarXup: pdf_marxup :: FilePath -> Act ()
+ Cake.MarXup: pdflatexMarxup :: FilePath -> Act ()
+ Cake.Tex: _bibtex :: String -> Act ()
+ Cake.Tex: _lhs2TeX :: String -> String -> Act ()
+ Cake.Tex: _mpost :: String -> Act ()
+ Cake.Tex: _pdflatex :: String -> Act ()
+ Cake.Tex: _xelatex :: String -> Act ()
+ Cake.Tex: argsOf :: [Char] -> [[Char]] -> [[Char]]
+ Cake.Tex: getBibFiles :: String -> Act Answer
+ Cake.Tex: graphviz :: String -> FilePath -> String -> [String] -> Act ()
+ Cake.Tex: includedLhs :: String -> [[Char]]
+ Cake.Tex: includedTex :: String -> [String]
+ Cake.Tex: lhs2tex :: [Char] -> Act ()
+ Cake.Tex: pandoc :: FilePath -> [Char] -> [String] -> Act ()
+ Cake.Tex: pdflatexBibtex :: FilePath -> Act ()
- Cake.Actions: (++?) :: Eq a => [a] -> [a] -> [a]
+ Cake.Actions: (++?) :: String -> String -> String
- Cake.Actions: chaseDeps :: Monad m => (a -> m [a]) -> a -> m ()
+ Cake.Actions: chaseDeps :: (String -> [FilePath]) -> FilePath -> Act ()
- Cake.Actions: dropSpaces :: [Char] -> [Char]
+ Cake.Actions: dropSpaces :: String -> String
Files
- Cake/Actions.hs +19/−98
- Cake/Core.hs +11/−21
- Cake/Haskell.hs +20/−0
- Cake/MarXup.hs +34/−0
- Cake/Marxup.hs +0/−40
- Cake/Rules.hs +3/−8
- Cake/Tex.hs +116/−0
- Parsek.hs +0/−558
- cake.cabal +23/−20
Cake/Actions.hs view
@@ -4,15 +4,13 @@ import Cake.Process import System.Directory import System.FilePath-import Control.Applicative import Control.Monad (when) import Control.Monad.RWS (liftIO) import Data.List-import Data.List.Split import Data.Char (isSpace) copy :: FilePath -> FilePath -> Act()-copy from to = shielded $ produce to $ do+copy from to = produce to $ do needs [from] cut $ do mkdir $ takeDirectory to@@ -22,113 +20,36 @@ mkdir d = liftIO $ createDirectoryIfMissing True d touch :: FilePath -> Act ()-touch x = shielded $ produce x $ do+touch x = produce x $ do system ["touch",x] +remove :: String -> Act ()+remove x = system ["rm", "-f", x]+ readFile :: FilePath -> Act String readFile x = do need x liftIO $ Prelude.readFile x -_pdflatex x = system ["pdflatex",x]- -_bibtex x = system ["bibtex",x]---pandoc inp typ options = produce out $ do - need inp- cut $ system $ ["pandoc",inp,"-t",typ,"-o",out] ++ options- where out = replaceExtension inp ext- ext = case typ of - "latex" -> "tex"- _ -> typ--graphviz program inp typ options = produce out $ do- needs [inp] - cut $ system $ [program, "-T"++typ, "-o"++out, inp] ++ options- where out = replaceExtension inp typ- --- | Argument of a latex macro-argsOf s = map (init . (drop $ 2 + length s)) . filter (("\\" ++ s ++ "{") `isPrefixOf`) ---- | Find the bib files used in a tex file-getBibFiles input = distill (Custom ["bibfiles",input]) $ do- ls <- map (drop 14) . filter ("\\bibliography{" `isPrefixOf`) . lines <$> Cake.Actions.readFile input- let bibs = map (++".bib") $ case ls of- [] -> []- (l:_) -> splitOn "," $ reverse . dropWhile (== '}') . reverse $ l- return $ Text bibs--s ++? e = if e `isSuffixOf` s then s else s ++ e-+dropSpaces :: String -> String dropSpaces = reverse . dropWhile isSpace . reverse . dropWhile isSpace -includedTex input = map (++? ".tex") . argsOf "input" . lines <$> Cake.Actions.readFile input--includedLhs input = filter (`notElem` stdinclude) . map (dropSpaces . drop 8) . filter ("%include" `isPrefixOf`) . map (dropWhile isSpace). lines <$> Cake.Actions.readFile input- where stdinclude = ["lhs2TeX.fmt","polycode.fmt"]-+-- | Depend on the input file and its dependencies, as given by the 1st argument.+chaseDeps :: (String -> [FilePath]) -> FilePath -> Act () chaseDeps includedFiles i = do- is <- includedFiles i+ is <- includedFiles <$> Cake.Actions.readFile i mapM_ (chaseDeps includedFiles) is- -pdflatexBibtex c = do- let input = c ++ ".tex"- aux = c ++ ".aux"- pdf = c ++ ".pdf"- bbl = c ++ ".bbl" - produces [aux,pdf] $ do- chaseDeps includedTex input- cut $ _pdflatex c- - produce bbl $ do- Text bibs <- getBibFiles input - needs bibs - cut $ _bibtex c - - shielded $ do- use aux- use bbl- updates [aux,pdf] $ cut $ _pdflatex c- --{--pdf_tex_bibtex = extension ".pdf" ==> \(_,c) -> pdflatexBibtex c--pdflatexBiblatex c = do- let input = c ++ ".tex"- aux = c ++ ".aux"- pdf = c ++ ".pdf"- produce pdf $ do- produce aux $ do - chaseDeps includedTex input- cut $ _pdflatex c- - produce (c ++ ".bbl") $ do- -- Note that this does not depend on the actual tex file; only the list of bibs.- Text bibs <- getBibFiles input- mapM_ need bibs- use aux- when (not $ null bibs) $- cut $ _bibtex c-- cut $ do _pdflatex c- overwrote aux- return ()- --pdf_tex_biblatex = anyExtension [".pdf",".aux"] ==> \(_,c) -> - pdflatexBibtex c---}-_lhs2TeX i o = do- system ["lhs2TeX","-o",o,i]+-- | Depend on the input file and its dependencies. If a file cannot+-- be found, do not depend on it.+chaseSoftDeps :: (String -> [FilePath]) -> FilePath -> Act ()+chaseSoftDeps includedFiles i = do+ e <- liftIO $ doesFileExist i+ when e $ do + is <- includedFiles <$> Cake.Actions.readFile i+ mapM_ (chaseDeps includedFiles) is +(++?) :: String -> String -> String+s ++? e = if e `isSuffixOf` s then s else s ++ e -lhs2tex c = produce tex $ do- chaseDeps includedLhs lhs- cut $ _lhs2TeX lhs tex- where lhs = c ++ ".lhs"- tex = c ++ ".tex"
Cake/Core.hs view
@@ -34,12 +34,10 @@ import System.Directory import System.FilePath import Control.Applicative-import Control.Monad (when) import Control.Monad.RWS hiding (put,get) import qualified Control.Monad.RWS as RWS import Control.Monad.Error -import qualified Parsek-import Parsek (completeResults, parse, Parser)+import Text.ParserCombinators.Parsek (completeResults, parse, Parser) import qualified Data.Map as M import qualified Data.Set as S import Data.Binary hiding (put,get)@@ -97,25 +95,14 @@ noMsg = Panic strMsg = CakeError -instance Applicative P where- (<*>) = ap- pure = return--instance Alternative P where- (<|>) = (Parsek.<|>)- empty = Parsek.pzero-- -- | Primitve for rule construction. The given action must produce -- files matched by the pattern. (==>) :: P x -> (x -> Act a) -> Rule p ==> a = (\s -> do a s;return ()) <$> p - databaseFile = ".cake" logFile = ".cake.log" - -- | Run an action in the context of a set of rules. cake :: Rule -> Act () -> IO () cake rule action = do@@ -130,6 +117,9 @@ putStrLn $ (show k) ++ " => " ++ (show v) encodeFile databaseFile newDB +-- | Produce a shell script rebuilding everything+-- eatIt :: Rule -> Act () -> String () + -- | Was the file already produced? produced :: FilePath -> Act Bool produced f = do @@ -138,7 +128,10 @@ modCx q (Context {..}) = Context {ctxProducing = q:ctxProducing,..} --- | Answer a question using the action given. +-- | Answer a question using the action given. The action is+-- encapsulated by the answer. That is, clobbering done by the action+-- will be hidden if the answer to the question turns out the same as+-- in a previous run. distill :: Question -> Act Answer -> Act Answer distill q act = local (modCx q) $ do debug $ "Starting to answer: " ++ show q@@ -178,10 +171,8 @@ updates [] a = a updates (f:fs) a = distill (FileContents f) (do e <- liftIO $ doesFileExist f- updates fs (when (not e) clobber >> a)- -- force running the action if the file is not present, even if in a clean state.- modify $ first $ S.insert f - -- remember that the file has been produced already+ updates fs (when (not e) clobber >> a) -- force running the action if the file is not present, even if in a clean state.+ modify $ first $ S.insert f -- remember that the file has been produced already fileStamp f) >> return () @@ -310,5 +301,4 @@ needs = independently . map need --+
+ Cake/Haskell.hs view
@@ -0,0 +1,20 @@+module Cake.Haskell where+ +import Cake.Core +import Cake.Actions+import Cake.Process+import System.FilePath+import Data.List++importedHaskell = map (moduleToFile . dropSpaces . drop (length prefix)) . filter (prefix `isPrefixOf`) . map dropSpaces . lines+ where prefix = "import"+ moduleToFile m = map dotToSlash m <.> "hs"+ dotToSlash '.' = '/'+ dotToSlash c = c+++ghcMake x = produce x $ do+ let src = x <.> "hs"+ chaseDeps importedHaskell src+ system ["ghc", "-o", x, "--make", src]+
+ Cake/MarXup.hs view
@@ -0,0 +1,34 @@+module Cake.MarXup where+ +import Cake.Core +import Cake.Actions+import Cake.Process+import System.FilePath+import Cake.Tex+import Cake.Haskell++marxup x = do + produces [x <.> "tex",x <.> "mp"] $ do+ ghcMake x+ cut $ system $ ["./" ++ x]++pdflatexMarxup x = produce (x <.> "pdf") $ do + mapM_ use [x <.> "tex",x <.> "mp"]+ let delayed = x ++ "-delayed.mp"+ produce delayed $ do+ let mp = x <.> "mp"+ need mp+ cut $ do + remove delayed+ _mpost mp+ _mpost mp+ + pdflatexBibtex x++++pdf_marxup x = produce (x <.> "pdf") $ do + marxup x+ pdflatexMarxup x++
− Cake/Marxup.hs
@@ -1,40 +0,0 @@-module Cake.Marxup where- -import Cake.Core -import Cake.Actions-import Cake.Process-import System.FilePath--import Parsek--ghcMake x = produce x $ do- let src = x <.> "hs"- need src- system ["ghc", "-o", x, "--make", src]- --marxup x = do - produce (x <.> "tex") $ do- ghcMake x- cut $ - system $ ["./" ++ x]- produce (x <.> "mp") $ return ()--mpost x = system ["mpost", x]--remove x = system ["rm", "-f", x]--pdf_marxup x = produce (x <.> "pdf") $ do - marxup x- let delayed = x ++ "-delayed.mp"- produce delayed $ do- let mp = x <.> "mp"- need mp- cut $ do - remove delayed- mpost mp- mpost mp- - cut $ _pdflatex x--
Cake/Rules.hs view
@@ -2,19 +2,14 @@ import Cake.Core import Cake.Process-import Cake.Actions-import System.Directory-import System.FilePath-import Control.Applicative-import qualified Parsek-import Data.List-import Data.List.Split+import Cake.Tex+import qualified Text.ParserCombinators.Parsek as Parsek ------------------------------------------------------ -- Patterns extension :: String -> P (String,String) extension s = do- base <- Parsek.many Parsek.anyChar+ base <- Parsek.many Parsek.anySymbol Parsek.string s return (base++s,base)
+ Cake/Tex.hs view
@@ -0,0 +1,116 @@+module Cake.Tex where++import Cake.Core+import Cake.Process+import System.Directory+import System.FilePath+import Control.Applicative+import Control.Monad.RWS (liftIO)+import Control.Monad (when)+import Data.List+import Data.List.Split+import Data.Char (isSpace)+import Cake.Actions++_mpost x = system ["mpost", x]++_pdflatex x = system ["pdflatex",x]+_xelatex x = system ["xelatex",x]+ +_bibtex x = system ["bibtex",x]+++pandoc inp typ options = produce out $ do + need inp+ cut $ system $ ["pandoc",inp,"-t",typ,"-o",out] ++ options+ where out = replaceExtension inp ext+ ext = case typ of + "latex" -> "tex"+ _ -> typ++graphviz program inp typ options = produce out $ do+ needs [inp] + cut $ system $ [program, "-T"++typ, "-o"++out, inp] ++ options+ where out = replaceExtension inp typ+ +-- | Argument of a latex macro+argsOf s = map (init . (drop $ 2 + length s)) . filter (("\\" ++ s ++ "{") `isPrefixOf`) ++-- | Find the bib files used in a tex file+getBibFiles input = distill (Custom ["bibfiles",input]) $ do+ ls <- map (drop 14) . filter ("\\bibliography{" `isPrefixOf`) . lines <$> Cake.Actions.readFile input+ let bibs = map (++".bib") $ case ls of+ [] -> []+ (l:_) -> splitOn "," $ reverse . dropWhile (== '}') . reverse $ l+ return $ Text bibs++includedTex = map (++? ".tex") . argsOf "input" . lines++includedLhs = filter (`notElem` stdinclude) . + map (dropSpaces . drop (length prefix)) . filter (prefix `isPrefixOf`) . + map (dropWhile isSpace) . + lines+ where stdinclude = ["lhs2TeX.fmt","polycode.fmt"]+ prefix = "%include"++pdflatexBibtex c = do+ let [input,aux,pdf,bbl] = map (c <.>) ["tex","aux","pdf","bbl"]++ produces [aux,pdf] $ do+ chaseDeps includedTex input+ cut $ _pdflatex c++ bibliographyExists <- do+ aux_contents <- Cake.Actions.readFile aux+ return ("\\bibdata" `isInfixOf` aux_contents)++ when bibliographyExists $ do+ produce bbl $ do+ Text bibs <- getBibFiles input+ needs bibs+ cut $ _bibtex c++ updates [aux,pdf] $ do+ use aux+ when bibliographyExists $ use bbl >> return ()+ cut $ _pdflatex c+++{-+pdf_tex_bibtex = extension ".pdf" ==> \(_,c) -> pdflatexBibtex c++pdflatexBiblatex c = do+ let input = c ++ ".tex"+ aux = c ++ ".aux"+ pdf = c ++ ".pdf"+ produce pdf $ do+ produce aux $ do + chaseDeps includedTex input+ cut $ _pdflatex c+ + produce (c ++ ".bbl") $ do+ -- Note that this does not depend on the actual tex file; only the list of bibs.+ Text bibs <- getBibFiles input+ mapM_ need bibs+ use aux+ when (not $ null bibs) $+ cut $ _bibtex c++ cut $ do _pdflatex c+ overwrote aux+ return ()+ ++pdf_tex_biblatex = anyExtension [".pdf",".aux"] ==> \(_,c) -> + pdflatexBibtex c++-}+_lhs2TeX i o = do+ system ["lhs2TeX","-o",o,i]+++lhs2tex c = produce tex $ do+ chaseDeps includedLhs lhs+ cut $ _lhs2TeX lhs tex+ where lhs = c ++ ".lhs"+ tex = c ++ ".tex"
− Parsek.hs
@@ -1,558 +0,0 @@--- |------ Module : Parsek--- Copyright : Koen Claessen 2003--- License : GPL------ Maintainer : otakar.smrz mff.cuni.cz--- Stability : provisional--- Portability : portable------ This module provides the /Parsek/ library developed by Koen Claessen in his--- functional pearl article /Parallel Parsing Processes/, Journal of Functional--- Programming, 14(6), 741–757, Cambridge University Press, 2004:------ <http://www.cs.chalmers.se/~koen/pubs/entry-jfp04-parser.html>------ <http://www.cs.chalmers.se/Cs/Grundutb/Kurser/afp/>------ <http://www.cs.chalmers.se/Cs/Grundutb/Kurser/afp/code/week3/Parsek.hs>--------- Copyright (C) 2003 Koen Claessen------ This program is free software; you can redistribute it and\/or modify--- it under the terms of the GNU General Public License as published by--- the Free Software Foundation; either version 2 of the License, or--- (at your option) any later version.------ This program is distributed in the hope that it will be useful,--- but WITHOUT ANY WARRANTY; without even the implied warranty of--- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the--- GNU General Public License for more details.------ You should have received a copy of the GNU General Public License along--- with this program; if not, write to the Free Software Foundation, Inc.,--- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.--------- "PureFP.Parsers.Stream"----------------------------------------------------------------------- Parsek, a Parser Combinator Library ----- Copyright (c) 2003 Koen Claessen ----- koen@cs.chalmers.se ----- ----- This file is part of Parsek. ----- ----- Parsek is free software; you can redistribute it and/or ----- modify it under the terms of the GNU General Public License ----- as published by the Free Software Foundation; either version ---{-# LANGUAGE RankNTypes #-}--- 2 of the License, or (at your option) any later version. ----- ----- Parsek is distributed in the hope that it will be useful, ----- but WITHOUT ANY WARRANTY; without even the implied warranty ----- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See ----- the GNU General Public License for more details. ----- ----- You should have received a copy of the GNU General Public ----- License along with Parsek; if not, write to the Free ----- Software Foundation, Inc., 59 Temple Place, Suite 330, ----- Boston, MA 02111-1307 USA. -----------------------------------------------------------------------module Parsek- -- basic parser type- ( Parser -- :: * -> * -> *; Functor, Monad, MonadPlus- , Expect -- :: *; = [String]- , Unexpect -- :: *; = [String]-- -- parsers- , satisfy -- :: Show s => (s -> Bool) -> Parser s s- , look -- :: Parser s [s]- , succeeds -- :: Parser s a -> Parser s (Maybe a)- , string -- :: (Eq s, Show s) => [s] -> Parser s [s]-- , char -- :: Eq s => s -> Parser s s- , noneOf -- :: Eq s => [s] -> Parser s s- , oneOf -- :: Eq s => [s] -> Parser s s-- , spaces -- :: Parser Char ()- , space -- :: Parser Char Char- , newline -- :: Parser Char Char- , tab -- :: Parser Char Char- , upper -- :: Parser Char Char- , lower -- :: Parser Char Char- , alphaNum -- :: Parser Char Char- , letter -- :: Parser Char Char- , digit -- :: Parser Char Char- , hexDigit -- :: Parser Char Char- , octDigit -- :: Parser Char Char- , anyChar -- :: Parser s s- , anySymbol -- :: Parser s s- , munch, munch1 -- :: (s -> Bool) -> Parser s [s]-- -- parser combinators- , label -- :: String -> Parser s a -> Parser s a- , (<?>) -- :: Parser s a -> String -> Parser s a- , pzero -- :: Parser s a- , (<|>) -- :: Parser s a -> Parser s a -> Parser s a- , (<<|>) -- :: Parser s a -> Parser s a -> Parser s a- , try -- :: Parser s a -> Parser s a; = id- , choice -- :: [Parser s a] -> Parser s a- , option -- :: a -> Parser s a -> Parser s a- , optional -- :: Parser s a -> Parser s ()- , between -- :: Parser s open -> Parser s close -> Parser s a -> Parser s a- , count -- :: Int -> Parser s a -> Parser s [a]-- , chainl1 -- :: Parser s a -> Parser s (a -> a -> a) -> Parser s a- , chainl -- :: Parser s a -> Parser s (a -> a -> a) -> a -> Parser s a- , chainr1 -- :: Parser s a -> Parser s (a -> a -> a) -> Parser s a- , chainr -- :: Parser s a -> Parser s (a -> a -> a) -> a -> Parser s a-- , skipMany1 -- :: Parser s a -> Parser s ()- , skipMany -- :: Parser s a -> Parser s ()- , many1 -- :: Parser s a -> Parser s [a]- , many -- :: Parser s a -> Parser s [a]- , sepBy1 -- :: Parser s a -> Parser s sep -> Parser s [a]- , sepBy -- :: Parser s a -> Parser s sep -> Parser s [a]-- -- parsing & parse methods- , ParseMethod -- :: * -> * -> * -> * -> *- , ParseResult -- :: * -> * -> *; = Either (e, Expect, Unexpect) r- , parseFromFile -- :: Parser Char a -> ParseMethod Char a e r -> FilePath -> IO (ParseResult e r)- , parse -- :: Parser s a -> ParseMethod s a e r -> [s] -> ParseResult e r-- , shortestResult -- :: ParseMethod s a (Maybe s) a- , longestResult -- :: ParseMethod s a (Maybe s) a- , longestResults -- :: ParseMethod s a (Maybe s) [a]- , allResults -- :: ParseMethod s a (Maybe s) [a]- , allResultsStaged -- :: ParseMethod s a (Maybe s) [[a]]- , completeResults -- :: ParseMethod s a (Maybe s) [a]-- , shortestResultWithLeftover -- :: ParseMethod s a (Maybe s) (a,[s])- , longestResultWithLeftover -- :: ParseMethod s a (Maybe s) (a,[s])- , longestResultsWithLeftover -- :: ParseMethod s a (Maybe s) ([a],[s])- , allResultsWithLeftover -- :: ParseMethod s a (Maybe s) [(a,[s])]-- , completeResultsWithLine -- :: ParseMethod Char a Int [a]- )- where--import Control.Monad- ( MonadPlus(..)- , guard- )--import Data.List- ( union- , intersperse- )--import Data.Char--infix 0 <?>-infixr 1 <|>, <<|>------------------------------------------------------------------------------ type Parser--newtype Parser s a- = Parser (forall res . (a -> Expect -> P s res) -> Expect -> P s res)---- type P; parsing processes--data P s res- = Symbol (s -> P s res)- | Look ([s] -> P s res)- | Fail Expect Unexpect- | Result res (P s res)---- type Expect, Unexpect--type Expect- = [String]--type Unexpect- = [String]------------------------------------------------------------------------------ instances: Functor, Monad, MonadPlus--instance Functor (Parser s) where- fmap p (Parser f) =- Parser (\fut -> f (fut . p))--instance Monad (Parser s) where- return a =- Parser (\fut -> fut a)-- Parser f >>= k =- Parser (\fut -> f (\a -> let Parser g = k a in g fut))-- fail s =- Parser (\fut exp -> Fail exp [s])--instance MonadPlus (Parser s) where- mzero =- Parser (\fut exp -> Fail exp [])-- mplus (Parser f) (Parser g) =- Parser (\fut exp -> f fut exp `plus` g fut exp)--plus :: P s res -> P s res -> P s res-Symbol fut1 `plus` Symbol fut2 = Symbol (\s -> fut1 s `plus` fut2 s)-Fail exp1 err1 `plus` Fail exp2 err2 = Fail (exp1 `union` exp2) (err1 `union` err2)-p `plus` Result res q = Result res (p `plus` q)-Result res p `plus` q = Result res (p `plus` q)-Look fut1 `plus` Look fut2 = Look (\s -> fut1 s `plus` fut2 s)-Look fut1 `plus` q = Look (\s -> fut1 s `plus` q)-p `plus` Look fut2 = Look (\s -> p `plus` fut2 s)-p@(Symbol _) `plus` _ = p-_ `plus` q@(Symbol _) = q------------------------------------------------------------------------------ primitive parsers--anySymbol :: Parser s s-anySymbol =- Parser (\fut exp -> Symbol (\c ->- fut c []- ))--satisfy :: Show s => (s -> Bool) -> Parser s s-satisfy pred =- Parser (\fut exp -> Symbol (\c ->- if pred c- then fut c []- else Fail exp [show [c]]- ))--label :: Parser s a -> String -> Parser s a-label (Parser f) s =- Parser (\fut exp ->- if null exp- then f (\a _ -> fut a []) [s]- else f fut exp- )--look :: Parser s [s]-look =- Parser (\fut exp ->- Look (\s -> fut s exp)- )--succeeds :: Parser s a -> Parser s (Maybe a)-succeeds (Parser f) =- Parser (\fut exp ->- Look (\xs ->- let sim (Symbol f) q (x:xs) = sim (f x) (\k -> Symbol (\_ -> q k)) xs- sim (Look f) q xs = sim (f xs) q xs- sim p@(Result _ _) q xs = q (cont p)- sim _ _ _ = fut Nothing []-- cont (Symbol f) = Symbol (\x -> cont (f x))- cont (Look f) = Look (\s -> cont (f s))- cont (Result a p) = fut (Just a) [] `plus` cont p- cont (Fail exp unexp) = Fail exp unexp-- in sim (f (\a _ -> Result a (Fail [] [])) exp) id xs- )- )---- specialized--string :: (Eq s, Show s) => [s] -> Parser s [s]-string s =- Parser (\fut exp ->- let inputs [] = fut s []- inputs (x:xs) =- Symbol (\c ->- if c == x- then inputs xs- else Fail (if null exp then [show s] else exp) [show [c]]- )-- in inputs s- )------------------------------------------------------------------------------ derived parsers--char c = satisfy (==c) <?> show [c]-noneOf cs = satisfy (\c -> not (c `elem` cs))-oneOf cs = satisfy (\c -> c `elem` cs)--spaces = skipMany space <?> "white space"-space = satisfy (isSpace) <?> "space"-newline = char '\n' <?> "new-line"-tab = char '\t' <?> "tab"-upper = satisfy (isUpper) <?> "uppercase letter"-lower = satisfy (isLower) <?> "lowercase letter"-alphaNum = satisfy (isAlphaNum) <?> "letter or digit"-letter = satisfy (isAlpha) <?> "letter"-digit = satisfy (isDigit) <?> "digit"-hexDigit = satisfy (isHexDigit) <?> "hexadecimal digit"-octDigit = satisfy (isOctDigit) <?> "octal digit"-anyChar = anySymbol--munch :: (s -> Bool) -> Parser s [s]-munch p =- do cs <- look- scan cs- where- scan (c:cs) | p c = do anySymbol; as <- scan cs; return (c:as)- scan _ = do return []--munch1 :: Show s => (s -> Bool) -> Parser s [s]-munch1 p =- do c <- satisfy p- cs <- munch p- return (c:cs)---------------------------------------------------------------- parser combinators--(<?>) :: Parser s a -> String -> Parser s a-p <?> s = label p s--pzero :: Parser s a-pzero = mzero--(<|>) :: Parser s a -> Parser s a -> Parser s a-p <|> q = p `mplus` q--(<<|>) :: Parser s a -> Parser s a -> Parser s a-p <<|> q =- do ma <- succeeds p- case ma of- Nothing -> q- Just a -> return a--try :: Parser s a -> Parser s a-try p = p -- backwards compatibility with Parsec--choice :: [Parser s a] -> Parser s a-choice ps = foldr (<|>) mzero ps--option :: a -> Parser s a -> Parser s a-option x p = p <|> return x--optional :: Parser s a -> Parser s ()-optional p = (do p; return ()) <|> return ()--between :: Parser s open -> Parser s close -> Parser s a -> Parser s a-between open close p = do open; x <- p; close; return x---- repetition--skipMany1,skipMany :: Parser s a -> Parser s ()-skipMany1 p = do p; skipMany p-skipMany p = let scan = (do p; scan) <|> return () in scan--many1,many :: Parser s a -> Parser s [a]-many1 p = do x <- p; xs <- many p; return (x:xs)-many p = let scan f = (do x <- p; scan (f.(x:))) <|> return (f []) in scan id--sepBy1,sepBy :: Parser s a -> Parser s sep -> Parser s [a]-sepBy p sep = sepBy1 p sep <|> return []-sepBy1 p sep = do x <- p; xs <- many (do sep; p); return (x:xs)--count :: Int -> Parser s a -> Parser s [a]-count n p = sequence (replicate n p)--chainr,chainl :: Parser s a -> Parser s (a -> a -> a) -> a -> Parser s a-chainr p op x = chainr1 p op <|> return x-chainl p op x = chainl1 p op <|> return x--chainr1,chainl1 :: Parser s a -> Parser s (a -> a -> a) -> Parser s a-chainr1 p op = scan- where- scan = do x <- p; rest x- rest x = (do f <- op; y <- scan; return (f x y)) <|> return x--chainl1 p op = scan- where- scan = do x <- p; rest x- rest x = (do f <- op; y <- p; rest (f x y)) <|> return x------------------------------------------------------------------------------ type ParseMethod, ParseResult--type ParseMethod s a e r- = P s a -> [s] -> ParseResult e r--type ParseResult e r- = Either (e, Expect, Unexpect) r---- parse functions--parseFromFile :: Parser Char a -> ParseMethod Char a e r -> FilePath -> IO (ParseResult e r)-parseFromFile p method file =- do s <- readFile file- return (parse p method s)--parse :: Parser s a -> ParseMethod s a e r -> [s] -> ParseResult e r-parse (Parser f) method xs =- case method (f (\a exp -> Result a (Fail exp [])) []) xs of- Left (err, exp, unexp) -> Left (err, [ s | s@(_:_) <- exp ], unexp)- Right x -> Right x---- parse methods--shortestResult :: ParseMethod s a (Maybe s) a-shortestResult p xs = scan p xs- where- scan (Symbol sym) (x:xs) = scan (sym x) xs- scan (Symbol _) [] = scan (Fail [] []) []- scan (Result res _) _ = Right res- scan (Fail exp err) (x:xs) = failSym x exp err- scan (Fail exp err) [] = failEof exp err- scan (Look f) xs = scan (f xs) xs--longestResult :: ParseMethod s a (Maybe s) a-longestResult p xs = scan p Nothing xs- where- scan (Symbol sym) mres (x:xs) = scan (sym x) mres xs- scan (Symbol _) mres [] = scan (Fail [] []) mres []- scan (Result res p) _ xs = scan p (Just res) xs- scan (Fail exp err) Nothing (x:xs) = failSym x exp err- scan (Fail exp err) Nothing [] = failEof exp err- scan (Fail _ _) (Just res) _ = Right res- scan (Look f) mres xs = scan (f xs) mres xs--longestResults :: ParseMethod s a (Maybe s) [a]-longestResults p xs = scan p [] [] xs- where- scan (Symbol sym) [] old (x:xs) = scan (sym x) [] old xs- scan (Symbol sym) new old (x:xs) = scan (sym x) [] new xs- scan (Symbol _) new old [] = scan (Fail [] []) new old []- scan (Result res p) new old xs = scan p (res:new) [] xs- scan (Fail exp err) [] [] (x:xs) = failSym x exp err- scan (Fail exp err) [] [] [] = failEof exp err- scan (Fail _ _) [] old _ = Right old- scan (Fail _ _) new _ _ = Right new- scan (Look f) new old xs = scan (f xs) new old xs--allResultsStaged :: ParseMethod s a (Maybe s) [[a]]-allResultsStaged p xs = Right (scan p [] xs)- where- scan (Symbol sym) ys (x:xs) = ys : scan (sym x) [] xs- scan (Symbol _) ys [] = [ys]- scan (Result res p) ys xs = scan p (res:ys) xs- scan (Fail _ _) ys _ = [ys]- scan (Look f) ys xs = scan (f xs) ys xs--allResults :: ParseMethod s a (Maybe s) [a]-allResults p xs = scan p xs- where- scan (Symbol sym) (x:xs) = scan (sym x) xs- scan (Symbol _) [] = scan (Fail [] []) []- scan (Result res p) xs = Right (res : scan' p xs)- scan (Fail exp err) (x:xs) = failSym x exp err- scan (Fail exp err) [] = failEof exp err- scan (Look f) xs = scan (f xs) xs-- scan' p xs =- case scan p xs of- Left _ -> []- Right ress -> ress--completeResults :: ParseMethod s a (Maybe s) [a]-completeResults p xs = scan p xs- where- scan (Symbol sym) (x:xs) = scan (sym x) xs- scan (Symbol _) [] = scan (Fail [] []) []- scan (Result res p) [] = Right (res : scan' p [])- scan (Result _ p) xs = scan p xs- scan (Fail exp err) (x:xs) = failSym x exp err- scan (Fail exp err) [] = failEof exp err- scan (Look f) xs = scan (f xs) xs-- scan' p xs =- case scan p xs of- Left _ -> []- Right ress -> ress---- with left overs--shortestResultWithLeftover :: ParseMethod s a (Maybe s) (a,[s])-shortestResultWithLeftover p xs = scan p xs- where- scan (Symbol sym) (x:xs) = scan (sym x) xs- scan (Symbol _) [] = scan (Fail [] []) []- scan (Result res _) xs = Right (res,xs)- scan (Fail exp err) (x:xs) = failSym x exp err- scan (Fail exp err) [] = failEof exp err- scan (Look f) xs = scan (f xs) xs--longestResultWithLeftover :: ParseMethod s a (Maybe s) (a,[s])-longestResultWithLeftover p xs = scan p Nothing xs- where- scan (Symbol sym) mres (x:xs) = scan (sym x) mres xs- scan (Symbol _) mres [] = scan (Fail [] []) mres []- scan (Result res p) _ xs = scan p (Just (res,xs)) xs- scan (Fail exp err) Nothing (x:xs) = failSym x exp err- scan (Fail exp err) Nothing [] = failEof exp err- scan (Fail _ _) (Just resxs) _ = Right resxs- scan (Look f) mres xs = scan (f xs) mres xs--longestResultsWithLeftover :: ParseMethod s a (Maybe s) ([a],Maybe [s])-longestResultsWithLeftover p xs = scan p empty empty xs- where- scan (Symbol sym) ([],_) old (x:xs) = scan (sym x) empty old xs- scan (Symbol sym) new old (x:xs) = scan (sym x) empty new xs- scan (Symbol _) new old [] = scan (Fail [] []) new old []- scan (Result res p) (as,_) old xs = scan p (res:as,Just xs) empty xs- scan (Fail exp err) ([],_) ([],_) (x:xs) = failSym x exp err- scan (Fail exp err) ([],_) ([],_) [] = failEof exp err- scan (Fail _ _) ([],_) old _ = Right old- scan (Fail _ _) new _ _ = Right new- scan (Look f) new old xs = scan (f xs) new old xs-- empty = ([],Nothing)--allResultsWithLeftover :: ParseMethod s a (Maybe s) [(a,[s])]-allResultsWithLeftover p xs = scan p xs- where- scan (Symbol sym) (x:xs) = scan (sym x) xs- scan (Symbol _) [] = scan (Fail [] []) []- scan (Result res p) xs = Right ((res,xs) : scan' p xs)- scan (Fail exp err) (x:xs) = failSym x exp err- scan (Fail exp err) [] = failEof exp err- scan (Look f) xs = scan (f xs) xs-- scan' p xs =- case scan p xs of- Left _ -> []- Right ress -> ress--completeResultsWithLine :: ParseMethod Char a Int [a]-completeResultsWithLine p xs = scan p 1 xs- where- scan (Symbol sym) n (x:xs) = let n' = x |> n in n' `seq` scan (sym x) n' xs- scan (Symbol _) n [] = scan (Fail [] ["end of file"]) n []- scan (Result res p) n [] = Right (res : scan' p n [])- scan (Result _ p) n xs = scan p n xs- scan (Fail exp err) n xs = Left (n, exp, err)- scan (Look f) n xs = scan (f xs) n xs-- scan' p n xs =- case scan p n xs of- Left _ -> []- Right ress -> ress-- '\n' |> n = n+1- _ |> n = n---- failing--failSym :: s -> Expect -> Unexpect -> ParseResult (Maybe s) r-failSym s exp err = Left (Just s, exp, err)--failEof :: Expect -> Unexpect -> ParseResult (Maybe s) r-failEof exp err = Left (Nothing, exp, err ++ ["end of file"])------------------------------------------------------------------------------ the end.
cake.cabal view
@@ -1,5 +1,5 @@ name: cake-version: 1.0.0+version: 1.1.0.1 category: Development synopsis: A build-system library and driver description:@@ -15,29 +15,32 @@ library default-language: Haskell2010 -- extensions: PackageImports, GeneralizedNewtypeDeriving, TypeSynonymInstances- build-depends: base==4.*- build-depends: derive==2.5.*- build-depends: mtl==2.1.*- build-depends: filepath==1.3.* - build-depends: process==1.1.*- build-depends: binary==0.5.*- build-depends: containers>=0.4 && <0.6- build-depends: directory==1.2.*- build-depends: bytestring>=0.9&&<1- build-depends: pureMD5==2.1.*- build-depends: split==0.1.*+ build-depends: base>=4 && <666+ build-depends: derive>=2.5+ build-depends: mtl>=2.1+ build-depends: filepath>=1.3 + build-depends: process>=1.1+ build-depends: binary>=0.5+ build-depends: containers>=0.4+ build-depends: directory>=1.1+ build-depends: bytestring>=0.9+ build-depends: pureMD5>=2.1+ build-depends: split>=0.1+ build-depends: parsek>=1 - exposed-modules: Cake, Cake.Actions, Cake.Core, Cake.Rules, Cake.Process, Cake.Marxup, Parsek+ exposed-modules: + Cake, Cake.Actions, Cake.Core, Cake.Rules, Cake.Process,+ Cake.Tex, Cake.MarXup, Cake.Haskell executable cake default-language: Haskell2010- build-depends: base==4.*- build-depends: process==1.1.*- build-depends: cmdargs==0.9.*- build-depends: regex-tdfa==1.1.*- build-depends: array==0.4.*- build-depends: filepath==1.3.* - build-depends: directory==1.2.*+ build-depends: base>=4+ build-depends: process>=1.1+ build-depends: cmdargs>=0.9+ build-depends: regex-tdfa>=1.1+ build-depends: array>=0.4+ build-depends: filepath>=1.3 + build-depends: directory>=1.1 main-is: Main.hs