diff --git a/remarks.cabal b/remarks.cabal
--- a/remarks.cabal
+++ b/remarks.cabal
@@ -1,5 +1,5 @@
 name:                remarks
-version:             0.1.12
+version:             0.1.13
 synopsis:            A DSL for marking student work
 description:         A DSL for marking student work; see README.md for further details.
 homepage:            https://github.com/DIKU-EDU/remarks#readme
@@ -19,8 +19,10 @@
                      , Config
                      , Export
                      , Export.Html
+                     , Export.HtmlTable
                      , Export.Generic
                      , Export.CSV
+                     , Export.MD
                      , Invalid
                      , Parser
                      , Parser.Impl
diff --git a/src/Export/HtmlTable.hs b/src/Export/HtmlTable.hs
new file mode 100644
--- /dev/null
+++ b/src/Export/HtmlTable.hs
@@ -0,0 +1,38 @@
+module Export.HtmlTable (htmlTableRemarks) where
+
+import Ast
+
+import Export.Generic
+import PrettyPrinter
+
+htmlTableRemarks :: [Judgement] -> Table 
+htmlTableRemarks js = Rows $ tblHead:(concatMap formatStart js)
+  where
+    tblHead = "Student":"Total / 100":(tail $ tableHead (head js))
+
+tableHead :: Judgement -> Row
+tableHead (j @ (Bonus _)) = [getTitle j]
+tableHead (j @ (Judgement (_, _, _, js))) =
+  ((getTitle j) ++ " / " ++ (getMaxPoints j)):(concatMap tableHead js)
+
+formatStart :: Judgement -> [Row]
+formatStart (Bonus _) = []
+formatStart (j @ (Judgement (_, _, cs, js))) =
+  [(getTitle j):(getTotal j):r1,"":(formatComments cs):r2]
+  where
+    (r1, r2) = concatUnzipMap formatJudgement js
+
+formatJudgement :: Judgement -> (Row, Row)
+formatJudgement (j @ (Bonus (_, _, cs))) = ([getTotal j], [formatComments cs])
+formatJudgement (j @ (Judgement (_, _, cs, js))) =
+  ((getTotal j):r1, (formatComments cs):r2)
+  where
+    (r1, r2) = concatUnzipMap formatJudgement js
+
+concatUnzipMap :: (a -> ([b],[c])) -> [a] -> ([b],[c])
+concatUnzipMap f l =
+  (concat c1, concat c2)
+  where (c1, c2) = unzip $ map f l
+
+formatComments :: [Comment] -> String
+formatComments cs = ppComments cs
diff --git a/src/Export/MD.hs b/src/Export/MD.hs
new file mode 100644
--- /dev/null
+++ b/src/Export/MD.hs
@@ -0,0 +1,40 @@
+module Export.MD (mdRemarks) where
+
+import Ast
+import Export.Generic
+
+import Text.PrettyPrint
+import Data.List (intersperse)
+
+mdRemarks :: [Judgement] -> String
+mdRemarks = render . vcat . intersperse (text "") . map (formatJudgement 1)
+
+formatJudgement :: Int -> Judgement -> Doc
+formatJudgement depth (j @ (Bonus (_, _, _))) =
+  (text $ replicate depth '#') <+> text "Bonus" <> colon <+> text "+" <>
+    lookupTotal j
+formatJudgement depth (j @ (Judgement (_, _, comments, judgements))) =
+  formatHeader depth j $+$
+  (nest 2 $ vcat $ map formatComment comments) $+$
+  text "" $+$
+  (vcat $ map (formatJudgement (depth + 1)) judgements)
+
+formatHeader :: Int -> Judgement -> Doc
+formatHeader depth j =
+  (text $ replicate depth '#') <+> lookupTitle j <> colon <> space <>
+    lookupTotal j <> text "/" <> lookupMaxPoints j
+
+formatComment :: Comment -> Doc
+formatComment (Comment (mood, commentParts)) =
+  text "*" <+> formatMood mood <+> (vcat $ map formatCommentPart commentParts)
+
+formatMood :: Mood -> Doc
+formatMood Positive  = text "(+)"
+formatMood Negative  = text "(-)"
+formatMood Neutral   = text ""
+formatMood Impartial = text "(?)"
+formatMood Warning = text "(!)"
+
+formatCommentPart :: CommentPart -> Doc
+formatCommentPart (CommentStr string)  = text string
+formatCommentPart (CommentCmt comment) = nest 2 $ formatComment comment
