diff --git a/LICENSE b/LICENSE
deleted file mode 100644
--- a/LICENSE
+++ /dev/null
@@ -1,30 +0,0 @@
-Copyright Andrew Martin (c) 2016
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-
-    * Neither the name of Andrew Martin nor the names of other
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/dot.cabal b/dot.cabal
--- a/dot.cabal
+++ b/dot.cabal
@@ -1,29 +1,66 @@
-name:                dot
-version:             0.2.2
-synopsis:            Data types and encoding for graphviz dot files
-description:         Please see README.md
-homepage:            https://github.com/andrewthad/dot#readme
-license:             BSD3
-license-file:        LICENSE
-author:              Andrew Martin
-maintainer:          andrew.thaddeus@gmail.com
-copyright:           2016 Andrew Martin
-category:            web
-build-type:          Simple
-cabal-version:       >=1.10
+cabal-version: 2.2
+name:
+  dot
+version:
+  0.3
+synopsis:
+  Datatypes and encoding for graphviz dot files
+description:
+  Datatypes and encoding for graphviz dot files.
+  See the example directory for example usage.
+homepage:
+  https://github.com/andrewthad/dot
+license:
+  BSD-3-Clause
+author:
+  Andrew Martin
+maintainer:
+  Andrew Martin <andrew.thaddeus@gmail.com>
+  chessai <chessai1996@gmail.com>
+copyright:
+  2019 Andrew Martin
+category:
+  Data,Graphics,Graphs
+build-type:
+  Simple
 
 library
-  hs-source-dirs:      src
+  hs-source-dirs:
+    src
   exposed-modules:
-    Dot.Types
+    Dot
     Dot.Text
-    Data.Graph.Immutable.Dot
+    Dot.Types
   build-depends:
-      base >= 4.7 && < 5
+    , base >= 4.7 && < 5
     , text
-    , impure-containers >= 0.3 && < 0.5
-  default-language:    Haskell2010
+  default-language:
+    Haskell2010
 
+executable example
+  hs-source-dirs:
+    example
+  main-is:
+    Example.hs
+  build-depends:
+    , base
+    , dot
+    , text
+  default-language:
+    Haskell2010
+  if !(flag(examples))
+    buildable: False
+
+flag examples
+  description:
+    Also compile examples
+  manual:
+    True
+  default:
+    False
+
 source-repository head
-  type:     git
-  location: https://github.com/andrewthad/dot
+  type:
+    git
+  location:
+    https://github.com/andrewthad/dot
diff --git a/example/Example.hs b/example/Example.hs
new file mode 100644
--- /dev/null
+++ b/example/Example.hs
@@ -0,0 +1,25 @@
+{-# language OverloadedStrings #-}
+
+module Main (main) where
+
+import Dot
+
+main :: IO ()
+main = do
+  putStrLn $ "dumping example dotgraph to " ++ target
+  encodeToFile target example
+ 
+target :: FilePath
+target = "example/example.dot"
+
+example :: DotGraph
+example = DotGraph Strict Directed (Just "foobar")
+  [ StatementNode $ NodeStatement "a1"
+    [ Attribute "color" "blue"
+    , Attribute "shape" "box"
+    ]
+  , StatementNode $ NodeStatement "a2" []
+  , StatementEdge $ EdgeStatement (ListTwo "a1" "a2" ["a3"])
+      [ Attribute "color" "red"
+      ]
+  ]
diff --git a/src/Data/Graph/Immutable/Dot.hs b/src/Data/Graph/Immutable/Dot.hs
deleted file mode 100644
--- a/src/Data/Graph/Immutable/Dot.hs
+++ /dev/null
@@ -1,54 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-
-module Data.Graph.Immutable.Dot
-  ( toDotGraph
-  , toLabeledDotGraph
-  ) where
-
-import Data.Graph.Types
-import Dot.Types
-import Control.Applicative
-import Data.Text (Text)
-import qualified Data.Graph.Immutable as Graph
-import qualified Data.Text as Text
-import qualified Data.Text.Lazy as LText
-import qualified Data.Text.Lazy.Builder as Builder
-import qualified Data.Text.Lazy.Builder.Int as Builder
-
--- | This is a fairly general way to build a dot file from a graph.
-toDotGraph :: Directionality -> (v -> [Attribute]) -> (v -> v -> e -> [Attribute]) -> Graph g e v -> DotGraph
-toDotGraph directionality vertexAttrs edgeAttrs g =
-  DotGraph strictness directionality Nothing $ []
-    ++ vertexDeclarations
-    ++ edgeDeclarations
-  where
-  vertexDeclarations = getConst $ flip Graph.traverseVertices_ g $ \vertex v ->
-    Const [StatementNode $ NodeStatement (vertexToNodeId vertex) (vertexAttrs v)]
-  edgeDeclarations = getConst $ flip Graph.traverseEdges_ g $ \vertexFrom vertexTo vFrom vTo e ->
-    Const [StatementEdge $ EdgeStatement
-             (ListTwo
-               (EdgeNode (vertexToNodeId vertexFrom))
-               (EdgeNode (vertexToNodeId vertexTo))
-               []
-             )
-             (edgeAttrs vFrom vTo e)
-          ]
-  strictness = case directionality of
-    Undirected -> NonStrict
-    Directed -> Strict
-
--- | This is a more convenient variant of 'toDotGraph' that just labels
--- all of the nodes and edges. It does not color or style anything.
-toLabeledDotGraph :: Directionality -> (v -> Text) -> (e -> Text) -> Graph g e v -> DotGraph
-toLabeledDotGraph dir vertexLabel edgeLabel =
-  toDotGraph dir (textToLabel . vertexLabel) (const $ const $ textToLabel . edgeLabel)
-
-textToLabel :: Text -> [Attribute]
-textToLabel name = [Attribute "label" (Id name)]
-
-vertexToNodeId :: Vertex g -> NodeId
-vertexToNodeId = id
-  . flip NodeId Nothing . Id
-  . LText.toStrict . Builder.toLazyText
-  . mappend "a" . Builder.decimal . Graph.vertexInt
-
diff --git a/src/Dot.hs b/src/Dot.hs
new file mode 100644
--- /dev/null
+++ b/src/Dot.hs
@@ -0,0 +1,6 @@
+module Dot
+  ( module D
+  ) where
+
+import Dot.Text as D
+import Dot.Types as D
diff --git a/src/Dot/Text.hs b/src/Dot/Text.hs
--- a/src/Dot/Text.hs
+++ b/src/Dot/Text.hs
@@ -4,15 +4,17 @@
   ( encode
   , encodeLazy
   , builder
+  , encodeToFile
   ) where
 
+import Data.Monoid
 import Data.Text (Text)
 import Data.Text.Lazy.Builder (Builder)
-import qualified Data.Text.Lazy.Builder as Builder
-import qualified Data.Text.Lazy as LText
-import qualified Data.Text as Text
-import Data.Monoid
 import Dot.Types
+import qualified Data.Text as Text
+import qualified Data.Text.IO as TIO
+import qualified Data.Text.Lazy as LText
+import qualified Data.Text.Lazy.Builder as Builder
 
 levelSpaces :: Int
 levelSpaces = 2
@@ -26,6 +28,9 @@
 encodeLazy :: DotGraph -> LText.Text
 encodeLazy = Builder.toLazyText . builder
 
+encodeToFile :: FilePath -> DotGraph -> IO ()
+encodeToFile fp dg = TIO.writeFile fp (encode dg)
+
 builder :: DotGraph -> Builder
 builder (DotGraph strictness directionality mid statements) = mempty
   <> encodeStrictness strictness
@@ -39,7 +44,14 @@
 encodeId (Id theId) = case Text.uncons theId of
   Just (c,_) -> if not (c >= '0' && c <= '9') && Text.all (\c -> (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_') theId
     then Builder.fromText theId
-    else "\"" <> Builder.fromText (Text.replace "\"" "\\\"" theId) <> "\""
+    else "\""
+      <> Builder.fromText
+         ( Text.replace "\"" "\\\""
+         $ Text.replace "\n" "\\n"
+         $ Text.replace "\\" "\\\\"
+         $ theId
+         )
+      <> "\""
   Nothing -> "\"\""
 
 encodeNodeId :: NodeId -> Builder
@@ -126,7 +138,6 @@
   Directed -> "digraph "
   Undirected -> "graph "
 
-
 example :: DotGraph
 example = DotGraph Strict Directed (Just "foobar")
   [ StatementNode $ NodeStatement "a1"
@@ -138,4 +149,3 @@
     [ Attribute "color" "red"
     ]
   ]
-
diff --git a/src/Dot/Types.hs b/src/Dot/Types.hs
--- a/src/Dot/Types.hs
+++ b/src/Dot/Types.hs
@@ -41,10 +41,6 @@
 instance IsString NodeId where
   fromString str = NodeId (fromString str) Nothing
 
--- | Stole this from semigroups. Remove it once GHC 8.0 gains
---   widespread adoption.
-data NonEmpty a = a :| [a]
-
 data ListTwo a = ListTwo
   { listTwoFirst :: a
   , listTwoSecond :: a
