diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,10 @@
-# 0.2
+# 0.3.0
+
+* Added `Generic` and `Data` instances.
+
+* Split back `preface`, `header`, `content` from their annotations.
+
+# 0.2.0.0
 
 * Renamed `Annotated` to `WithSource`.
 
diff --git a/cmark-sections.cabal b/cmark-sections.cabal
--- a/cmark-sections.cabal
+++ b/cmark-sections.cabal
@@ -1,5 +1,5 @@
 name:                cmark-sections
-version:             0.2.0.0
+version:             0.3.0
 synopsis:            Represent cmark-parsed Markdown as a tree of sections
 description:
   Represent cmark-parsed Markdown as a tree of sections
diff --git a/lib/CMark/Sections.hs b/lib/CMark/Sections.hs
--- a/lib/CMark/Sections.hs
+++ b/lib/CMark/Sections.hs
@@ -1,12 +1,16 @@
-{-# LANGUAGE
-RecordWildCards,
-DeriveFunctor,
-DeriveFoldable,
-DeriveTraversable,
-OverloadedStrings,
-NoImplicitPrelude
-  #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE DeriveFoldable #-}
+{-# LANGUAGE DeriveTraversable #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude #-}
 
+#if __GLASGOW_HASKELL__ == 708
+{-# LANGUAGE StandaloneDeriving #-}
+#endif
 
 {- | This library lets you parse Markdown into a hierarchical structure
 (delimited by headings). For instance, let's say your document looks like
@@ -106,7 +110,7 @@
 only use @WithSource [Node]@, which stands for “some Markdown nodes + source”.
 -}
 data WithSource a = WithSource Text a
-  deriving (Eq, Show, Functor, Foldable, Traversable)
+  deriving (Eq, Show, Functor, Foldable, Traversable, Generic, Data)
 
 -- | Extract source from 'WithSource' (it's stored there in a field).
 getSource :: WithSource a -> Text
@@ -131,22 +135,29 @@
 -}
 data Section a b = Section {
   -- | Level (from 1 to 6).
-  level   :: Int,
+  level      :: Int,
   -- | Heading
-  heading :: (a, WithSource [Node]),
+  heading    :: WithSource [Node],
+  -- | Annotation for the heading
+  headingAnn :: a,
   -- | Text between the heading and the first subsection. Can be empty.
-  content :: (b, WithSource [Node])
+  content    :: WithSource [Node],
+  -- | Annotation for the content
+  contentAnn :: b
   }
-  deriving (Eq, Show)
+  deriving (Eq, Show, Generic, Data)
 
 {- | The whole parsed Markdown tree. In a @Document a b@, headings are
 annotated with @a@ and content blocks – with @b@.
 -}
 data Document a b = Document {
   -- | Text before the first section. Can be empty.
-  preface  :: (b, WithSource [Node]),
-  sections :: Tree.Forest (Section a b) }
-  deriving (Eq, Show)
+  preface    :: WithSource [Node],
+  -- | Annotation for the preface
+  prefaceAnn :: b,
+  -- | A tree with the sections comprising the rest of the document
+  sections   :: Tree.Forest (Section a b) }
+  deriving (Eq, Show, Generic, Data)
 
 {- | 'commonmarkToNodesWithSource' parses Markdown with the given options and
 extracts nodes from the initial 'DOCUMENT' node.
@@ -249,15 +260,18 @@
       makeTree (((level, heading), content) : xs) =
         let (nested, others) = span (\x -> x^._1._1 > level) xs
             section = Section {
-              level   = level,
-              heading = ((), heading),
-              content = ((), content)
+              level      = level,
+              heading    = heading,
+              headingAnn = (),
+              content    = content,
+              contentAnn = ()
               }
         in  Tree.Node section (makeTree nested) : makeTree others
   -- Return the result
   Document {
-    preface  = ((), prefaceAnnotated),
-    sections = makeTree blocks
+    preface    = prefaceAnnotated,
+    prefaceAnn = (),
+    sections   = makeTree blocks
     }
 
 {- $monoid-note
@@ -273,15 +287,15 @@
 
 -- | Turn the whole parsed-and-broken-down 'Document' into a list of nodes.
 flattenDocument :: Document a b -> WithSource [Node]
-flattenDocument Document{..} = snd preface <> flattenForest sections
+flattenDocument Document{..} = preface <> flattenForest sections
 
 -- | Turn a section into a list of nodes.
 flattenSection :: Section a b -> WithSource [Node]
 flattenSection Section{..} =
-  WithSource (getSource (snd heading) <> getSource (snd content))
-             (headingNode : stripSource (snd content))
+  WithSource (getSource heading <> getSource content)
+             (headingNode : stripSource content)
   where
-    headingNode = Node Nothing (HEADING level) (stripSource (snd heading))
+    headingNode = Node Nothing (HEADING level) (stripSource heading)
 
 -- | Turn a "Data.Tree" 'Tree.Tree' into a list of nodes.
 flattenTree :: Tree.Tree (Section a b) -> WithSource [Node]
@@ -290,3 +304,13 @@
 -- | Turn a "Data.Tree" 'Tree.Forest' into a list of nodes.
 flattenForest :: Tree.Forest (Section a b) -> WithSource [Node]
 flattenForest = mconcat . map flattenSection . concatMap Tree.flatten
+
+----------------------------------------------------------------------------
+-- Instances for GHC 7.8
+----------------------------------------------------------------------------
+
+#if __GLASGOW_HASKELL__ == 708
+deriving instance Typeable WithSource
+deriving instance Typeable Section
+deriving instance Typeable Document
+#endif
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -1,9 +1,7 @@
-{-# LANGUAGE
-OverloadedStrings,
-RecordWildCards,
-ViewPatterns,
-NoImplicitPrelude
-  #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE NoImplicitPrelude #-}
 
 
 module Main where
@@ -28,40 +26,45 @@
 main = hspec $ do
   let mkSect level heading content ns =
         Tree.Node
-          (Section level ((), heading) ((), content))
+          (Section level heading () content ())
           ns
   describe "converting:" $ do
     it "empty document" $ do
       let src = ""
-          preface = ((), mempty)
+          preface = mempty
+          prefaceAnn = ()
           sections = []
       nodesToDocument (commonmarkToNodesWithSource [] src)
         `shouldBe` Document{..}
     it "spaces" $ do
       let src = "  \n\n  \n"
-          preface = ((), WithSource "  \n\n  \n" [])
+          preface = WithSource "  \n\n  \n" []
+          prefaceAnn = ()
           sections = []
       nodesToDocument (commonmarkToNodesWithSource [] src)
         `shouldBe` Document{..}
     it "paragraph" $ do
       let src = "x"
-          preface = ((), WithSource "x" [
-            Node (Just (PosInfo 1 1 1 1)) PARAGRAPH [text "x"] ])
+          preface = WithSource "x" [
+            Node (Just (PosInfo 1 1 1 1)) PARAGRAPH [text "x"] ]
+          prefaceAnn = ()
           sections = []
       nodesToDocument (commonmarkToNodesWithSource [] src)
         `shouldBe` Document{..}
     it "3 paragraphs" $ do
       let src = T.unlines ["","x","","","y","","z",""]
-          preface = ((), WithSource "\nx\n\n\ny\n\nz\n\n" [
+          preface = WithSource "\nx\n\n\ny\n\nz\n\n" [
             Node (Just (PosInfo 2 1 2 1)) PARAGRAPH [text "x"],
             Node (Just (PosInfo 5 1 5 1)) PARAGRAPH [text "y"],
-            Node (Just (PosInfo 7 1 7 1)) PARAGRAPH [text "z"] ])
+            Node (Just (PosInfo 7 1 7 1)) PARAGRAPH [text "z"] ]
+          prefaceAnn = ()
           sections = []
       nodesToDocument (commonmarkToNodesWithSource [] src)
         `shouldBe` Document{..}
     it "headers" $ do
       let src = T.unlines ["# 1", "", "## 2", "", "## 3"]
-          preface = ((), mempty)
+          preface = mempty
+          prefaceAnn = ()
           sections = [
             mkSect 1 (WithSource "# 1\n\n" [text "1"]) mempty [
               mkSect 2 (WithSource "## 2\n\n" [text "2"]) mempty [],
@@ -70,7 +73,8 @@
         `shouldBe` Document{..}
     it "headers+content" $ do
       let src = T.unlines ["# 1", "", "## 2", "test", "## 3"]
-          preface = ((), mempty)
+          preface = mempty
+          prefaceAnn = ()
           sections = [
             mkSect 1 (WithSource "# 1\n\n" [text "1"]) mempty [
               mkSect 2 (WithSource "## 2\n" [text "2"])
@@ -81,7 +85,8 @@
         `shouldBe` Document{..}
     it "preface+headers" $ do
       let src = T.unlines ["blah", "# 1", "", "## 2", "", "## 3"]
-          preface = ((), commonmarkToNodesWithSource [] "blah\n")
+          preface = commonmarkToNodesWithSource [] "blah\n"
+          prefaceAnn = ()
           sections = [
             mkSect 1 (WithSource "# 1\n\n" [text "1"]) mempty [
               mkSect 2 (WithSource "## 2\n\n" [text "2"]) mempty [],
