aboutsummaryrefslogtreecommitdiff
path: root/src/Text/Pandoc/Writers/Markdown.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Text/Pandoc/Writers/Markdown.hs')
-rw-r--r--src/Text/Pandoc/Writers/Markdown.hs148
1 files changed, 86 insertions, 62 deletions
diff --git a/src/Text/Pandoc/Writers/Markdown.hs b/src/Text/Pandoc/Writers/Markdown.hs
index 55d0eb2e1..eded63425 100644
--- a/src/Text/Pandoc/Writers/Markdown.hs
+++ b/src/Text/Pandoc/Writers/Markdown.hs
@@ -1,4 +1,16 @@
--- | Converts Pandoc to Markdown.
+{- |
+ Module : Text.Pandoc.Writers.Markdown
+ Copyright : Copyright (C) 2006 John MacFarlane
+ License : GNU GPL, version 2 or above
+
+ Maintainer : John MacFarlane <jgm at berkeley dot edu>
+ Stability : unstable
+ Portability : portable
+
+Conversion of 'Pandoc' documents to markdown-formatted plain text.
+
+Markdown: http://daringfireball.net/projects/markdown/
+-}
module Text.Pandoc.Writers.Markdown (
writeMarkdown
) where
@@ -11,11 +23,11 @@ import Text.PrettyPrint.HughesPJ hiding ( Str )
writeMarkdown :: WriterOptions -> Pandoc -> String
writeMarkdown options (Pandoc meta blocks) =
let body = text (writerIncludeBefore options) <>
- vcat (map (blockToMarkdown (writerTabStop options)) (formatKeys blocks)) $$ text (writerIncludeAfter options) in
- let head = if (writerStandalone options) then
- ((metaToMarkdown meta) $$ text (writerHeader options))
- else
- empty in
+ vcat (map (blockToMarkdown (writerTabStop options))
+ (formatKeys blocks)) $$ text (writerIncludeAfter options) in
+ let head = if (writerStandalone options)
+ then ((metaToMarkdown meta) $$ text (writerHeader options))
+ else empty in
render $ head <> body
-- | Escape special characters for Markdown.
@@ -28,13 +40,15 @@ escapeLinkTitle = gsub "\"" "\\\\\""
-- | Take list of inline elements and return wrapped doc.
wrappedMarkdown :: [Inline] -> Doc
-wrappedMarkdown lst = fsep $ map (fcat . (map inlineToMarkdown)) (splitBySpace lst)
+wrappedMarkdown lst = fsep $
+ map (fcat . (map inlineToMarkdown)) (splitBySpace lst)
-- | Insert Blank block between key and non-key
formatKeys :: [Block] -> [Block]
formatKeys [] = []
formatKeys [x] = [x]
-formatKeys ((Key x1 y1):(Key x2 y2):rest) = (Key x1 y1):(formatKeys ((Key x2 y2):rest))
+formatKeys ((Key x1 y1):(Key x2 y2):rest) =
+ (Key x1 y1):(formatKeys ((Key x2 y2):rest))
formatKeys ((Key x1 y1):rest) = (Key x1 y1):Blank:(formatKeys rest)
formatKeys (x:(Key x1 y1):rest) = x:Blank:(formatKeys ((Key x1 y1):rest))
formatKeys (x:rest) = x:(formatKeys rest)
@@ -43,17 +57,18 @@ formatKeys (x:rest) = x:(formatKeys rest)
metaToMarkdown :: Meta -> Doc
metaToMarkdown (Meta [] [] "") = empty
metaToMarkdown (Meta title [] "") = (titleToMarkdown title) <> (text "\n")
-metaToMarkdown (Meta title authors "") =
- (titleToMarkdown title) <> (text "\n") <> (authorsToMarkdown authors) <> (text "\n")
-metaToMarkdown (Meta title authors date) =
- (titleToMarkdown title) <> (text "\n") <> (authorsToMarkdown authors) <>
- (text "\n") <> (dateToMarkdown date) <> (text "\n")
+metaToMarkdown (Meta title authors "") = (titleToMarkdown title) <>
+ (text "\n") <> (authorsToMarkdown authors) <> (text "\n")
+metaToMarkdown (Meta title authors date) = (titleToMarkdown title) <>
+ (text "\n") <> (authorsToMarkdown authors) <> (text "\n") <>
+ (dateToMarkdown date) <> (text "\n")
titleToMarkdown :: [Inline] -> Doc
titleToMarkdown lst = text "% " <> (inlineListToMarkdown lst)
authorsToMarkdown :: [String] -> Doc
-authorsToMarkdown lst = text "% " <> text (joinWithSep ", " (map escapeString lst))
+authorsToMarkdown lst =
+ text "% " <> text (joinWithSep ", " (map escapeString lst))
dateToMarkdown :: String -> Doc
dateToMarkdown str = text "% " <> text (escapeString str)
@@ -67,33 +82,34 @@ blockToMarkdown tabStop Null = empty
blockToMarkdown tabStop (Plain lst) = wrappedMarkdown lst
blockToMarkdown tabStop (Para lst) = (wrappedMarkdown lst) <> (text "\n")
blockToMarkdown tabStop (BlockQuote lst) =
- (vcat $ map (\line -> (text "> ") <> (text line)) $ lines $ render $ vcat $
- map (blockToMarkdown tabStop) lst) <> (text "\n")
+ (vcat $ map (\line -> (text "> ") <> (text line)) $ lines $ render $ vcat $
+ map (blockToMarkdown tabStop) lst) <> (text "\n")
blockToMarkdown tabStop (Note ref lst) =
- let lns = lines $ render $ vcat $ map (blockToMarkdown tabStop) lst in
- if null lns then
- empty
- else
- let first = head lns
- rest = tail lns in
- text ("[^" ++ (escapeString ref) ++ "]: ") <> (text first) $$ (vcat $
- map (\line -> (text " ") <> (text line)) rest) <> text "\n"
+ let lns = lines $ render $ vcat $ map (blockToMarkdown tabStop) lst in
+ if null lns
+ then empty
+ else let first = head lns
+ rest = tail lns in
+ text ("[^" ++ (escapeString ref) ++ "]: ") <> (text first) $$
+ (vcat $ map (\line -> (text " ") <> (text line)) rest) <>
+ text "\n"
blockToMarkdown tabStop (Key txt (Src src tit)) =
- text " " <> char '[' <> inlineListToMarkdown txt <> char ']' <> text ": " <> text src <>
- (if tit /= "" then (text (" \"" ++ (escapeLinkTitle tit) ++ "\"")) else empty)
-blockToMarkdown tabStop (CodeBlock str) = (nest tabStop $ vcat $ map text (lines str)) <>
- text "\n"
+ text " " <> char '[' <> inlineListToMarkdown txt <> char ']' <>
+ text ": " <> text src <>
+ if tit /= "" then text (" \"" ++ (escapeLinkTitle tit) ++ "\"") else empty
+blockToMarkdown tabStop (CodeBlock str) =
+ (nest tabStop $ vcat $ map text (lines str)) <> text "\n"
blockToMarkdown tabStop (RawHtml str) = text str
blockToMarkdown tabStop (BulletList lst) =
- vcat (map (bulletListItemToMarkdown tabStop) lst) <> text "\n"
+ vcat (map (bulletListItemToMarkdown tabStop) lst) <> text "\n"
blockToMarkdown tabStop (OrderedList lst) =
- vcat (zipWith (orderedListItemToMarkdown tabStop) (enumFromTo 1 (length lst)) lst) <>
- text "\n"
+ vcat (zipWith (orderedListItemToMarkdown tabStop)
+ (enumFromTo 1 (length lst)) lst) <> text "\n"
blockToMarkdown tabStop HorizontalRule = text "\n* * * * *\n"
-blockToMarkdown tabStop (Header level lst) =
- text ((replicate level '#') ++ " ") <> (inlineListToMarkdown lst) <> (text "\n")
+blockToMarkdown tabStop (Header level lst) = text ((replicate level '#') ++
+ " ") <> (inlineListToMarkdown lst) <> (text "\n")
bulletListItemToMarkdown tabStop list =
- hang (text "- ") tabStop (vcat (map (blockToMarkdown tabStop) list))
+ hang (text "- ") tabStop (vcat (map (blockToMarkdown tabStop) list))
-- | Convert ordered list item (a list of blocks) to markdown.
orderedListItemToMarkdown :: Int -- ^ tab stop
@@ -101,8 +117,9 @@ orderedListItemToMarkdown :: Int -- ^ tab stop
-> [Block] -- ^ list item (list of blocks)
-> Doc
orderedListItemToMarkdown tabStop num list =
- hang (text ((show num) ++ "." ++ spacer)) tabStop (vcat (map (blockToMarkdown tabStop) list))
- where spacer = if (num < 10) then " " else ""
+ hang (text ((show num) ++ "." ++ spacer)) tabStop
+ (vcat (map (blockToMarkdown tabStop) list))
+ where spacer = if (num < 10) then " " else ""
-- | Convert list of Pandoc inline elements to markdown.
inlineListToMarkdown :: [Inline] -> Doc
@@ -110,39 +127,46 @@ inlineListToMarkdown lst = hcat $ map inlineToMarkdown lst
-- | Convert Pandoc inline element to markdown.
inlineToMarkdown :: Inline -> Doc
-inlineToMarkdown (Emph lst) = text "*" <> (inlineListToMarkdown lst) <> text "*"
-inlineToMarkdown (Strong lst) = text "**" <> (inlineListToMarkdown lst) <> text "**"
+inlineToMarkdown (Emph lst) = text "*" <>
+ (inlineListToMarkdown lst) <> text "*"
+inlineToMarkdown (Strong lst) = text "**" <>
+ (inlineListToMarkdown lst) <> text "**"
inlineToMarkdown (Code str) =
- case (matchRegex (mkRegex "``") str) of
- Just match -> text ("` " ++ str ++ " `")
- Nothing -> case (matchRegex (mkRegex "`") str) of
- Just match -> text ("`` " ++ str ++ " ``")
- Nothing -> text ("`" ++ str ++ "`")
+ case (matchRegex (mkRegex "``") str) of
+ Just match -> text ("` " ++ str ++ " `")
+ Nothing -> case (matchRegex (mkRegex "`") str) of
+ Just match -> text ("`` " ++ str ++ " ``")
+ Nothing -> text ("`" ++ str ++ "`")
inlineToMarkdown (Str str) = text $ escapeString str
inlineToMarkdown (TeX str) = text str
inlineToMarkdown (HtmlInline str) = text str
inlineToMarkdown (LineBreak) = text " \n"
inlineToMarkdown Space = char ' '
inlineToMarkdown (Link txt (Src src tit)) =
- let linktext = if (null txt) || (txt == [Str ""]) then
- text "link"
- else
- inlineListToMarkdown txt in
- char '[' <> linktext <> char ']' <> char '(' <> text src <>
- (if tit /= "" then (text (" \"" ++ (escapeLinkTitle tit) ++ "\"")) else empty) <> char ')'
-inlineToMarkdown (Link txt (Ref [])) = char '[' <> inlineListToMarkdown txt <> text "][]"
-inlineToMarkdown (Link txt (Ref ref)) = char '[' <> inlineListToMarkdown txt <> char ']' <>
- char '[' <> inlineListToMarkdown ref <> char ']'
+ let linktext = if (null txt) || (txt == [Str ""])
+ then text "link"
+ else inlineListToMarkdown txt in
+ char '[' <> linktext <> char ']' <> char '(' <> text src <>
+ (if tit /= ""
+ then text (" \"" ++ (escapeLinkTitle tit) ++ "\"")
+ else empty) <> char ')'
+inlineToMarkdown (Link txt (Ref [])) =
+ char '[' <> inlineListToMarkdown txt <> text "][]"
+inlineToMarkdown (Link txt (Ref ref)) =
+ char '[' <> inlineListToMarkdown txt <> char ']' <> char '[' <>
+ inlineListToMarkdown ref <> char ']'
inlineToMarkdown (Image alternate (Src source tit)) =
- let alt = if (null alternate) || (alternate == [Str ""]) then
- text "image"
- else
- inlineListToMarkdown alternate in
- char '!' <> char '[' <> alt <> char ']' <> char '(' <> text source <>
- (if tit /= "" then (text (" \"" ++ (escapeLinkTitle tit) ++ "\"")) else empty) <> char ')'
+ let alt = if (null alternate) || (alternate == [Str ""])
+ then text "image"
+ else inlineListToMarkdown alternate in
+ char '!' <> char '[' <> alt <> char ']' <> char '(' <> text source <>
+ (if tit /= ""
+ then text (" \"" ++ (escapeLinkTitle tit) ++ "\"")
+ else empty) <> char ')'
inlineToMarkdown (Image alternate (Ref [])) =
- char '!' <> char '[' <> inlineListToMarkdown alternate <> char ']'
+ char '!' <> char '[' <> inlineListToMarkdown alternate <> char ']'
inlineToMarkdown (Image alternate (Ref ref)) =
- char '!' <> char '[' <> inlineListToMarkdown alternate <> char ']' <>
- char '[' <> inlineListToMarkdown ref <> char ']'
-inlineToMarkdown (NoteRef ref) = text "[^" <> text (escapeString ref) <> char ']'
+ char '!' <> char '[' <> inlineListToMarkdown alternate <> char ']' <>
+ char '[' <> inlineListToMarkdown ref <> char ']'
+inlineToMarkdown (NoteRef ref) =
+ text "[^" <> text (escapeString ref) <> char ']'