diff options
author | dr@jones.dk <dr@jones.dk> | 2011-02-07 03:28:57 +0100 |
---|---|---|
committer | dr@jones.dk <dr@jones.dk> | 2011-02-07 03:28:57 +0100 |
commit | b880b82b7f4b7c50d79f015eaf635f4b3bd8a1a3 (patch) | |
tree | f0bffd00ed41dbe294c71449c02b86d1738fe044 /src | |
parent | 91179df4907bec919e0884019da785be1ceb01b3 (diff) |
Imported Upstream version 1.8.0.3
Diffstat (limited to 'src')
-rw-r--r-- | src/Tests/Arbitrary.hs | 77 | ||||
-rw-r--r-- | src/Tests/Readers/Markdown.hs | 26 | ||||
-rw-r--r-- | src/Tests/Shared.hs | 5 | ||||
-rw-r--r-- | src/Tests/Writers/HTML.hs | 5 | ||||
-rw-r--r-- | src/Tests/Writers/Native.hs | 5 | ||||
-rw-r--r-- | src/Text/Pandoc/Readers/Markdown.hs | 16 | ||||
-rw-r--r-- | src/Text/Pandoc/Shared.hs | 18 | ||||
-rw-r--r-- | src/Text/Pandoc/Writers/HTML.hs | 141 | ||||
-rw-r--r-- | src/markdown2pdf.hs | 2 |
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>*&*</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*&*\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\">>>=</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] |