diff --git a/Yesod/Markdown.hs b/Yesod/Markdown.hs
--- a/Yesod/Markdown.hs
+++ b/Yesod/Markdown.hs
@@ -35,6 +35,12 @@
 instance ToFormField (Maybe Markdown) y where
   toFormField = maybeMarkdownField
 
+lines' :: String -> [String]
+lines' = map go . lines where
+  go [] = []
+  go ('\r':[]) = []
+  go (x:xs) = x : go xs
+
 markdownField :: (IsForm f, FormType f ~ Markdown)
               => FormFieldSettings -> Maybe Markdown -> f
 markdownField = requiredFieldHelper markdownFieldProfile
@@ -44,7 +50,7 @@
 
 markdownFieldProfile :: FieldProfile sub y Markdown
 markdownFieldProfile = FieldProfile
-    { fpParse = Right . Markdown
+    { fpParse = Right . Markdown . unlines . lines'
     , fpRender = \(Markdown m) -> m
     , fpWidget = \theId name val _isReq -> addHamlet
 #if GHC7
diff --git a/Yesod/Markdown/Macros.hs b/Yesod/Markdown/Macros.hs
--- a/Yesod/Markdown/Macros.hs
+++ b/Yesod/Markdown/Macros.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE ViewPatterns, QuasiQuotes, FlexibleContexts, CPP #-}
 -- | Macros allow users to access more advanced functionality from within Markdown syntax. There are two types
 -- of macros, block and inline, which allow substitution of 'Block' and 'Inline' data, respectively. Macros
 -- are called in a very similar fashion to shell programs: the argument string is split on whitespace. The
@@ -14,6 +14,7 @@
   where
 
 import Text.Pandoc
+import Safe
 import Yesod
 import Control.Applicative
 import Data.Map ( Map )
@@ -46,14 +47,14 @@
 -- where @MACRO_NAME@ is the identifying name of the macro and @MACRO_ARGS@ is a space-separated list of arguments.
 inlineMacros
   :: Yesod master
-  => String                                              -- ^ Magic string to introduce the macro
-  -> Map String ([String] -> GHandler sub master Inline) -- ^ Lookup table from macro names to macro functions
+  => String                                                -- ^ Magic string to introduce the macro
+  -> Map String ([String] -> GHandler sub master [Inline]) -- ^ Lookup table from macro names to macro functions
   -> Pandoc
   -> GHandler sub master Pandoc
-inlineMacros magic table p = processWithM inlineMacros' p where
+inlineMacros magic table p = processWithM (fmap concat . mapM inlineMacros') p where
   inlineMacros' (Code (splitAt (length magic) -> (magic',words -> ((flip Map.lookup table -> Just f):xs))))
     | magic == magic' = f xs
-  inlineMacros' b = return b
+  inlineMacros' b = return [b]
 
 -- | Convert a 'Hamlet' value to a 'Block'.
 hamletToBlock :: Hamlet (Route master) -> GHandler sub master Block
@@ -62,3 +63,14 @@
 -- | Convert a 'Hamlet' value to an 'Inline'.
 hamletToInline :: Hamlet (Route master) -> GHandler sub master Inline
 hamletToInline x = HtmlInline . U.toString . renderHtml . x <$> getUrlRenderParams
+
+-- | Read in 
+localRoute :: Read (Route master) => [String] -> GHandler sub master Inline
+localRoute = maybe (return (Str "")) f . readMay . unwords where
+  f = hamletToInline . (\x ->
+#if GHC7
+        [hamlet|
+#else
+        [$hamlet|
+#endif
+@x@|])
diff --git a/yesod-markdown.cabal b/yesod-markdown.cabal
--- a/yesod-markdown.cabal
+++ b/yesod-markdown.cabal
@@ -2,7 +2,7 @@
 -- options, see
 -- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.
 Name:                 yesod-markdown
-Version:              0.1
+Version:              0.2.1
 Synopsis:             Markdown processing for Yesod sites using Pandoc
 Description:          Process Markdown in Yesod sites.
 License:              BSD3
@@ -34,6 +34,7 @@
                , containers
                , bytestring
                , utf8-string
+               , safe
 
 source-repository head
   type:     git
