diff --git a/Text/Hamlet.hs b/Text/Hamlet.hs
--- a/Text/Hamlet.hs
+++ b/Text/Hamlet.hs
@@ -28,6 +28,7 @@
     , ToAttributes (..)
       -- * Internal, for making more
     , HamletSettings (..)
+    , NewlineStyle (..)
     , hamletWithSettings
     , hamletFileWithSettings
     , defaultHamletSettings
@@ -46,12 +47,8 @@
 import Data.Maybe (fromMaybe)
 import Data.Text (Text, pack)
 import qualified Data.Text.Lazy as TL
-#if MIN_VERSION_blaze_html(0,5,0)
 import Text.Blaze.Html (Html, toHtml)
 import Text.Blaze.Internal (preEscapedText)
-#else
-import Text.Blaze (Html, preEscapedText, toHtml)
-#endif
 import qualified Data.Foldable as F
 import Control.Monad (mplus)
 import Data.Monoid (mempty, mappend)
@@ -218,11 +215,6 @@
 hamlet :: QuasiQuoter
 hamlet = hamletWithSettings hamletRules defaultHamletSettings
 
--- | A variant which adds newlines to the output. Useful for debugging
--- but may alter browser page layout.
-hamlet' :: QuasiQuoter
-hamlet' = hamletWithSettings hamletRules defaultHamletSettings{hamletNewlines=True}
-         
 xhamlet :: QuasiQuoter
 xhamlet = hamletWithSettings hamletRules xhtmlHamletSettings
 
@@ -286,7 +278,11 @@
     hr <- qhr
     case parseDoc set s of
         Error s' -> error s'
-        Ok d -> hrWithEnv hr $ \env -> docsToExp env hr [] d
+        Ok (mnl, d) -> do
+            case (mnl, hamletNewlines set) of
+                (Nothing, DefaultNewlineStyle) -> qReport False "Warning: default newline style has changed, using an explicit $newline is recommended"
+                _ -> return ()
+            hrWithEnv hr $ \env -> docsToExp env hr [] d
 
 hamletFileWithSettings :: Q HamletRules -> HamletSettings -> FilePath -> Q Exp
 hamletFileWithSettings qhr set fp = do
diff --git a/Text/Hamlet/Parse.hs b/Text/Hamlet/Parse.hs
--- a/Text/Hamlet/Parse.hs
+++ b/Text/Hamlet/Parse.hs
@@ -8,9 +8,9 @@
     , HamletSettings (..)
     , defaultHamletSettings
     , xhtmlHamletSettings
-    , debugHamletSettings
     , CloseStyle (..)
     , Binding (..)
+    , NewlineStyle (..)
     )
     where
 
@@ -60,16 +60,39 @@
             , _lineContent :: [Content]
             , _lineClasses :: [(Maybe Deref, [Content])]
             , _lineAttrs :: [Deref]
+            , _lineNoNewline :: Bool
             }
-          | LineContent [Content]
+          | LineContent [Content] Bool -- ^ True == avoid newlines
     deriving (Eq, Show, Read)
 
-parseLines :: HamletSettings -> String -> Result [(Int, Line)]
+parseLines :: HamletSettings -> String -> Result (Maybe NewlineStyle, HamletSettings, [(Int, Line)])
 parseLines set s =
-    case parse (many $ parseLine set) s s of
+    case parse parser s s of
         Left e -> Error $ show e
         Right x -> Ok x
+  where
+    parser = do
+        mnewline <- parseNewline
+        let set' =
+                case mnewline of
+                    Nothing ->
+                        case hamletNewlines set of
+                            DefaultNewlineStyle -> set { hamletNewlines = AlwaysNewlines }
+                            _ -> set
+                    Just n -> set { hamletNewlines = n }
+        res <- many (parseLine set')
+        return (mnewline, set', res)
 
+    parseNewline =
+        (try (many eol' >> string "$newline ") >> parseNewline' >>= \nl -> eol' >> return nl) <|>
+        return Nothing
+    parseNewline' =
+        (try (string "always") >> return (Just AlwaysNewlines)) <|>
+        (try (string "never") >> return (Just NoNewlines)) <|>
+        (try (string "text") >> return (Just NewlinesText))
+
+    eol' = (char '\n' >> return ()) <|> (string "\r\n" >> return ())
+
 parseLine :: HamletSettings -> Parser (Int, Line)
 parseLine set = do
     ss <- fmap sum $ many ((char ' ' >> return 1) <|>
@@ -78,6 +101,7 @@
          doctypeDollar <|>
          comment <|>
          htmlComment <|>
+         doctypeRaw <|>
          backslash <|>
          controlIf <|>
          controlElseIf <|>
@@ -90,13 +114,13 @@
          controlOf <|>
          angle <|>
          invalidDollar <|>
-         (eol' >> return (LineContent [])) <|>
+         (eol' >> return (LineContent [] True)) <|>
          (do
-            cs <- content InContent
+            (cs, avoidNewLines) <- content InContent
             isEof <- (eof >> return True) <|> return False
             if null cs && ss == 0 && isEof
                 then fail "End of Hamlet template"
-                else return $ LineContent cs)
+                else return $ LineContent cs avoidNewLines)
     return (ss, x)
   where
     eol' = (char '\n' >> return ()) <|> (string "\r\n" >> return ())
@@ -104,15 +128,21 @@
     spaceTabs = many $ oneOf " \t"
     doctype = do
         try $ string "!!!" >> eol
-        return $ LineContent [ContentRaw $ hamletDoctype set ++ "\n"]
+        return $ LineContent [ContentRaw $ hamletDoctype set ++ "\n"] True
     doctypeDollar = do
         _ <- try $ string "$doctype "
         name <- many $ noneOf "\r\n"
         eol
-        case lookup name doctypeNames of
+        case lookup name $ hamletDoctypeNames set of
             Nothing -> fail $ "Unknown doctype name: " ++ name
-            Just val -> return $ LineContent [ContentRaw $ val ++ "\n"]
+            Just val -> return $ LineContent [ContentRaw $ val ++ "\n"] True
 
+    doctypeRaw = do
+        x <- try $ string "<!"
+        y <- many $ noneOf "\r\n"
+        eol
+        return $ LineContent [ContentRaw $ concat [x, y, "\n"]] True
+
     invalidDollar = do
         _ <- char '$'
         fail "Received a command I did not understand. If you wanted a literal $, start the line with a backslash."
@@ -120,13 +150,13 @@
         _ <- try $ string "$#"
         _ <- many $ noneOf "\r\n"
         eol
-        return $ LineContent []
+        return $ LineContent [] True
     htmlComment = do
         _ <- try $ string "<!--"
         _ <- manyTill anyChar $ try $ string "-->"
         x <- many nonComments
         eol
-        return $ LineContent [ContentRaw $ concat x] -- FIXME handle variables?
+        return $ LineContent [ContentRaw $ concat x] False {- FIXME -} -- FIXME handle variables?
     nonComments = (many1 $ noneOf "\r\n<") <|> (do
         _ <- char '<'
         (do
@@ -135,8 +165,8 @@
             return "") <|> return "<")
     backslash = do
         _ <- char '\\'
-        (eol >> return (LineContent [ContentRaw "\n"]))
-            <|> (LineContent <$> content InContent)
+        (eol >> return (LineContent [ContentRaw "\n"] True))
+            <|> (uncurry LineContent <$> content InContent)
     controlIf = do
         _ <- try $ string "$if"
         spaces
@@ -197,41 +227,42 @@
             NotInQuotes -> return ()
             NotInQuotesAttr -> return ()
             InContent -> eol
-        return $ cc x
+        return (cc $ map fst x, or $ map snd x)
       where
         cc [] = []
         cc (ContentRaw a:ContentRaw b:c) = cc $ ContentRaw (a ++ b) : c
         cc (a:b) = a : cc b
     content' cr = contentHash <|> contentAt <|> contentCaret
                               <|> contentUnder
-                              <|> contentReg cr
+                              <|> contentReg' cr
     contentHash = do
         x <- parseHash
         case x of
-            Left str -> return $ ContentRaw str
-            Right deref -> return $ ContentVar deref
+            Left str -> return (ContentRaw str, null str)
+            Right deref -> return (ContentVar deref, False)
     contentAt = do
         x <- parseAt
         return $ case x of
-                    Left str -> ContentRaw str
-                    Right (s, y) -> ContentUrl y s
+                    Left str -> (ContentRaw str, null str)
+                    Right (s, y) -> (ContentUrl y s, False)
     contentCaret = do
         x <- parseCaret
         case x of
-            Left str -> return $ ContentRaw str
-            Right deref -> return $ ContentEmbed deref
+            Left str -> return (ContentRaw str, null str)
+            Right deref -> return (ContentEmbed deref, False)
     contentUnder = do
         x <- parseUnder
         case x of
-            Left str -> return $ ContentRaw str
-            Right deref -> return $ ContentMsg deref
+            Left str -> return (ContentRaw str, null str)
+            Right deref -> return (ContentMsg deref, False)
+    contentReg' x = (flip (,) False) <$> contentReg x
     contentReg InContent = (ContentRaw . return) <$> noneOf "#@^\r\n"
     contentReg NotInQuotes = (ContentRaw . return) <$> noneOf "@^#. \t\n\r>"
     contentReg NotInQuotesAttr = (ContentRaw . return) <$> noneOf "@^ \t\n\r>"
     contentReg InQuotes = (ContentRaw . return) <$> noneOf "#@^\\\"\n\r"
     tagAttribValue notInQuotes = do
         cr <- (char '"' >> return InQuotes) <|> return notInQuotes
-        content cr
+        fst <$> content cr
     tagIdent = char '#' >> TagIdent <$> tagAttribValue NotInQuotes
     tagCond = do
         d <- between (char ':') (char ':') parseDeref
@@ -277,11 +308,11 @@
               (tagIdent <|> tagCond <|> tagClass Nothing <|> tagAttrs <|> tagAttrib Nothing))
         _ <- many $ oneOf " \t\r\n"
         _ <- char '>'
-        c <- content InContent
+        (c, avoidNewLines) <- content InContent
         let (tn, attr, classes, attrsd) = tag' $ TagName name : xs
         if '/' `elem` tn
           then fail "A tag name may not contain a slash. Perhaps you have a closing tag in your HTML."
-          else return $ LineTag tn attr c classes attrsd
+          else return $ LineTag tn attr c classes attrsd avoidNewLines
 
 data TagPiece = TagName String
               | TagIdent [Content]
@@ -341,7 +372,7 @@
     cases <- mapM getOf inside
     rest' <- nestToDoc set rest
     Ok $ DocCase d cases : rest'
-nestToDoc set (Nest (LineTag tn attrs content classes attrsD) inside:rest) = do
+nestToDoc set (Nest (LineTag tn attrs content classes attrsD avoidNewLine) inside:rest) = do
     let attrFix (x, y, z) = (x, y, [(Nothing, z)])
     let takeClass (a, "class", b) = Just (a, fromMaybe [] b)
         takeClass _ = Nothing
@@ -367,24 +398,28 @@
         start = DocContent $ ContentRaw $ "<" ++ tn
         attrs'' = concatMap attrToContent attrs'
         newline' = DocContent $ ContentRaw
-                 $ if hamletNewlines set then "\n" else ""
+                 $ case hamletNewlines set of { AlwaysNewlines | not avoidNewLine -> "\n"; _ -> "" }
     inside' <- nestToDoc set inside
     rest' <- nestToDoc set rest
     Ok $ start
        : attrs''
       ++ map (DocContent . ContentAttrs) attrsD
       ++ seal
-       : newline'
        : map DocContent content
       ++ inside'
       ++ end
        : newline'
        : rest'
-nestToDoc set (Nest (LineContent content) inside:rest) = do
+nestToDoc set (Nest (LineContent content avoidNewLine) inside:rest) = do
     inside' <- nestToDoc set inside
     rest' <- nestToDoc set rest
     let newline' = DocContent $ ContentRaw
-                   $ if hamletNewlines set then "\n" else ""
+                   $ case hamletNewlines set of { NoNewlines -> ""; _ -> if nextIsContent && not avoidNewLine then "\n" else "" }
+        nextIsContent =
+            case (inside, rest) of
+                ([], Nest LineContent{} _:_) -> True
+                ([], Nest LineTag{} _:_) -> True
+                _ -> False
     Ok $ map DocContent content ++ newline':inside' ++ rest'
 nestToDoc _set (Nest (LineElseIf _) _:_) = Error "Unexpected elseif"
 nestToDoc _set (Nest LineElse _:_) = Error "Unexpected else"
@@ -414,14 +449,14 @@
             ) = compressDoc $ (DocContent $ ContentRaw $ x ++ y) : rest
 compressDoc (DocContent x:rest) = DocContent x : compressDoc rest
 
-parseDoc :: HamletSettings -> String -> Result [Doc]
+parseDoc :: HamletSettings -> String -> Result (Maybe NewlineStyle, [Doc])
 parseDoc set s = do
-    ls <- parseLines set s
-    let notEmpty (_, LineContent []) = False
+    (mnl, set', ls) <- parseLines set s
+    let notEmpty (_, LineContent [] _) = False
         notEmpty _ = True
     let ns = nestLines $ filter notEmpty ls
-    ds <- nestToDoc set ns
-    return $ compressDoc ds
+    ds <- nestToDoc set' ns
+    return (mnl, compressDoc ds)
 
 attrToContent :: (Maybe Deref, String, [(Maybe Deref, Maybe [Content])]) -> [Doc]
 attrToContent (Just cond, k, v) =
@@ -459,12 +494,20 @@
       hamletDoctype :: String
       -- | Should we add newlines to the output, making it more human-readable?
       --  Useful for client-side debugging but may alter browser page layout.
-    , hamletNewlines :: Bool
+    , hamletNewlines :: NewlineStyle
       -- | How a tag should be closed. Use this to switch between HTML, XHTML
       -- or even XML output.
     , hamletCloseStyle :: String -> CloseStyle
+      -- | Mapping from short names in \"$doctype\" statements to full doctype.
+    , hamletDoctypeNames :: [(String, String)]
     }
 
+data NewlineStyle = NoNewlines -- ^ never add newlines
+                  | NewlinesText -- ^ add newlines between consecutive text lines
+                  | AlwaysNewlines -- ^ add newlines everywhere
+                  | DefaultNewlineStyle
+    deriving Show
+
 htmlEmptyTags :: Set String
 htmlEmptyTags = Set.fromAscList
     [ "area"
@@ -484,18 +527,15 @@
 
 -- | Defaults settings: HTML5 doctype and HTML-style empty tags.
 defaultHamletSettings :: HamletSettings
-defaultHamletSettings = HamletSettings "<!DOCTYPE html>" False htmlCloseStyle
+defaultHamletSettings = HamletSettings "<!DOCTYPE html>" DefaultNewlineStyle htmlCloseStyle doctypeNames
 
 xhtmlHamletSettings :: HamletSettings
 xhtmlHamletSettings =
-    HamletSettings doctype False xhtmlCloseStyle
+    HamletSettings doctype DefaultNewlineStyle xhtmlCloseStyle doctypeNames
   where
     doctype =
       "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" " ++
       "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
-
-debugHamletSettings :: HamletSettings
-debugHamletSettings = HamletSettings "<!DOCTYPE html>" True htmlCloseStyle
 
 htmlCloseStyle :: String -> CloseStyle
 htmlCloseStyle s =
diff --git a/Text/Hamlet/RT.hs b/Text/Hamlet/RT.hs
--- a/Text/Hamlet/RT.hs
+++ b/Text/Hamlet/RT.hs
@@ -64,7 +64,7 @@
 parseHamletRT set s =
     case parseDoc set s of
         Error s' -> failure $ HamletParseException s'
-        Ok x -> liftM HamletRT $ mapM convert x
+        Ok (_, x) -> liftM HamletRT $ mapM convert x
   where
     convert x@(DocForall deref (BindVar (Ident ident)) docs) = do
         deref' <- flattenDeref' x deref
diff --git a/hamlet.cabal b/hamlet.cabal
--- a/hamlet.cabal
+++ b/hamlet.cabal
@@ -1,5 +1,5 @@
 name:            hamlet
-version:         1.0.1.4
+version:         1.1.0
 license:         MIT
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>
@@ -39,13 +39,9 @@
   test/tmp.hs
   test.hs
 
-flag blaze_html_0_5
-    description: Use blaze-html 0.5 and blaze-markup 0.5
-    default: True
-
 library
     build-depends:   base             >= 4       && < 5
-                   , shakespeare      >= 1.0     && < 1.1
+                   , shakespeare      >= 1.0.1   && < 1.1
                    , bytestring       >= 0.9
                    , template-haskell
                    , parsec           >= 2       && < 4
@@ -54,14 +50,8 @@
                    , containers       >= 0.2
                    , blaze-builder    >= 0.2     && < 0.4
                    , process          >= 1.0     && < 1.2
-
-    if flag(blaze_html_0_5)
-        build-depends:
-                     blaze-html       >= 0.5     && < 0.6
+                   , blaze-html       >= 0.5     && < 0.6
                    , blaze-markup     >= 0.5.1   && < 0.6
-    else
-        build-depends:
-                     blaze-html       >= 0.4     && < 0.5
 
     exposed-modules: Text.Hamlet
                      Text.Hamlet.RT
@@ -82,7 +72,7 @@
                  , containers       >= 0.2     && < 0.5
                  , text             >= 0.7     && < 1
                  , HUnit
-                 , hspec            >= 1.0     && < 1.2
+                 , hspec            >= 1.2     && < 1.3
                  , blaze-html       >= 0.5     && < 0.6
                  , blaze-markup     >= 0.5.1   && < 0.6
 
diff --git a/test.hs b/test.hs
--- a/test.hs
+++ b/test.hs
@@ -1,5 +1,5 @@
 import HamletTest (specs)
-import Test.Hspec
+import Test.Hspec.Core
 
 main :: IO ()
-main = hspecX [specs]
+main = hspec [specs]
diff --git a/test/HamletTest.hs b/test/HamletTest.hs
--- a/test/HamletTest.hs
+++ b/test/HamletTest.hs
@@ -3,7 +3,7 @@
 module HamletTest (specs) where 
 
 import Test.HUnit hiding (Test)
-import Test.Hspec
+import Test.Hspec.Core
 import Test.Hspec.HUnit
 
 import Prelude hiding (reverse)
@@ -14,11 +14,12 @@
 import qualified Data.List as L
 import qualified Data.Map as Map
 import Data.Text (Text, pack, unpack)
-import Data.Monoid (mappend)
+import Data.Monoid (mappend,mconcat)
 import qualified Data.Set as Set
 import qualified Text.Blaze.Html.Renderer.Text
 import Text.Blaze.Html (toHtml)
 import Text.Blaze.Internal (preEscapedString)
+import Text.Blaze
 
 specs = describe "hamlet"
   [ it "empty" caseEmpty
@@ -72,6 +73,7 @@
   , it "parens" caseParens
   , it "hamlet literals" caseHamletLiterals
   , it "hamlet' and xhamlet'" caseHamlet'
+  , it "hamlet tuple" caseTuple
 
 
 
@@ -83,7 +85,7 @@
 
 
   , it "ignores a blank line" $ do
-    helper "<p>foo</p>" [hamlet|
+    helper "<p>foo</p>\n" [hamlet|
 <p>
 
     foo
@@ -94,9 +96,10 @@
 
 
 
-  , it "hamlet angle bracket syntax" $
+  , it "angle bracket syntax" $
       helper "<p class=\"foo\" height=\"100\"><span id=\"bar\" width=\"50\">HELLO</span></p>"
         [hamlet|
+$newline never
 <p.foo height="100">
     <span #bar width=50>HELLO
 |]
@@ -106,7 +109,9 @@
   , it "hamlet module names" $
     let foo = "foo" in
       helper "oof oof 3.14 -5"
-        [hamlet|#{Data.List.reverse foo} #
+        [hamlet|
+$newline never
+#{Data.List.reverse foo} #
 #{L.reverse foo} #
 #{show 3.14} #{show -5}|]
 
@@ -157,6 +162,7 @@
 
   , it "HTML comments" $ do
     helper "<p>1</p><p>2 not ignored</p>" [hamlet|
+$newline never
 <p>1
 <!-- ignored comment -->
 <p>
@@ -192,13 +198,13 @@
 
 
   , it "conditional class" $ do
-      helper "<p class=\"current\"></p>" 
+      helper "<p class=\"current\"></p>\n"
         [hamlet|<p :False:.ignored :True:.current>|]
 
-      helper "<p class=\"1 3 2 4\"></p>"
+      helper "<p class=\"1 3 2 4\"></p>\n"
         [hamlet|<p :True:.1 :True:class=2 :False:.a :False:class=b .3 class=4>|]
 
-      helper "<p class=\"foo bar baz\"></p>"
+      helper "<p class=\"foo bar baz\"></p>\n"
         [hamlet|<p class=foo class=bar class=baz>|]
 
 
@@ -214,31 +220,32 @@
 
 
   , it "non-poly HTML" $ do
-      helperHtml "<h1>HELLO WORLD</h1>" [shamlet|
+      helperHtml "<h1>HELLO WORLD</h1>\n" [shamlet|
   <h1>HELLO WORLD
   |]
-      helperHtml "<h1>HELLO WORLD</h1>" $(shamletFile "test/hamlets/nonpolyhtml.hamlet")
+      helperHtml "<h1>HELLO WORLD</h1>\n" $(shamletFile "test/hamlets/nonpolyhtml.hamlet")
 
 
   , it "non-poly Hamlet" $ do
       let embed = [hamlet|<p>EMBEDDED|]
-      helper "<h1>url</h1><p>EMBEDDED</p>" [hamlet|
+      helper "<h1>url</h1>\n<p>EMBEDDED</p>\n" [hamlet|
   <h1>@{Home}
   ^{embed}
   |]
-      helper "<h1>url</h1>" $(hamletFile "test/hamlets/nonpolyhamlet.hamlet")
+      helper "<h1>url</h1>\n" $(hamletFile "test/hamlets/nonpolyhamlet.hamlet")
 
   , it "non-poly IHamlet" $ do
       let embed = [ihamlet|<p>EMBEDDED|]
-      ihelper "<h1>Adios</h1><p>EMBEDDED</p>" [ihamlet|
+      ihelper "<h1>Adios</h1>\n<p>EMBEDDED</p>\n" [ihamlet|
   <h1>_{Goodbye}
   ^{embed}
   |]
-      ihelper "<h1>Hola</h1>" $(ihamletFile "test/hamlets/nonpolyihamlet.hamlet")
+      ihelper "<h1>Hola</h1>\n" $(ihamletFile "test/hamlets/nonpolyihamlet.hamlet")
 
   , it "pattern-match tuples: forall" $ do
       let people = [("Michael", 26), ("Miriam", 25)]
       helper "<dl><dt>Michael</dt><dd>26</dd><dt>Miriam</dt><dd>25</dd></dl>" [hamlet|
+$newline never
 <dl>
     $forall (name, age) <- people
         <dt>#{name}
@@ -247,6 +254,7 @@
   , it "pattern-match tuples: maybe" $ do
       let people = Just ("Michael", 26)
       helper "<dl><dt>Michael</dt><dd>26</dd></dl>" [hamlet|
+$newline never
 <dl>
     $maybe (name, age) <- people
         <dt>#{name}
@@ -255,6 +263,7 @@
   , it "pattern-match tuples: with" $ do
       let people = ("Michael", 26)
       helper "<dl><dt>Michael</dt><dd>26</dd></dl>" [hamlet|
+$newline never
 <dl>
     $with (name, age) <- people
         <dt>#{name}
@@ -262,17 +271,17 @@
 |]
   , it "list syntax for interpolation" $ do
       helper "<ul><li>1</li><li>2</li><li>3</li></ul>" [hamlet|
+$newline never
 <ul>
     $forall num <- [1, 2, 3]
         <li>#{show num}
 |]
-{-
   , it "infix operators" $
       helper "5" [hamlet|#{show $ (4 + 5) - (2 + 2)}|]
   , it "infix operators with parens" $
-      helper "5" [hamlet|#{show (2 + 3)}|]
-      -}
+      helper "5" [hamlet|#{show ((+) 1 1 + 3)}|]
   , it "doctypes" $ helper "<!DOCTYPE html>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" [hamlet|
+$newline never
 $doctype 5
 $doctype strict
 |]
@@ -281,6 +290,7 @@
       let nothing  = Nothing
           justTrue = Just True
       in helper "<br><br><br><br>" [hamlet|
+$newline never
 $case nothing
     $of Just val
     $of Nothing
@@ -304,7 +314,8 @@
   , it "case on Url" $
       let url1 = Home
           url2 = Sub SubUrl
-      in helper "<br><br>" [hamlet|
+      in helper "<br>\n<br>\n" [hamlet|
+$newline always
 $case url1
     $of Home
         <br>
@@ -320,6 +331,7 @@
   , it "pattern-match constructors: forall" $ do
       let people = [Pair "Michael" 26, Pair "Miriam" 25]
       helper "<dl><dt>Michael</dt><dd>26</dd><dt>Miriam</dt><dd>25</dd></dl>" [hamlet|
+$newline text
 <dl>
     $forall Pair name age <- people
         <dt>#{name}
@@ -328,6 +340,7 @@
   , it "pattern-match constructors: maybe" $ do
       let people = Just $ Pair "Michael" 26
       helper "<dl><dt>Michael</dt><dd>26</dd></dl>" [hamlet|
+$newline text
 <dl>
     $maybe Pair name age <- people
         <dt>#{name}
@@ -336,6 +349,7 @@
   , it "pattern-match constructors: with" $ do
       let people = Pair "Michael" 26
       helper "<dl><dt>Michael</dt><dd>26</dd></dl>" [hamlet|
+$newline text
 <dl>
     $with Pair name age <- people
         <dt>#{name}
@@ -343,21 +357,56 @@
 |]
 
   , it "multiline tags" $ helper
-      "<foo bar=\"baz\" bin=\"bin\">content</foo>" [hamlet|
+      "<foo bar=\"baz\" bin=\"bin\">content</foo>\n" [hamlet|
 <foo bar=baz
      bin=bin>content
 |]
   , let attrs = [("bar", "baz"), ("bin", "<>\"&")]
      in it "*{...} attributes" $ helper
-      "<foo bar=\"baz\" bin=\"&lt;&gt;&quot;&amp;\">content</foo>" [hamlet|
+      "<foo bar=\"baz\" bin=\"&lt;&gt;&quot;&amp;\">content</foo>\n" [hamlet|
 <foo *{attrs}>content
 |]
   , it "blank attr values" $ helper
-      "<foo bar=\"\" baz bin=\"\"></foo>"
+      "<foo bar=\"\" baz bin=\"\"></foo>\n"
       [hamlet|<foo bar="" baz bin=>|]
   , it "greater than in attr" $ helper
-      "<button data-bind=\"enable: someFunction() > 5\">hello</button>"
+      "<button data-bind=\"enable: someFunction() > 5\">hello</button>\n"
       [hamlet|<button data-bind="enable: someFunction() > 5">hello|]
+  , it "normal doctype" $ helper
+      "<!DOCTYPE html>\n"
+      [hamlet|<!DOCTYPE html>|]
+  , it "newline style" $ helper
+      "<p>foo</p>\n<pre>bar\nbaz\nbin</pre>\n"
+      [hamlet|
+$newline always
+<p>foo
+<pre>
+    bar
+    baz
+    bin
+|]
+  , it "avoid newlines" $ helper
+      "<p>foo</p><pre>barbazbin</pre>"
+      [hamlet|
+$newline always
+<p>foo#
+<pre>#
+    bar#
+    baz#
+    bin#
+|]
+  , it "manual linebreaks" $ helper
+      "<p>foo</p><pre>bar\nbaz\nbin</pre>"
+      [hamlet|
+$newline never
+<p>foo
+<pre>
+    bar
+    \
+    baz
+    \
+    bin
+|]
   ]
 
 data Pair = Pair String Int
@@ -445,10 +494,12 @@
 caseTag :: Assertion
 caseTag = do
     helper "<p class=\"foo\"><div id=\"bar\">baz</div></p>" [hamlet|
+$newline text
 <p .foo>
   <#bar>baz
 |]
     helper "<p class=\"foo.bar\"><div id=\"bar\">baz</div></p>" [hamlet|
+$newline text
 <p class=foo.bar>
   <#bar>baz
 |]
@@ -580,24 +631,24 @@
 |]
 
 caseScriptNotEmpty :: Assertion
-caseScriptNotEmpty = helper "<script></script>" [hamlet|<script>|]
+caseScriptNotEmpty = helper "<script></script>\n" [hamlet|<script>|]
 
 caseMetaEmpty :: Assertion
 caseMetaEmpty = do
-    helper "<meta>" [hamlet|<meta>|]
-    helper "<meta/>" [xhamlet|<meta>|]
+    helper "<meta>\n" [hamlet|<meta>|]
+    helper "<meta/>\n" [xhamlet|<meta>|]
 
 caseInputEmpty :: Assertion
 caseInputEmpty = do
-    helper "<input>" [hamlet|<input>|]
-    helper "<input/>" [xhamlet|<input>|]
+    helper "<input>\n" [hamlet|<input>|]
+    helper "<input/>\n" [xhamlet|<input>|]
 
 caseMultiClass :: Assertion
-caseMultiClass = helper "<div class=\"foo bar\"></div>" [hamlet|<.foo.bar>|]
+caseMultiClass = helper "<div class=\"foo bar\"></div>\n" [hamlet|<.foo.bar>|]
 
 caseAttribOrder :: Assertion
 caseAttribOrder =
-    helper "<meta 1 2 3>" [hamlet|<meta 1 2 3>|]
+    helper "<meta 1 2 3>\n" [hamlet|<meta 1 2 3>|]
 
 caseNothing :: Assertion
 caseNothing = do
@@ -644,6 +695,7 @@
 caseEscape :: Assertion
 caseEscape = do
     helper "#this is raw\n " [hamlet|
+$newline never
 \#this is raw
 \
 \ 
@@ -659,16 +711,16 @@
 
 caseAttribCond :: Assertion
 caseAttribCond = do
-    helper "<select></select>" [hamlet|<select :False:selected>|]
-    helper "<select selected></select>" [hamlet|<select :True:selected>|]
-    helper "<meta var=\"foo:bar\">" [hamlet|<meta var=foo:bar>|]
-    helper "<select selected></select>"
+    helper "<select></select>\n" [hamlet|<select :False:selected>|]
+    helper "<select selected></select>\n" [hamlet|<select :True:selected>|]
+    helper "<meta var=\"foo:bar\">\n" [hamlet|<meta var=foo:bar>|]
+    helper "<select selected></select>\n"
         [hamlet|<select :true theArg:selected>|]
 
-    helper "<select></select>" [hamlet|<select :False:selected>|]
-    helper "<select selected></select>" [hamlet|<select :True:selected>|]
-    helper "<meta var=\"foo:bar\">" [hamlet|<meta var=foo:bar>|]
-    helper "<select selected></select>"
+    helper "<select></select>\n" [hamlet|<select :False:selected>|]
+    helper "<select selected></select>\n" [hamlet|<select :True:selected>|]
+    helper "<meta var=\"foo:bar\">\n" [hamlet|<meta var=foo:bar>|]
+    helper "<select selected></select>\n"
         [hamlet|<select :true theArg:selected>|]
 
 caseNonAscii :: Assertion
@@ -684,7 +736,9 @@
 
 caseTrailingDollarSign :: Assertion
 caseTrailingDollarSign =
-    helper "trailing space \ndollar sign #" [hamlet|trailing space #
+    helper "trailing space \ndollar sign #" [hamlet|
+$newline never
+trailing space #
 \
 dollar sign #\
 |]
@@ -692,29 +746,31 @@
 caseNonLeadingPercent :: Assertion
 caseNonLeadingPercent =
     helper "<span style=\"height:100%\">foo</span>" [hamlet|
+$newline never
 <span style=height:100%>foo
 |]
 
 caseQuotedAttribs :: Assertion
 caseQuotedAttribs =
     helper "<input type=\"submit\" value=\"Submit response\">" [hamlet|
+$newline never
 <input type=submit value="Submit response">
 |]
 
 caseSpacedDerefs :: Assertion
 caseSpacedDerefs = do
     helper "&lt;var&gt;" [hamlet|#{var theArg}|]
-    helper "<div class=\"&lt;var&gt;\"></div>" [hamlet|<.#{var theArg}>|]
+    helper "<div class=\"&lt;var&gt;\"></div>\n" [hamlet|<.#{var theArg}>|]
 
 caseAttribVars :: Assertion
 caseAttribVars = do
-    helper "<div id=\"&lt;var&gt;\"></div>" [hamlet|<##{var theArg}>|]
-    helper "<div class=\"&lt;var&gt;\"></div>" [hamlet|<.#{var theArg}>|]
-    helper "<div f=\"&lt;var&gt;\"></div>" [hamlet|< f=#{var theArg}>|]
+    helper "<div id=\"&lt;var&gt;\"></div>\n" [hamlet|<##{var theArg}>|]
+    helper "<div class=\"&lt;var&gt;\"></div>\n" [hamlet|<.#{var theArg}>|]
+    helper "<div f=\"&lt;var&gt;\"></div>\n" [hamlet|< f=#{var theArg}>|]
 
-    helper "<div id=\"&lt;var&gt;\"></div>" [hamlet|<##{var theArg}>|]
-    helper "<div class=\"&lt;var&gt;\"></div>" [hamlet|<.#{var theArg}>|]
-    helper "<div f=\"&lt;var&gt;\"></div>" [hamlet|< f=#{var theArg}>|]
+    helper "<div id=\"&lt;var&gt;\"></div>\n" [hamlet|<##{var theArg}>|]
+    helper "<div class=\"&lt;var&gt;\"></div>\n" [hamlet|<.#{var theArg}>|]
+    helper "<div f=\"&lt;var&gt;\"></div>\n" [hamlet|< f=#{var theArg}>|]
 
 caseStringsAndHtml :: Assertion
 caseStringsAndHtml = do
@@ -727,6 +783,7 @@
     helper
       "<table><tbody><tr><td>1</td></tr><tr><td>2</td></tr></tbody></table>"
       [hamlet|
+$newline never
 <table>
   <tbody>
     $forall user <- users
@@ -741,6 +798,7 @@
           , "</select>"
           ])
         [hamlet|
+$newline never
 <select #"#{name}" name=#{name}>
     <option :isBoolBlank val:selected>
     <option value=true :isBoolTrue val:selected>Yes
@@ -766,8 +824,8 @@
 
 caseExternal :: Assertion
 caseExternal = do
-    helper "foo<br>" $(hamletFile "test/hamlets/external.hamlet")
-    helper "foo<br/>" $(xhamletFile "test/hamlets/external.hamlet")
+    helper "foo\n<br>\n" $(hamletFile "test/hamlets/external.hamlet")
+    helper "foo\n<br/>\n" $(xhamletFile "test/hamlets/external.hamlet")
   where
     foo = "foo"
 
@@ -798,14 +856,14 @@
 caseHamlet' = do
     helper' "foo" [shamlet|foo|]
     helper' "foo" [xshamlet|foo|]
-    helper "<br>" $ const $ [shamlet|<br>|]
-    helper "<br/>" $ const $ [xshamlet|<br>|]
+    helper "<br>\n" $ const $ [shamlet|<br>|]
+    helper "<br/>\n" $ const $ [xshamlet|<br>|]
 
     -- new with generalized stuff
     helper' "foo" [shamlet|foo|]
     helper' "foo" [xshamlet|foo|]
-    helper "<br>" $ const $ [shamlet|<br>|]
-    helper "<br/>" $ const $ [xshamlet|<br>|]
+    helper "<br>\n" $ const $ [shamlet|<br>|]
+    helper "<br/>\n" $ const $ [xshamlet|<br>|]
 
 
 instance Show Url where
@@ -832,6 +890,21 @@
 
 
 
+caseTuple :: Assertion
+caseTuple = do
+   helper "(1,1)" [hamlet| #{("1","1")}|]
+   helper "foo" [hamlet| 
+    $with (a,b) <- ("foo","bar")
+      #{a}
+   |]
+   helper "url" [hamlet| 
+    $with (a,b) <- (Home,Home)
+      @{a}
+   |]
+   helper "url" [hamlet| 
+    $with p <- (Home,[])
+      @?{p}
+   |]
 
 data Msg = Hello | Goodbye
 
@@ -842,3 +915,11 @@
   where
     showMsg Hello = preEscapedString "Hola"
     showMsg Goodbye = preEscapedString "Adios"
+
+instance (ToMarkup a, ToMarkup b) => ToMarkup (a,b) where
+  toMarkup (a,b) = do
+    toMarkup "("
+    toMarkup a
+    toMarkup ","
+    toMarkup b
+    toMarkup ")"
