diff --git a/dataflow.cabal b/dataflow.cabal
--- a/dataflow.cabal
+++ b/dataflow.cabal
@@ -1,5 +1,5 @@
 name:                dataflow
-version:             0.2.0.0
+version:             0.3.0.0
 synopsis:            Generate Graphviz documents from a Haskell representation.
 description:         Outputs .dot files that can be processed by the dot
                      command. Currently it only supports the DFD format.
diff --git a/src/DataFlow/Core.hs b/src/DataFlow/Core.hs
--- a/src/DataFlow/Core.hs
+++ b/src/DataFlow/Core.hs
@@ -19,31 +19,41 @@
             | Edge ID ID Operation Description deriving (Show, Eq)
 
 type Indent = Int
+type IndentNext = Bool
 type Step = Int
-data GenState = GenState Indent Step
+data GenState = GenState Indent IndentNext Step
 
 -- | The monad stack for generating output based on Diagram.
 type Gen t = WriterT [String] (State GenState) t
 
 write :: String -> Gen ()
 write s = do
-  (GenState n _) <- lift get
-  tell [replicate n ' ' ++ s]
+  (GenState n indentNext step) <- lift get
+  if indentNext
+    then tell [replicate n ' ' ++ s]
+    else tell [s]
+  put $ GenState n False step
 
+writeln :: String -> Gen ()
+writeln s = do
+  write s
+  write "\n"
+  modify $ \(GenState n _ s') -> GenState n True s'
+
 incrStep :: Gen ()
-incrStep = modify $ \(GenState n s') -> GenState n (s' + 1)
+incrStep = modify $ \(GenState n indentNext s') -> GenState n indentNext (s' + 1)
 
 nextStep :: Gen Int
 nextStep = do
   incrStep
-  (GenState _ s) <- lift get
+  (GenState _ _ s) <- lift get
   return s
 
 indent :: Gen ()
-indent = modify $ \(GenState n s) -> GenState (n + 2) s
+indent = modify $ \(GenState n indentNext s) -> GenState (n + 2) indentNext s
 
 dedent :: Gen ()
-dedent = modify $ \(GenState n s) -> GenState (n - 2) s
+dedent = modify $ \(GenState n indentNext s) -> GenState (n - 2) indentNext s
 
 withIndent :: Gen () -> Gen ()
 withIndent gen = do
@@ -57,13 +67,13 @@
 label :: Gen () -> Gen ()
 label contents = do
   write "label = <"
-  withIndent contents
-  write ">;"
+  contents
+  writeln ">;"
 
 tag :: String -> String -> Gen () -> Gen ()
 tag t attrs contents = do
   write $ "<" ++ t ++ (if null attrs then "" else " " ++ attrs) ++ ">"
-  withIndent contents
+  contents
   write $ "</" ++ t ++ ">"
 
 bold :: Gen () -> Gen ()
@@ -86,10 +96,10 @@
 objectWith :: Enclosing -> ID -> Gen () -> Gen ()
 objectWith (before, after) id' attributes = do
   blank
-  write $ id' ++ " " ++ [before]
+  writeln $ id' ++ " " ++ [before]
   withIndent attributes
-  write [after]
+  writeln [after]
 
 useFont :: ID -> String -> Gen ()
-useFont id' font = objectWith brackets id' $ write $ "fontname = \"" ++ font ++ "\";"
+useFont id' font = objectWith brackets id' $ writeln $ "fontname = \"" ++ font ++ "\";"
 
diff --git a/src/DataFlow/DFD.hs b/src/DataFlow/DFD.hs
--- a/src/DataFlow/DFD.hs
+++ b/src/DataFlow/DFD.hs
@@ -10,22 +10,22 @@
 
 instance DFD Object where
   dfd (External id' name) = objectWith brackets id' $ do
-    write "shape = square;"
-    write "style = bold;"
+    writeln "shape = square;"
+    writeln "style = bold;"
     label $ bold $ write name
 
   dfd (TrustBoundary id' name objects) = do
     blank
-    write $ "subgraph cluster_" ++ id' ++ " {"
+    writeln $ "subgraph cluster_" ++ id' ++ " {"
     withIndent $ do
       mapM_ dfd objects
       blank
-      write $ "label = <<b>" ++ name ++ "</b>>;"
-      write "graph[style = dashed];"
-    write "}"
+      label $ bold $ write name
+      writeln "graph[style = dashed];"
+    writeln "}"
 
   dfd (Process id' name) = objectWith brackets id' $ do
-    write "shape = circle;"
+    writeln "shape = circle;"
     label $ bold $ write name
 
   dfd (Database id' name) = objectWith brackets id' $ do
@@ -34,40 +34,40 @@
         tr $
           td $
             bold $ write name
-    write "shape = none;"
+    writeln "shape = none;"
 
   dfd (Edge i1 i2 operation description) = do
     step <- nextStep
     blank
-    write $ i1 ++ " -> " ++ i2 ++ " ["
+    writeln $ i1 ++ " -> " ++ i2 ++ " ["
     withIndent $
       label $ do
         bold $ write $ "(" ++ show step ++ ") " ++ operation
         write "<br/>"
         write description
-    write "]"
+    writeln "]"
 
 instance DFD Diagram where
   dfd (Diagram title objects) = do
-    write $ "digraph \"" ++ title ++ "\" {"
+    writeln $ "digraph \"" ++ title ++ "\" {"
     withIndent $ do
       useFont "graph" "sans-serif"
       useFont "node" "sans-serif"
       useFont "edge" "sans-serif"
       blank
 
-      write "labelloc = \"t\";"
+      writeln "labelloc = \"t\";"
       label $ bold $ write title
 
-      write "rankdir = LR;"
+      writeln "rankdir = LR;"
 
       mapM_ dfd objects
 
-    write "}"
+    writeln "}"
 
 -- | Generates the DFD output as a String.
 runDfd :: Diagram -> String
-runDfd diagram = unlines $ evalState (execWriterT (dfd diagram)) (GenState 0 0)
+runDfd diagram = concat $ evalState (execWriterT (dfd diagram)) (GenState 0 False 0)
 
 -- | Prints the DFD output to stdout.
 printDfd :: Diagram -> IO ()
