diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -3,6 +3,7 @@
 import Ast
 import Parser
 import Validator
+import PPmrk
 
 import Control.Monad ( void, filterM )
 import Data.List ( sort, partition )
@@ -120,6 +121,9 @@
 check :: [Judgement] -> IO ()
 check js = putStrLn $ pretty $ map validate js
 
+ppMarkup :: [Judgement] -> IO ()
+ppMarkup = putStrLn . toMrk
+
 main :: IO ()
 main = do
   args <- getArgs
@@ -127,4 +131,5 @@
     [] -> noCommand
     ("parse" : paths) -> parsePaths paths >>= putStrLn . pretty
     ("check" : paths) -> parsePaths paths >>= mapM_ check
+    ("markup" : paths) -> parsePaths paths >>= mapM_ ppMarkup
     (c:args) -> invalidCommand c args
diff --git a/remarks.cabal b/remarks.cabal
--- a/remarks.cabal
+++ b/remarks.cabal
@@ -1,5 +1,5 @@
 name:                remarks
-version:             0.1.1
+version:             0.1.2
 synopsis:            A DSL for marking student work
 description:         A DSL for marking student work; see README.md for further details.
 homepage:            https://github.com/oleks/remarks#readme
@@ -19,8 +19,10 @@
                      , Parser
                      , Parser.Impl
                      , Validator
+                     , PPmrk
   build-depends:       base >= 4.7 && < 5
                      , GenericPretty >= 1.2.1
+                     , pretty >= 1.1.3.3
   default-language:    Haskell2010
 
 executable remarks
diff --git a/src/PPmrk.hs b/src/PPmrk.hs
new file mode 100644
--- /dev/null
+++ b/src/PPmrk.hs
@@ -0,0 +1,27 @@
+module PPmrk (toMrk) where
+
+import Ast
+
+import Text.PrettyPrint
+
+toMrk :: [Judgement] -> String
+toMrk js = render $ vcat $ map (formatJudgement 1) js
+
+formatJudgement level (Judgement (header, comments, judgements)) = 
+  formatHeader level header $+$ 
+  (nest 2 $ vcat $ map (formatComment) comments) $+$ 
+  (vcat $ map (formatJudgement (level + 1)) judgements)
+
+formatHeader level (Header (title, point, maxPoints)) = 
+  (text $ replicate level '#') <+> text title <> colon <+> double point <> text "/" <> double maxPoints 
+
+formatComment (Comment (mood, commentParts)) = 
+  formatMood mood <+> (vcat $ map formatCommentPart commentParts)
+
+formatMood Positive  = text "+"
+formatMood Negative  = text "-"
+formatMood Neutral   = text "*"
+formatMood Impartial = text "?"
+
+formatCommentPart (CommentStr string)  = text string
+formatCommentPart (CommentCmt comment) = nest 2 $ formatComment comment
