@@ -39,6 +39,7 @@ import Text.Pandoc.Shared
3939import Text.Pandoc.Writers.Shared
4040import Text.Pandoc.Options
4141import Text.Pandoc.Templates
42+import Text.Pandoc.Logging
4243import Text.Printf ( printf )
4344import Network.URI ( isURI, unEscapeString )
4445import Data.Aeson (object, (.=), FromJSON)
@@ -57,7 +58,7 @@ import Text.Pandoc.Slides
5758import Text.Pandoc.Highlighting (highlight, styleToLaTeX,
5859 formatLaTeXInline, formatLaTeXBlock,
5960 toListingsLanguage)
60−import Text.Pandoc.Class (PandocMonad)
61+import Text.Pandoc.Class (PandocMonad, report)
6162
6263data WriterState =
6364 WriterState { stInNote :: Bool -- true if we're in a note
@@ -110,17 +111,20 @@ startingState options = WriterState {
110111
111112-- | Convert Pandoc to LaTeX.
112113writeLaTeX :: PandocMonad m => WriterOptions -> Pandoc -> m String
113−writeLaTeX options document = return $
114− evalState (pandocToLaTeX options document) $
114+writeLaTeX options document =
115+ evalStateT (pandocToLaTeX options document) $
115116 startingState options
116117
117118-- | Convert Pandoc to LaTeX Beamer.
118119writeBeamer :: PandocMonad m => WriterOptions -> Pandoc -> m String
119−writeBeamer options document = return $
120− evalState (pandocToLaTeX options document) $
120+writeBeamer options document =
121+ evalStateT (pandocToLaTeX options document) $
121122 (startingState options){ stBeamer = True }
122123
123−pandocToLaTeX :: WriterOptions -> Pandoc -> State WriterState String
124+type LW m = StateT WriterState m
125+
126+pandocToLaTeX :: PandocMonad m
127+ => WriterOptions -> Pandoc -> LW m String
124128pandocToLaTeX options (Pandoc meta blocks) = do
125129 -- Strip off final 'references' header if --natbib or --biblatex
126130 let method = writerCiteMethod options
@@ -279,7 +283,7 @@ pandocToLaTeX options (Pandoc meta blocks) = do
279283 Just tpl -> renderTemplate' tpl context'
280284
281285-- | Convert Elements to LaTeX
282−elementToLaTeX :: WriterOptions -> Element -> State WriterState Doc
286+elementToLaTeX :: PandocMonad m => WriterOptions -> Element -> LW m Doc
283287elementToLaTeX _ (Blk block) = blockToLaTeX block
284288elementToLaTeX opts (Sec level _ (id',classes,_) title' elements) = do
285289 modify $ \s -> s{stInHeading = True}
@@ -294,7 +298,7 @@ data StringContext = TextString
294298 deriving (Eq)
295299
296300-- escape things as needed for LaTeX
297−stringToLaTeX :: StringContext -> String -> State WriterState String
301+stringToLaTeX :: PandocMonad m => StringContext -> String -> LW m String
298302stringToLaTeX _ [] = return ""
299303stringToLaTeX ctx (x:xs) = do
300304 opts <- gets stOptions
@@ -339,7 +343,7 @@ stringToLaTeX ctx (x:xs) = do
339343 '\x2013' | ligatures -> "--" ++ rest
340344 _ -> x : rest
341345
342−toLabel :: String -> State WriterState String
346+toLabel :: PandocMonad m => String -> LW m String
343347toLabel z = go `fmap` stringToLaTeX URLString z
344348 where go [] = ""
345349 go (x:xs)
@@ -351,14 +355,14 @@ toLabel z = go `fmap` stringToLaTeX URLString z
351355inCmd :: String -> Doc -> Doc
352356inCmd cmd contents = char '\\' <> text cmd <> braces contents
353357
354−toSlides :: [Block] -> State WriterState [Block]
358+toSlides :: PandocMonad m => [Block] -> LW m [Block]
355359toSlides bs = do
356360 opts <- gets stOptions
357361 let slideLevel = fromMaybe (getSlideLevel bs) $ writerSlideLevel opts
358362 let bs' = prepSlides slideLevel bs
359363 concat `fmap` (mapM (elementToBeamer slideLevel) $ hierarchicalize bs')
360364
361−elementToBeamer :: Int -> Element -> State WriterState [Block]
365+elementToBeamer :: PandocMonad m => Int -> Element -> LW m [Block]
362366elementToBeamer _slideLevel (Blk b) = return [b]
363367elementToBeamer slideLevel (Sec lvl _num (ident,classes,kvs) tit elts)
364368 | lvl > slideLevel = do
@@ -408,8 +412,9 @@ isLineBreakOrSpace Space = True
408412isLineBreakOrSpace _ = False
409413
410414-- | Convert Pandoc block element to LaTeX.
411−blockToLaTeX :: Block -- ^ Block to convert
412− -> State WriterState Doc
415+blockToLaTeX :: PandocMonad m
416+ => Block -- ^ Block to convert
417+ -> LW m Doc
413418blockToLaTeX Null = return empty
414419blockToLaTeX (Div (identifier,classes,kvs) bs) = do
415420 beamer <- gets stBeamer
@@ -541,10 +546,12 @@ blockToLaTeX (CodeBlock (identifier,classes,keyvalAttr) str) = do
541546 | not (null classes) && isJust (writerHighlightStyle opts)
542547 -> highlightedCodeBlock
543548 | otherwise -> rawCodeBlock
544−blockToLaTeX (RawBlock f x)
549+blockToLaTeX b@(RawBlock f x)
545550 | f == Format "latex" || f == Format "tex"
546551 = return $ text x
547− | otherwise = return empty
552+ | otherwise = do
553+ report $ BlockNotRendered b
554+ return empty
548555blockToLaTeX (BulletList []) = return empty -- otherwise latex error
549556blockToLaTeX (BulletList lst) = do
550557 incremental <- gets stIncremental
@@ -652,14 +659,15 @@ toColDescriptor align =
652659 AlignCenter -> "c"
653660 AlignDefault -> "l"
654661
655−blockListToLaTeX :: [Block] -> State WriterState Doc
662+blockListToLaTeX :: PandocMonad m => [Block] -> LW m Doc
656663blockListToLaTeX lst = vsep `fmap` mapM blockToLaTeX lst
657664
658−tableRowToLaTeX :: Bool
665+tableRowToLaTeX :: PandocMonad m
666+ => Bool
659667 -> [Alignment]
660668 -> [Double]
661669 -> [[Block]]
662− -> State WriterState Doc
670+ -> LW m Doc
663671tableRowToLaTeX header aligns widths cols = do
664672 -- scale factor compensates for extra space between columns
665673 -- so the whole table isn't larger than columnwidth
@@ -700,8 +708,8 @@ displayMathToInline :: Inline -> Inline
700708displayMathToInline (Math DisplayMath x) = Math InlineMath x
701709displayMathToInline x = x
702710
703−tableCellToLaTeX :: Bool -> (Double, Alignment, [Block])
704− -> State WriterState Doc
711+tableCellToLaTeX :: PandocMonad m => Bool -> (Double, Alignment, [Block])
712+ -> LW m Doc
705713tableCellToLaTeX _ (0, _, blocks) =
706714 blockListToLaTeX $ walk fixLineBreaks $ walk displayMathToInline blocks
707715tableCellToLaTeX header (width, align, blocks) = do
@@ -734,7 +742,7 @@ notesToLaTeX ns = (case length ns of
734742 $ map (\x -> "\\footnotetext" <> braces x)
735743 $ reverse ns)
736744
737−listItemToLaTeX :: [Block] -> State WriterState Doc
745+listItemToLaTeX :: PandocMonad m => [Block] -> LW m Doc
738746listItemToLaTeX lst
739747 -- we need to put some text before a header if it's the first
740748 -- element in an item. This will look ugly in LaTeX regardless, but
@@ -744,7 +752,7 @@ listItemToLaTeX lst
744752 | otherwise = blockListToLaTeX lst >>= return . (text "\\item" $$) .
745753 (nest 2)
746754
747−defListItemToLaTeX :: ([Inline], [[Block]]) -> State WriterState Doc
755+defListItemToLaTeX :: PandocMonad m => ([Inline], [[Block]]) -> LW m Doc
748756defListItemToLaTeX (term, defs) = do
749757 term' <- inlineListToLaTeX term
750758 -- put braces around term if it contains an internal link,
@@ -762,11 +770,12 @@ defListItemToLaTeX (term, defs) = do
762770 "\\item" <> brackets term'' $$ def'
763771
764772-- | Craft the section header, inserting the secton reference, if supplied.
765−sectionHeader :: Bool -- True for unnumbered
773+sectionHeader :: PandocMonad m
774+ => Bool -- True for unnumbered
766775 -> [Char]
767776 -> Int
768777 -> [Inline]
769− -> State WriterState Doc
778+ -> LW m Doc
770779sectionHeader unnumbered ident level lst = do
771780 txt <- inlineListToLaTeX lst
772781 plain <- stringToLaTeX TextString $ concatMap stringify lst
@@ -831,7 +840,7 @@ sectionHeader unnumbered ident level lst = do
831840 braces txtNoNotes
832841 else empty
833842
834−hypertarget :: String -> Doc -> State WriterState Doc
843+hypertarget :: PandocMonad m => String -> Doc -> LW m Doc
835844hypertarget ident x = do
836845 ref <- text `fmap` toLabel ident
837846 internalLinks <- gets stInternalLinks
@@ -842,15 +851,16 @@ hypertarget ident x = do
842851 <> braces x
843852 else x
844853
845−labelFor :: String -> State WriterState Doc
854+labelFor :: PandocMonad m => String -> LW m Doc
846855labelFor "" = return empty
847856labelFor ident = do
848857 ref <- text `fmap` toLabel ident
849858 return $ text "\\label" <> braces ref
850859
851860-- | Convert list of inline elements to LaTeX.
852−inlineListToLaTeX :: [Inline] -- ^ Inlines to convert
853− -> State WriterState Doc
861+inlineListToLaTeX :: PandocMonad m
862+ => [Inline] -- ^ Inlines to convert
863+ -> LW m Doc
854864inlineListToLaTeX lst =
855865 mapM inlineToLaTeX (fixBreaks $ fixLineInitialSpaces lst)
856866 >>= return . hcat
@@ -878,8 +888,9 @@ isQuoted (Quoted _ _) = True
878888isQuoted _ = False
879889
880890-- | Convert inline element to LaTeX
881−inlineToLaTeX :: Inline -- ^ Inline to convert
882− -> State WriterState Doc
891+inlineToLaTeX :: PandocMonad m
892+ => Inline -- ^ Inline to convert
893+ -> LW m Doc
883894inlineToLaTeX (Span (id',classes,kvs) ils) = do
884895 ref <- toLabel id'
885896 let linkAnchor = if null id'
@@ -980,10 +991,12 @@ inlineToLaTeX (Math InlineMath str) =
980991 return $ "\\(" <> text str <> "\\)"
981992inlineToLaTeX (Math DisplayMath str) =
982993 return $ "\\[" <> text str <> "\\]"
983−inlineToLaTeX (RawInline f str)
994+inlineToLaTeX il@(RawInline f str)
984995 | f == Format "latex" || f == Format "tex"
985996 = return $ text str
986− | otherwise = return empty
997+ | otherwise = do
998+ report $ InlineNotRendered il
999+ return empty
9871000inlineToLaTeX (LineBreak) = return $ "\\\\" <> cr
9881001inlineToLaTeX SoftBreak = do
9891002 wrapText <- gets (writerWrapText . stOptions)
@@ -1066,7 +1079,7 @@ protectCode (x@(Code _ _) : xs) = ltx "\\mbox{" : x : ltx "}" : xs
10661079 where ltx = RawInline (Format "latex")
10671080protectCode (x : xs) = x : protectCode xs
10681081
1069−citationsToNatbib :: [Citation] -> State WriterState Doc
1082+citationsToNatbib :: PandocMonad m => [Citation] -> LW m Doc
10701083citationsToNatbib (one:[])
10711084 = citeCommand c p s k
10721085 where
@@ -1113,12 +1126,14 @@ citationsToNatbib cits = do
11131126 SuppressAuthor -> citeCommand "citeyear" p s k
11141127 NormalCitation -> citeCommand "citealp" p s k
11151128
1116−citeCommand :: String -> [Inline] -> [Inline] -> String -> State WriterState Doc
1129+citeCommand :: PandocMonad m
1130+ => String -> [Inline] -> [Inline] -> String -> LW m Doc
11171131citeCommand c p s k = do
11181132 args <- citeArguments p s k
11191133 return $ text ("\\" ++ c) <> args
11201134
1121−citeArguments :: [Inline] -> [Inline] -> String -> State WriterState Doc
1135+citeArguments :: PandocMonad m
1136+ => [Inline] -> [Inline] -> String -> LW m Doc
11221137citeArguments p s k = do
11231138 let s' = case s of
11241139 (Str (x:[]) : r) | isPunctuation x -> dropWhile (== Space) r
@@ -1132,7 +1147,7 @@ citeArguments p s k = do
11321147 (_ , _ ) -> brackets pdoc <> brackets sdoc
11331148 return $ optargs <> braces (text k)
11341149
1135−citationsToBiblatex :: [Citation] -> State WriterState Doc
1150+citationsToBiblatex :: PandocMonad m => [Citation] -> LW m Doc
11361151citationsToBiblatex (one:[])
11371152 = citeCommand cmd p s k
11381153 where