hipe-0.1.0.0: src/Data/Geometry/Ipe/IpeGeometry.hs
module Data.Geometry.Ipe.IpeGeometry( RunWith(..)
, runSimple
, runSimple'
, runSimpleIO
, runSimpleIO'
) where
import Data.Monoid
import Data.Geometry.Ipe.IpeTypes
import Data.Geometry.Ipe.IpeView
import Data.Geometry.Ipe.IGC(IGC)
import Data.Geometry.Ipe.ReadIpeGeometry
import Data.Geometry.Ipe.WriteIpeGeometry
import Data.Geometry.Ipe.Pickle
-- | A class expressing that we can run a computation on the data stored in
-- this part of the ipe drawing. A minimum implementation implements
-- replaceIGC and extend.
class IsConvertableToIGC c => RunWith c where
-- | given a IGC, replace whatever I'm storing with the contents of the IGC
replaceIGC :: Eq a => IGC a -> c a -> c a
-- | add everything from the given IGC to whatever I'm storing allready.
extend :: Eq a => IGC a -> c a -> c a
-- | Given a function, run the function on my contents, and replace my contents
-- with the results.
runAndReplace :: Eq a => (IGC a -> IGC a) -> c a -> c a
runAndReplace f o = let gc' = f . toIGC $ o in
replaceIGC gc' o
-- | Given a function, run the computation on my contents, and replace my contents
-- with te results.
runWith :: Eq a => (IGC a -> IGC a) -> c a -> c a
runWith = runAndReplace
-- | Given a function, run the computation on my contents, and store the result
-- together with the stuff I'm allready storing.
runAndExtend :: Eq a => (IGC a -> IGC a) -> c a -> c a
runAndExtend f o = let gc = toIGC o
gc' = f gc in
extend (gc `mappend` gc') o
instance RunWith Layer where
replaceIGC gc (Layer n _) = Layer n gc
-- | we do not really add stuff to this layer, but create a copy containing
-- our stuff together with the new stuff.
extend gc (Layer n _) = Layer (n++"'") gc
instance RunWith ViewInstance where
-- | replace the contents from the first layer, and drop the rest of the layers
replaceIGC gc v = let l@(Layer n _) = head . layers $ v in
ViewInstance (ViewDefinition [n] n) [replaceIGC gc l]
extend gc v = let l = head . layers $ v in
addLayer (extend gc l) v
instance RunWith Page where
replaceIGC gc _ = Page [] [] (toIpeObjects' gc)
extend gc p = let v = head . ipeViews $ p in
addToPage (extend gc v) p
instance RunWith IpeDrawing where
replaceIGC gc (Ipe pre sty []) = Ipe pre sty [extend gc emptyPage]
replaceIGC gc (Ipe pre sty (p:_)) = Ipe pre sty [replaceIGC gc p]
extend gc (Ipe pre sty []) = Ipe pre sty [extend gc emptyPage]
extend gc (Ipe pre sty (p:pgs)) = Ipe pre sty $ extend gc p : pgs
-- | shorthand to run a computation on a given drawing, and extend the input
-- drawing with the results
runSimple :: Eq a => (IGC a -> IGC a) -> IpeDrawing a -> IpeDrawing a
runSimple = runAndExtend
-- | Run a computation on an Ipe drawing
runSimple' :: (IGC a -> b) -> IpeDrawing a -> b
runSimple' f = f . toIGC
-- | Load an drawing from a file path, and run the given computation on it.
runSimpleIO :: (Eq a, Coordinate a) =>
(IGC a -> IGC a) -> FilePath -> IO (IpeDrawing a)
runSimpleIO f = fmap (runSimple f) . loadDrawing
-- | runSimpleIO' f inPath outPath runs loads a drawing from inPath, runs
-- function f on it, extending the drawing with the result. The resulting
-- drawing is stored in as outPath.
runSimpleIO' :: (Eq a, Coordinate a) =>
(IGC a -> IGC a) -> FilePath -> FilePath -> IO ()
runSimpleIO' f inPath outPath = do
d <- loadDrawing inPath
storeDrawing (runSimple f d) outPath