summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordr@jones.dk <dr@jones.dk>2011-02-07 03:28:57 +0100
committerdr@jones.dk <dr@jones.dk>2011-02-07 03:28:57 +0100
commitb880b82b7f4b7c50d79f015eaf635f4b3bd8a1a3 (patch)
treef0bffd00ed41dbe294c71449c02b86d1738fe044 /src
parent91179df4907bec919e0884019da785be1ceb01b3 (diff)
Imported Upstream version 1.8.0.3
Diffstat (limited to 'src')
-rw-r--r--src/Tests/Arbitrary.hs77
-rw-r--r--src/Tests/Readers/Markdown.hs26
-rw-r--r--src/Tests/Shared.hs5
-rw-r--r--src/Tests/Writers/HTML.hs5
-rw-r--r--src/Tests/Writers/Native.hs5
-rw-r--r--src/Text/Pandoc/Readers/Markdown.hs16
-rw-r--r--src/Text/Pandoc/Shared.hs18
-rw-r--r--src/Text/Pandoc/Writers/HTML.hs141
-rw-r--r--src/markdown2pdf.hs2
9 files changed, 196 insertions, 99 deletions
diff --git a/src/Tests/Arbitrary.hs b/src/Tests/Arbitrary.hs
index 978717bef..39491431d 100644
--- a/src/Tests/Arbitrary.hs
+++ b/src/Tests/Arbitrary.hs
@@ -6,17 +6,20 @@ where
import Test.QuickCheck.Gen
import Test.QuickCheck.Arbitrary
import Control.Monad (liftM, liftM2)
-import Text.Pandoc
-import Text.Pandoc.Shared
+import Text.Pandoc.Definition
+import Text.Pandoc.Shared (normalize, escapeURI)
import Text.Pandoc.Builder
realString :: Gen String
-realString = resize 8 arbitrary -- elements wordlist
+realString = resize 8 $ listOf $ frequency [ (9, elements [' '..'\127'])
+ , (1, elements ['\128'..'\9999']) ]
-{-
-wordlist :: [String]
-wordlist = ["foo","Bar","baz","\\","/",":","\"","'","féé"]
--}
+arbAttr :: Gen Attr
+arbAttr = do
+ id' <- elements ["","loc"]
+ classes <- elements [[],["haskell"],["c","numberLines"]]
+ keyvals <- elements [[],[("start","22")],[("a","11"),("b_2","a b c")]]
+ return (id',classes,keyvals)
instance Arbitrary Inlines where
arbitrary = liftM fromList arbitrary
@@ -27,69 +30,79 @@ instance Arbitrary Blocks where
instance Arbitrary Inline where
arbitrary = resize 3 $ arbInline 3
+arbInlines :: Int -> Gen [Inline]
+arbInlines n = listOf1 (arbInline n) `suchThat` (not . startsWithSpace)
+ where startsWithSpace (Space:_) = True
+ startsWithSpace _ = False
+
-- restrict to 3 levels of nesting max; otherwise we get
-- bogged down in indefinitely large structures
arbInline :: Int -> Gen Inline
arbInline n = frequency $ [ (60, liftM Str realString)
, (60, return Space)
- , (10, liftM2 Code arbitrary realString)
+ , (10, liftM2 Code arbAttr realString)
, (5, return EmDash)
, (5, return EnDash)
, (5, return Apostrophe)
, (5, return Ellipses)
- , (5, elements [ RawInline "html" "<a>*&amp;*</a>"
+ , (5, elements [ RawInline "html" "<a id=\"eek\">"
, RawInline "latex" "\\my{command}" ])
] ++ [ x | x <- nesters, n > 1]
- where nesters = [ (10, liftM Emph $ listOf $ arbInline (n-1))
- , (10, liftM Strong $ listOf $ arbInline (n-1))
- , (10, liftM Strikeout $ listOf $ arbInline (n-1))
- , (10, liftM Superscript $ listOf $ arbInline (n-1))
- , (10, liftM Subscript $ listOf $ arbInline (n-1))
- , (10, liftM SmallCaps $ listOf $ arbInline (n-1))
+ where nesters = [ (10, liftM Emph $ arbInlines (n-1))
+ , (10, liftM Strong $ arbInlines (n-1))
+ , (10, liftM Strikeout $ arbInlines (n-1))
+ , (10, liftM Superscript $ arbInlines (n-1))
+ , (10, liftM Subscript $ arbInlines (n-1))
+-- , (10, liftM SmallCaps $ arbInlines (n-1))
, (10, do x1 <- arbitrary
- x2 <- listOf $ arbInline (n-1)
+ x2 <- arbInlines (n-1)
return $ Quoted x1 x2)
, (10, do x1 <- arbitrary
x2 <- realString
return $ Math x1 x2)
- , (10, do x1 <- listOf $ arbInline (n-1)
+ , (10, do x1 <- arbInlines (n-1)
x3 <- realString
- x2 <- realString
+ x2 <- liftM escapeURI realString
return $ Link x1 (x2,x3))
- , (10, do x1 <- listOf $ arbInline (n-1)
+ , (10, do x1 <- arbInlines (n-1)
x3 <- realString
- x2 <- realString
+ x2 <- liftM escapeURI realString
return $ Image x1 (x2,x3))
- , (2, liftM Note $ resize 3 $ listOf1 arbitrary)
+ , (2, liftM Note $ resize 3 $ listOf1 $ arbBlock (n-1))
]
instance Arbitrary Block where
arbitrary = resize 3 $ arbBlock 3
arbBlock :: Int -> Gen Block
-arbBlock n = frequency $ [ (10, liftM Plain arbitrary)
- , (15, liftM Para arbitrary)
- , (5, liftM2 CodeBlock arbitrary realString)
+arbBlock n = frequency $ [ (10, liftM Plain $ arbInlines (n-1))
+ , (15, liftM Para $ arbInlines (n-1))
+ , (5, liftM2 CodeBlock arbAttr realString)
, (2, elements [ RawBlock "html"
"<div>\n*&amp;*\n</div>"
, RawBlock "latex"
"\\begin[opt]{env}\nhi\n{\\end{env}"
])
, (5, do x1 <- choose (1 :: Int, 6)
- x2 <- arbitrary
+ x2 <- arbInlines (n-1)
return (Header x1 x2))
, (2, return HorizontalRule)
] ++ [x | x <- nesters, n > 0]
- where nesters = [ (5, liftM BlockQuote $ listOf $ arbBlock (n-1))
- , (5, liftM2 OrderedList arbitrary
- $ (listOf1 $ listOf1 $ arbBlock (n-1)))
+ where nesters = [ (5, liftM BlockQuote $ listOf1 $ arbBlock (n-1))
+ , (5, do x2 <- arbitrary
+ x3 <- arbitrary
+ x1 <- arbitrary `suchThat` (> 0)
+ x4 <- listOf1 $ listOf1 $ arbBlock (n-1)
+ return $ OrderedList (x1,x2,x3) x4 )
, (5, liftM BulletList $ (listOf1 $ listOf1 $ arbBlock (n-1)))
- , (5, do x1 <- listOf $ listOf1 $ listOf1 $ arbBlock (n-1)
- x2 <- arbitrary
- return (DefinitionList $ zip x2 x1))
+ , (5, do items <- listOf1 $ do
+ x1 <- listOf1 $ listOf1 $ arbBlock (n-1)
+ x2 <- arbInlines (n-1)
+ return (x2,x1)
+ return $ DefinitionList items)
, (2, do rs <- choose (1 :: Int, 4)
cs <- choose (1 :: Int, 4)
- x1 <- arbitrary
+ x1 <- arbInlines (n-1)
x2 <- vector cs
x3 <- vectorOf cs $ elements [0, 0.25]
x4 <- vectorOf cs $ listOf $ arbBlock (n-1)
diff --git a/src/Tests/Readers/Markdown.hs b/src/Tests/Readers/Markdown.hs
index 722a45bdb..feec8fa65 100644
--- a/src/Tests/Readers/Markdown.hs
+++ b/src/Tests/Readers/Markdown.hs
@@ -6,6 +6,7 @@ import Test.Framework
import Tests.Helpers
import Tests.Arbitrary()
import Text.Pandoc.Builder
+-- import Text.Pandoc.Shared ( normalize )
import Text.Pandoc
markdown :: String -> Pandoc
@@ -16,6 +17,19 @@ infix 5 =:
=> String -> (String, c) -> Test
(=:) = test markdown
+{-
+p_markdown_round_trip :: Block -> Bool
+p_markdown_round_trip b = matches d' d''
+ where d' = normalize $ Pandoc (Meta [] [] []) [b]
+ d'' = normalize
+ $ readMarkdown defaultParserState{ stateSmart = True }
+ $ writeMarkdown defaultWriterOptions d'
+ matches (Pandoc _ [Plain []]) (Pandoc _ []) = True
+ matches (Pandoc _ [Para []]) (Pandoc _ []) = True
+ matches (Pandoc _ [Plain xs]) (Pandoc _ [Para xs']) = xs == xs'
+ matches x y = x == y
+-}
+
tests :: [Test]
tests = [ testGroup "inline code"
[ "with attribute" =:
@@ -26,4 +40,16 @@ tests = [ testGroup "inline code"
"`*` {.haskell .special x=\"7\"}"
=?> para (codeWith ("",["haskell","special"],[("x","7")]) "*")
]
+ , testGroup "footnotes"
+ [ "indent followed by newline and flush-left text" =:
+ "[^1]\n\n[^1]: my note\n\n \nnot in note\n"
+ =?> para (note (para "my note")) +++ para "not in note"
+ , "indent followed by newline and indented text" =:
+ "[^1]\n\n[^1]: my note\n \n in note\n"
+ =?> para (note (para "my note" +++ para "in note"))
+ ]
+-- the round-trip properties frequently fail
+-- , testGroup "round trip"
+-- [ property "p_markdown_round_trip" p_markdown_round_trip
+-- ]
]
diff --git a/src/Tests/Shared.hs b/src/Tests/Shared.hs
index c35a158c1..f4bf13da4 100644
--- a/src/Tests/Shared.hs
+++ b/src/Tests/Shared.hs
@@ -10,6 +10,8 @@ tests :: [Test]
tests = [ testGroup "normalize"
[ property "p_normalize_blocks_rt" p_normalize_blocks_rt
, property "p_normalize_inlines_rt" p_normalize_inlines_rt
+ , property "p_normalize_no_trailing_spaces"
+ p_normalize_no_trailing_spaces
]
]
@@ -19,3 +21,6 @@ p_normalize_blocks_rt bs = normalize bs == normalize (normalize bs)
p_normalize_inlines_rt :: [Inline] -> Bool
p_normalize_inlines_rt ils = normalize ils == normalize (normalize ils)
+p_normalize_no_trailing_spaces :: [Inline] -> Bool
+p_normalize_no_trailing_spaces ils = null ils' || last ils' /= Space
+ where ils' = normalize $ ils ++ [Space]
diff --git a/src/Tests/Writers/HTML.hs b/src/Tests/Writers/HTML.hs
index e13d0dc87..3e1e0ddc2 100644
--- a/src/Tests/Writers/HTML.hs
+++ b/src/Tests/Writers/HTML.hs
@@ -38,4 +38,9 @@ tests = [ testGroup "inline code"
, "nolanguage" =: codeWith ("",["nolanguage"],[]) ">>="
=?> "<code class=\"nolanguage\">&gt;&gt;=</code>"
]
+ , testGroup "images"
+ [ "alt with formatting" =:
+ image "/url" "title" ("my " +++ emph "image")
+ =?> "<img src=\"/url\" title=\"title\" alt=\"my image\" />"
+ ]
]
diff --git a/src/Tests/Writers/Native.hs b/src/Tests/Writers/Native.hs
index 234fe938a..19740e0f4 100644
--- a/src/Tests/Writers/Native.hs
+++ b/src/Tests/Writers/Native.hs
@@ -11,8 +11,9 @@ p_write_rt d =
read (writeNative defaultWriterOptions{ writerStandalone = True } d) == d
p_write_blocks_rt :: [Block] -> Bool
-p_write_blocks_rt bs =
- read (writeNative defaultWriterOptions (Pandoc (Meta [] [] []) bs)) == bs
+p_write_blocks_rt bs = length bs > 20 ||
+ read (writeNative defaultWriterOptions (Pandoc (Meta [] [] []) bs)) ==
+ bs
tests :: [Test]
tests = [ property "p_write_rt" p_write_rt
diff --git a/src/Text/Pandoc/Readers/Markdown.hs b/src/Text/Pandoc/Readers/Markdown.hs
index 58d2158bf..01cc5e2e8 100644
--- a/src/Text/Pandoc/Readers/Markdown.hs
+++ b/src/Text/Pandoc/Readers/Markdown.hs
@@ -245,15 +245,17 @@ noteMarker :: GenParser Char ParserState [Char]
noteMarker = string "[^" >> many1Till (satisfy $ not . isBlank) (char ']')
rawLine :: GenParser Char ParserState [Char]
-rawLine = do
+rawLine = try $ do
notFollowedBy blankline
notFollowedBy' $ try $ skipNonindentSpaces >> noteMarker
- contents <- many1 nonEndline
- end <- option "" (newline >> optional indentSpaces >> return "\n")
- return $ contents ++ end
+ optional indentSpaces
+ anyLine
rawLines :: GenParser Char ParserState [Char]
-rawLines = many1 rawLine >>= return . concat
+rawLines = do
+ first <- anyLine
+ rest <- many rawLine
+ return $ unlines (first:rest)
noteBlock :: GenParser Char ParserState [Char]
noteBlock = try $ do
@@ -263,7 +265,9 @@ noteBlock = try $ do
char ':'
optional blankline
optional indentSpaces
- raw <- sepBy rawLines (try (blankline >> indentSpaces))
+ raw <- sepBy rawLines
+ (try (blankline >> indentSpaces >>
+ notFollowedBy blankline))
optional blanklines
endPos <- getPosition
let newnote = (ref, (intercalate "\n" raw) ++ "\n\n")
diff --git a/src/Text/Pandoc/Shared.hs b/src/Text/Pandoc/Shared.hs
index b1d5de63f..8326c89ae 100644
--- a/src/Text/Pandoc/Shared.hs
+++ b/src/Text/Pandoc/Shared.hs
@@ -243,10 +243,7 @@ orderedListMarkers (start, numstyle, numdelim) =
-- remove empty Str elements.
normalizeSpaces :: [Inline] -> [Inline]
normalizeSpaces = cleanup . dropWhile isSpaceOrEmpty
- where isSpaceOrEmpty Space = True
- isSpaceOrEmpty (Str "") = True
- isSpaceOrEmpty _ = False
- cleanup [] = []
+ where cleanup [] = []
cleanup (Space:rest) = let rest' = dropWhile isSpaceOrEmpty rest
in case rest' of
[] -> []
@@ -254,13 +251,18 @@ normalizeSpaces = cleanup . dropWhile isSpaceOrEmpty
cleanup ((Str ""):rest) = cleanup rest
cleanup (x:rest) = x : cleanup rest
+isSpaceOrEmpty :: Inline -> Bool
+isSpaceOrEmpty Space = True
+isSpaceOrEmpty (Str "") = True
+isSpaceOrEmpty _ = False
+
-- | Normalize @Pandoc@ document, consolidating doubled 'Space's,
-- combining adjacent 'Str's and 'Emph's, remove 'Null's and
-- empty elements, etc.
normalize :: (Eq a, Data a) => a -> a
normalize = topDown removeEmptyBlocks .
topDown consolidateInlines .
- bottomUp removeEmptyInlines
+ bottomUp (removeEmptyInlines . removeTrailingInlineSpaces)
removeEmptyBlocks :: [Block] -> [Block]
removeEmptyBlocks (Null : xs) = removeEmptyBlocks xs
@@ -284,6 +286,12 @@ removeEmptyInlines (Str "" : zs) = removeEmptyInlines zs
removeEmptyInlines (x : xs) = x : removeEmptyInlines xs
removeEmptyInlines [] = []
+removeTrailingInlineSpaces :: [Inline] -> [Inline]
+removeTrailingInlineSpaces = reverse . removeLeadingInlineSpaces . reverse
+
+removeLeadingInlineSpaces :: [Inline] -> [Inline]
+removeLeadingInlineSpaces = dropWhile isSpaceOrEmpty
+
consolidateInlines :: [Inline] -> [Inline]
consolidateInlines (Str x : ys) =
case concat (x : map fromStr strs) of
diff --git a/src/Text/Pandoc/Writers/HTML.hs b/src/Text/Pandoc/Writers/HTML.hs
index ef14b6809..aba73a417 100644
--- a/src/Text/Pandoc/Writers/HTML.hs
+++ b/src/Text/Pandoc/Writers/HTML.hs
@@ -42,7 +42,7 @@ import Data.Char ( ord, toLower )
import Data.List ( isPrefixOf, intersperse )
import Data.Maybe ( catMaybes )
import Control.Monad.State
-import Text.XHtml.Transitional hiding ( stringToHtml )
+import Text.XHtml.Transitional hiding ( stringToHtml, unordList, ordList )
import Text.TeXMath
import Text.XML.Light.Output
@@ -58,16 +58,17 @@ defaultWriterState = WriterState {stNotes= [], stMath = False, stHighlighting =
-- Helpers to render HTML with the appropriate function.
-renderFragment :: (HTML html) => WriterOptions -> html -> String
-renderFragment opts = if writerWrapText opts
- then renderHtmlFragment
- else showHtmlFragment
-
-- | Modified version of Text.XHtml's stringToHtml.
-- Use unicode characters wherever possible.
stringToHtml :: String -> Html
stringToHtml = primHtml . escapeStringForXML
+-- | Hard linebreak.
+nl :: WriterOptions -> Html
+nl opts = if writerWrapText opts
+ then primHtml "\n"
+ else noHtml
+
-- | Convert Pandoc document to Html string.
writeHtmlString :: WriterOptions -> Pandoc -> String
writeHtmlString opts d =
@@ -75,7 +76,7 @@ writeHtmlString opts d =
defaultWriterState
in if writerStandalone opts
then inTemplate opts tit auths date toc body' newvars
- else renderFragment opts body'
+ else dropWhile (=='\n') $ showHtmlFragment body'
-- | Convert Pandoc document to Html structure.
writeHtml :: WriterOptions -> Pandoc -> Html
@@ -119,13 +120,13 @@ pandocToHtml opts (Pandoc (Meta title' authors' date') blocks) = do
cutUp xs ++ [endSlide]
_ -> [startSlide] ++ cutUp blocks ++
[endSlide]
- blocks' <- liftM toHtmlFromList $
+ blocks' <- liftM (toHtmlFromList . intersperse (nl opts)) $
if writerSlideVariant opts `elem` [SlidySlides, S5Slides]
then mapM (blockToHtml opts) slides
else mapM (elementToHtml opts) sects
st <- get
let notes = reverse (stNotes st)
- let thebody = blocks' +++ footnoteSection notes
+ let thebody = blocks' +++ footnoteSection opts notes
let math = if stMath st
then case writerHTMLMathMethod opts of
LaTeXMathML (Just url) ->
@@ -147,7 +148,7 @@ pandocToHtml opts (Pandoc (Meta title' authors' date') blocks) = do
else noHtml
let newvars = [("highlighting-css", defaultHighlightingCss) |
stHighlighting st] ++
- [("math", renderHtmlFragment math) | stMath st]
+ [("math", showHtmlFragment math) | stMath st]
return (tit, auths, date, toc, thebody, newvars)
inTemplate :: TemplateTarget a
@@ -166,13 +167,13 @@ inTemplate opts tit auths date toc body' newvars =
date' = stripTags $ showHtmlFragment date
variables = writerVariables opts ++ newvars
context = variables ++
- [ ("body", renderHtmlFragment body')
+ [ ("body", dropWhile (=='\n') $ showHtmlFragment body')
, ("pagetitle", topTitle')
- , ("title", renderHtmlFragment tit)
+ , ("title", dropWhile (=='\n') $ showHtmlFragment tit)
, ("date", date') ] ++
[ ("html5","true") | writerHtml5 opts ] ++
(case toc of
- Just t -> [ ("toc", renderHtmlFragment t)]
+ Just t -> [ ("toc", showHtmlFragment t)]
Nothing -> []) ++
[ ("author", a) | a <- authors ]
in renderTemplate context $ writerTemplate opts
@@ -181,6 +182,14 @@ inTemplate opts tit auths date toc body' newvars =
prefixedId :: WriterOptions -> String -> HtmlAttr
prefixedId opts s = identifier $ writerIdentifierPrefix opts ++ s
+-- | Replacement for Text.XHtml's unordList.
+unordList :: WriterOptions -> ([Html] -> Html)
+unordList opts items = ulist << toListItems opts items
+
+-- | Replacement for Text.XHtml's ordList.
+ordList :: WriterOptions -> ([Html] -> Html)
+ordList opts items = olist << toListItems opts items
+
-- | Construct table of contents from list of elements.
tableOfContents :: WriterOptions -> [Element] -> State WriterState (Maybe Html)
tableOfContents _ [] = return Nothing
@@ -192,10 +201,12 @@ tableOfContents opts sects = do
then Nothing
else Just $
if writerHtml5 opts
- then tag "nav" ! [prefixedId opts' "TOC"] $
- unordList tocList
- else thediv ! [prefixedId opts' "TOC"] $
- unordList tocList
+ then (tag "nav" ! [prefixedId opts' "TOC"] $
+ nl opts +++ unordList opts tocList +++ nl opts)
+ +++ nl opts
+ else (thediv ! [prefixedId opts' "TOC"] $
+ nl opts +++ unordList opts tocList +++ nl opts)
+ +++ nl opts
-- | Convert section number to string
showSecNum :: [Int] -> String
@@ -214,7 +225,7 @@ elementToListItem opts (Sec _ num id' headerText subsecs) = do
subHeads <- mapM (elementToListItem opts) subsecs >>= return . catMaybes
let subList = if null subHeads
then noHtml
- else unordList subHeads
+ else unordList opts subHeads
return $ Just $ (anchor ! [href ("#" ++ writerIdentifierPrefix opts ++ id')] $ txt) +++ subList
-- | Convert an Element to Html.
@@ -230,21 +241,24 @@ elementToHtml opts (Sec level num id' title' elements) = do
writerSectionDivs opts || slides)]
let stuff = header'' : innerContents
return $ if slides -- S5 gets confused by the extra divs around sections
- then toHtmlFromList stuff
+ then toHtmlFromList $ intersperse (nl opts) stuff
else if writerSectionDivs opts
then if writerHtml5 opts
then tag "section" ! [prefixedId opts id']
- << stuff
- else thediv ! [prefixedId opts id'] << stuff
- else toHtmlFromList stuff
+ << intersperse (nl opts) stuff
+ else thediv ! [prefixedId opts id'] <<
+ intersperse (nl opts) stuff
+ else toHtmlFromList $ intersperse (nl opts) stuff
-- | Convert list of Note blocks to a footnote <div>.
-- Assumes notes are sorted.
-footnoteSection :: [Html] -> Html
-footnoteSection notes =
+footnoteSection :: WriterOptions -> [Html] -> Html
+footnoteSection opts notes =
if null notes
then noHtml
- else thediv ! [theclass "footnotes"] $ hr +++ (olist << notes)
+ else nl opts +++ (thediv ! [theclass "footnotes"]
+ $ nl opts +++ hr +++ nl opts +++
+ (olist << (notes ++ [nl opts])) +++ nl opts)
-- | Parse a mailto link; return Just (name, domain) or Nothing.
@@ -306,20 +320,23 @@ attrsToHtml opts (id',classes',keyvals) =
-- | Convert Pandoc block element to HTML.
blockToHtml :: WriterOptions -> Block -> State WriterState Html
-blockToHtml _ Null = return $ noHtml
+blockToHtml _ Null = return noHtml
blockToHtml opts (Plain lst) = inlineListToHtml opts lst
blockToHtml opts (Para [Image txt (s,tit)]) = do
img <- inlineToHtml opts (Image txt (s,tit))
capt <- inlineListToHtml opts txt
return $ if writerHtml5 opts
then tag "figure" <<
- [img, tag "figcaption" << capt]
+ [nl opts, img, tag "figcaption" << capt, nl opts]
else thediv ! [theclass "figure"] <<
- [img, paragraph ! [theclass "caption"] << capt]
-blockToHtml opts (Para lst) = inlineListToHtml opts lst >>= (return . paragraph)
+ [nl opts, img, paragraph ! [theclass "caption"] << capt,
+ nl opts]
+blockToHtml opts (Para lst) = do
+ contents <- inlineListToHtml opts lst
+ return $ paragraph contents
blockToHtml _ (RawBlock "html" str) = return $ primHtml str
blockToHtml _ (RawBlock _ _) = return noHtml
-blockToHtml _ (HorizontalRule) = return $ hr
+blockToHtml _ (HorizontalRule) = return hr
blockToHtml opts (CodeBlock (id',classes,keyvals) rawCode) = do
let classes' = if writerLiterateHaskell opts
then classes
@@ -335,7 +352,8 @@ blockToHtml opts (CodeBlock (id',classes,keyvals) rawCode) = do
in return $ pre ! attrs $ thecode <<
(replicate (length leadingBreaks) br +++
[stringToHtml $ addBird rawCode'])
- Right h -> modify (\st -> st{ stHighlighting = True }) >> return h
+ Right h -> modify (\st -> st{ stHighlighting = True }) >>
+ return h
blockToHtml opts (BlockQuote blocks) =
-- in S5, treat list in blockquote specially
-- if default is incremental, make it nonincremental;
@@ -348,9 +366,12 @@ blockToHtml opts (BlockQuote blocks) =
[OrderedList attribs lst] ->
blockToHtml (opts {writerIncremental = inc})
(OrderedList attribs lst)
- _ -> blockListToHtml opts blocks >>=
- (return . blockquote)
- else blockListToHtml opts blocks >>= (return . blockquote)
+ _ -> do contents <- blockListToHtml opts blocks
+ return $ blockquote (nl opts +++
+ contents +++ nl opts)
+ else do
+ contents <- blockListToHtml opts blocks
+ return $ blockquote (nl opts +++ contents +++ nl opts)
blockToHtml opts (Header level lst) = do
contents <- inlineListToHtml opts lst
secnum <- liftM stSecNum get
@@ -361,20 +382,20 @@ blockToHtml opts (Header level lst) = do
let contents'' = if writerTableOfContents opts
then anchor ! [href $ "#" ++ writerIdentifierPrefix opts ++ "TOC"] $ contents'
else contents'
- return $ case level of
+ return $ (case level of
1 -> h1 contents''
2 -> h2 contents''
3 -> h3 contents''
4 -> h4 contents''
5 -> h5 contents''
6 -> h6 contents''
- _ -> paragraph contents''
+ _ -> paragraph contents'')
blockToHtml opts (BulletList lst) = do
contents <- mapM (blockListToHtml opts) lst
let attribs = if writerIncremental opts
then [theclass "incremental"]
else []
- return $ unordList ! attribs $ contents
+ return $ (unordList opts contents) ! attribs
blockToHtml opts (OrderedList (startnum, numstyle, _) lst) = do
contents <- mapM (blockListToHtml opts) lst
let numstyle' = camelCaseToHyphenated $ show numstyle
@@ -397,20 +418,23 @@ blockToHtml opts (OrderedList (startnum, numstyle, _) lst) = do
else [thestyle $ "list-style-type: " ++
numstyle']
else [])
- return $ ordList ! attribs $ contents
+ return $ (ordList opts contents) ! attribs
blockToHtml opts (DefinitionList lst) = do
contents <- mapM (\(term, defs) ->
do term' <- liftM (dterm <<) $ inlineListToHtml opts term
- defs' <- mapM (liftM (ddef <<) . blockListToHtml opts) defs
- return $ term' : defs') lst
+ defs' <- mapM ((liftM (\x -> ddef << (x +++ nl opts))) .
+ blockListToHtml opts) defs
+ return $ nl opts : term' : nl opts : defs') lst
let attribs = if writerIncremental opts
then [theclass "incremental"]
else []
- return $ dlist ! attribs << concat contents
+ return $ dlist ! attribs << (concat contents +++ nl opts)
blockToHtml opts (Table capt aligns widths headers rows') = do
captionDoc <- if null capt
then return noHtml
- else inlineListToHtml opts capt >>= return . caption
+ else do
+ cs <- inlineListToHtml opts capt
+ return $ caption cs +++ nl opts
let percent w = show (truncate (100*w) :: Integer) ++ "%"
let widthAttrs w = if writerHtml5 opts
then [thestyle $ "width: " ++ percent w]
@@ -418,13 +442,17 @@ blockToHtml opts (Table capt aligns widths headers rows') = do
let coltags = if all (== 0.0) widths
then noHtml
else concatHtml $ map
- (\w -> col ! (widthAttrs w) $ noHtml) widths
+ (\w -> (col ! (widthAttrs w)) noHtml +++ nl opts)
+ widths
head' <- if all null headers
then return noHtml
- else liftM (thead <<) $ tableRowToHtml opts aligns 0 headers
- body' <- liftM (tbody <<) $
+ else do
+ contents <- tableRowToHtml opts aligns 0 headers
+ return $ thead << (nl opts +++ contents) +++ nl opts
+ body' <- liftM (\x -> tbody << (nl opts +++ x)) $
zipWithM (tableRowToHtml opts aligns) [1..] rows'
- return $ table $ captionDoc +++ coltags +++ head' +++ body'
+ return $ table $ nl opts +++ captionDoc +++ coltags +++ head' +++
+ body' +++ nl opts
tableRowToHtml :: WriterOptions
-> [Alignment]
@@ -440,7 +468,8 @@ tableRowToHtml opts aligns rownum cols' = do
cols'' <- sequence $ zipWith
(\alignment item -> tableItemToHtml opts mkcell alignment item)
aligns cols'
- return $ tr ! [theclass rowclass] $ toHtmlFromList cols''
+ return $ (tr ! [theclass rowclass] $ nl opts +++ toHtmlFromList cols'')
+ +++ nl opts
alignmentToString :: Alignment -> [Char]
alignmentToString alignment = case alignment of
@@ -459,11 +488,18 @@ tableItemToHtml opts tag' align' item = do
let alignAttrs = if writerHtml5 opts
then [thestyle $ "align: " ++ alignmentToString align']
else [align $ alignmentToString align']
- return $ tag' ! alignAttrs $ contents
+ return $ (tag' ! alignAttrs) contents +++ nl opts
+
+toListItems :: WriterOptions -> [Html] -> [Html]
+toListItems opts items = map (toListItem opts) items ++ [nl opts]
+
+toListItem :: WriterOptions -> Html -> Html
+toListItem opts item = nl opts +++ li item
blockListToHtml :: WriterOptions -> [Block] -> State WriterState Html
-blockListToHtml opts lst =
- mapM (blockToHtml opts) lst >>= return . toHtmlFromList
+blockListToHtml opts lst =
+ mapM (blockToHtml opts) lst >>=
+ return . toHtmlFromList . intersperse (nl opts)
-- | Convert list of Pandoc inline elements to HTML.
inlineListToHtml :: WriterOptions -> [Inline] -> State WriterState Html
@@ -566,8 +602,7 @@ inlineToHtml opts inline =
if null tit then [] else [title tit]) $
linkText
(Image txt (s,tit)) -> do
- alternate <- inlineListToHtml opts txt
- let alternate' = renderFragment opts alternate
+ let alternate' = stringify txt
let attributes = [src s] ++
(if null tit
then []
@@ -610,5 +645,5 @@ blockListToNote opts ref blocks =
_ -> otherBlocks ++ [lastBlock,
Plain backlink]
in do contents <- blockListToHtml opts blocks'
- return $ li ! [prefixedId opts ("fn" ++ ref)] $ contents
+ return $ nl opts +++ (li ! [prefixedId opts ("fn" ++ ref)]) contents
diff --git a/src/markdown2pdf.hs b/src/markdown2pdf.hs
index 4070001f1..c61aaa8cb 100644
--- a/src/markdown2pdf.hs
+++ b/src/markdown2pdf.hs
@@ -37,7 +37,7 @@ parsePandocArgs args = do
runPandoc :: [String] -> FilePath -> IO (Either String FilePath)
runPandoc inputsAndArgs output = do
- let texFile = replaceExtension output "tex"
+ let texFile = addExtension output "tex"
result <- run "pandoc" $
["-s", "--no-wrap", "-r", "markdown", "-w", "latex"]
++ inputsAndArgs ++ ["-o", texFile]