{-# Language GeneralizedNewtypeDeriving #-} {-# Language DerivingVia #-} {-# Language StandaloneDeriving #-} module Zettel where import Text.Pandoc.Definition (Pandoc (..)) class Combine a where cappend :: a -> a -> a cempty :: a newtype UseCombine a = UC a instance Monoid a => Combine (UseCombine a) where cappend (UC a) (UC b) = UC $ a <> b cempty = UC mempty deriving via (UseCombine Text) instance Combine Text deriving via (UseCombine Pandoc) instance Combine Pandoc newtype ZettelId = ZettelId { -- | The ZettelId is just Text, however, it should also be possible to convert -- it to a list of the ID split up into it's parts. unZettelId :: Text } deriving (Show, Eq, Ord, IsString, ToString, Semigroup, Monoid) deriving (Combine) via (UseCombine ZettelId) data ZettelMetadata = ZettelMetadata { -- | Optional creation date of the Zettel.e zettelCreationDate :: Maybe Int, -- | Optional last modified date of the Zettel. zettelModifiedDate :: Maybe Int } deriving (Show, Eq) instance Combine (Maybe a) where cappend Nothing a = a cappend a _ = a cempty = Nothing instance Combine ZettelMetadata where cappend (ZettelMetadata c m) (ZettelMetadata c' m') = ZettelMetadata (cappend c c') (cappend m m') cempty = ZettelMetadata cempty cempty data Zettel = Zettel { -- | The ID that is assigned to the Zettel. zettelId :: !ZettelId, -- | The title of the Zettel, which should also be present in the body, however, -- this is useful to gather metadata about the Zettel. zettelTitle :: !Text, -- | The text body of the Zettel, which is stored as a Pandoc document to make it -- easy to export to other documents. zettelBody :: Pandoc, -- | Zettel metadata which is mostly optional. zettelMetadata :: ZettelMetadata } deriving (Show, Eq) instance Combine Zettel where cappend (Zettel a b c d) (Zettel a' b' c' d') = Zettel (cappend a a') (cappend b b') (cappend c c') (cappend d d') cempty = Zettel cempty cempty cempty cempty