module Data.Geometry.Ipe.IpeTypes where import Data.Geometry.Point import Data.Geometry.Geometry import Text.XML.HXT.DOM.TypeDefs import Data.Map(Map) import Data.Maybe import qualified Data.Map as M -- | Attribute Map type AMap = Map String String -------------------------------------------------------------------------------------- -- | Representing an ipe file -- | A complete ipe file data IpeDrawing a = Ipe { preamble :: Maybe Preamble , styles :: [IpeStyle] , pages :: [Page a] } deriving (Eq,Show) -- for now we simply ignore these type IpeStyle = [XmlTree] type Preamble = XmlTree instance IsPoint2Functor IpeDrawing where p2fmap f (Ipe p s pages) = Ipe p s (map (p2fmap f) pages) -- | A new blank ipe drawing emptyDrawing :: IpeDrawing a emptyDrawing = Ipe Nothing [] [emptyPage] -- | A single page in an ipe drawing data Page a = Page [LayerDefinition] [ViewDefinition] [IpeObject a] deriving (Eq, Show) -- | A new empty page emptyPage :: Page a emptyPage = Page [] [] [] type LayerDefinition = String instance IsPoint2Functor Page where p2fmap f (Page l v obs) = Page l v (map (p2fmap f) obs) -- | The definition of a view -- make active layer into an index ? data ViewDefinition = ViewDefinition { layerNames :: [String] , activeLayer :: String } deriving (Eq, Show) -------------------------------------------------------------------------------- -- | An ipe-object. The main ``thing'' that defines the drawings data IpeObject a = Path [Operation a] AMap | Group [IpeObject a] AMap | IpeText String AMap | Use (Point2' a) AMap deriving (Eq,Show) instance IsPoint2Functor IpeObject where p2fmap f (Path ops attrs) = Path (map (p2fmap f) ops) attrs p2fmap f (Group obs attrs) = Group (map (p2fmap f) obs) attrs p2fmap f (IpeText s attrs) = IpeText s attrs p2fmap f (Use p attrs) = Use (f p) attrs -- | type that represents a path in ipe. data Operation a = MoveTo (Point2' a) | LineTo (Point2' a) | CurveTo (Point2' a) (Point2' a) (Point2' a) | QCurveTo (Point2' a) (Point2' a) | Ellipse (Matrix3 a) | ArcTo (Matrix3 a) (Point2' a) | Spline [Point2' a] | ClosedSpline [Point2' a] | ClosePath deriving (Eq, Show) instance IsPoint2Functor Operation where p2fmap f (MoveTo p) = MoveTo (f p) p2fmap f (LineTo p) = LineTo (f p) p2fmap f (CurveTo p q r) = CurveTo (f p) (f q) (f r) p2fmap f (QCurveTo p q) = QCurveTo (f p) (f q) -- TODO: Should we transform the matrix too? -- p2fmap f (Ellipse m) = Ellipse m -- p2fmap f (ArcTo m p) = ArcTo m (f p) p2fmap f (Spline pts) = Spline (map f pts) p2fmap f (ClosedSpline pts) = ClosedSpline (map f pts) p2fmap f ClosePath = ClosePath -------------------------------------------------------------------------------------- -- | Stuff with attributes class HasAttributes c where attrs :: c -> AMap updateWith :: (AMap -> AMap) -> c -> c getAttr :: String -> c -> Maybe String getAttr s o = M.lookup s . attrs $ o hasAttrWithValue :: String -> String -> c -> Bool hasAttrWithValue at val o = Just val == getAttr at o hasAttr :: String -> c -> Bool hasAttr s = isJust . getAttr s extractAttr :: String -> c -> c extractAttr s = updateWith (M.delete s) instance HasAttributes (IpeObject a) where attrs (Path _ a) = a attrs (Group _ a) = a attrs (IpeText _ a) = a attrs (Use _ a) = a updateWith f (Path ops a) = Path ops (f a) updateWith f (Group obs a) = Group obs (f a) updateWith f (IpeText s a) = IpeText s (f a) updateWith f (Use p a) = Use p (f a)