@@ -42,6 +42,9 @@ import System.FilePath (dropExtension)
43data WriterState =
43data WriterState =
44 WriterState { stInNote :: Bool -- @True@ if we're in a note
44 WriterState { stInNote :: Bool -- @True@ if we're in a note
45+ , stInTable :: Bool -- @True@ if we're in a table
46+ , stTableNotes :: [(Char, Doc)] -- List of markers, notes
45 , stOLLevel :: Int -- level of ordered list nesting
48 , stOLLevel :: Int -- level of ordered list nesting
46 , stOptions :: WriterOptions -- writer options, so they don't have to be parameter
49 , stOptions :: WriterOptions -- writer options, so they don't have to be parameter
47 , stVerbInNote :: Bool -- true if document has verbatim text in note
50 , stVerbInNote :: Bool -- true if document has verbatim text in note
@@ -59,7 +62,8 @@ data WriterState =
59writeLaTeX :: WriterOptions -> Pandoc -> String
62writeLaTeX :: WriterOptions -> Pandoc -> String
60writeLaTeX options document =
63writeLaTeX options document =
61 evalState (pandocToLaTeX options document) $
64 evalState (pandocToLaTeX options document) $
65+ WriterState { stInNote = False, stInTable = False,
62− WriterState { stInNote = False, stOLLevel = 1, stOptions = options,
66+ stTableNotes = [], stOLLevel = 1, stOptions = options,
63 stVerbInNote = False, stEnumerate = False,
67 stVerbInNote = False, stEnumerate = False,
64 stTable = False, stStrikeout = False, stSubscript = False,
68 stTable = False, stStrikeout = False, stSubscript = False,
65 stUrl = False, stGraphics = False,
69 stUrl = False, stGraphics = False,
@@ -269,48 +273,61 @@ blockToLaTeX (Header level lst) = do
269 5 -> headerWith "\\subparagraph" stuffing
273 5 -> headerWith "\\subparagraph" stuffing
270 _ -> txt $$ blankline
274 _ -> txt $$ blankline
271blockToLaTeX (Table caption aligns widths heads rows) = do
275blockToLaTeX (Table caption aligns widths heads rows) = do
276+ modify $ \s -> s{ stInTable = True, stTableNotes = [] }
272 headers <- if all null heads
277 headers <- if all null heads
273 then return empty
278 then return empty
274− else liftM ($$ "\\hline\\noalign{\\smallskip}")
279+ else liftM ($$ "\\ML")
275− $ (tableRowToLaTeX widths) heads
280+ $ (tableRowToLaTeX True aligns widths) heads
276 captionText <- inlineListToLaTeX $ deVerb caption
281 captionText <- inlineListToLaTeX $ deVerb caption
282+ let capt = if isEmpty captionText
284+ else text "caption = " <> captionText <> "," <> space
277− rows' <- mapM (tableRowToLaTeX widths) rows
285+ rows' <- mapM (tableRowToLaTeX False aligns widths) rows
286+ let rows'' = intersperse ("\\\\\\noalign{\\medskip}") rows'
287+ tableNotes <- liftM (reverse . stTableNotes) get
288+ let toNote (marker, x) = "\\tnote" <> brackets (char marker) <>
290+ let notes = vcat $ map toNote tableNotes
278− let colDescriptors = concat $ zipWith toColDescriptor widths aligns
291+ let colDescriptors = text $ concat $ map toColDescriptor aligns
293+ ("\\ctable" <> brackets (capt <> text "pos = H, center, botcap"))
279− let tableBody = text ("\\begin{tabular}{" ++ colDescriptors ++ "}") $$
294+ <> braces colDescriptors
295+ $$ braces ("% notes" <> cr <> notes <> cr)
296+ $$ braces (text "% rows" $$ "\\FL" $$
280− headers $$ vcat rows' $$ "\\end{tabular}"
297+ vcat (headers : rows'') $$ "\\LL" <> cr)
281− let centered txt = "\\begin{center}" $$ txt $$ "\\end{center}"
282− modify $ \s -> s{ stTable = True }
298+ modify $ \s -> s{ stTable = True, stInTable = False, stTableNotes = [] }
283− return $ if isEmpty captionText
299+ return $ tableBody $$ blankline
284− then centered tableBody $$ blankline
300+
285− else "\\begin{table}[h]" $$ centered tableBody $$
286− inCmd "caption" captionText $$ "\\end{table}" $$ blankline
288−toColDescriptor :: Double -> Alignment -> String
301+toColDescriptor :: Alignment -> String
289−toColDescriptor 0 align =
302+toColDescriptor align =
290 case align of
303 case align of
291 AlignLeft -> "l"
304 AlignLeft -> "l"
292 AlignRight -> "r"
305 AlignRight -> "r"
293 AlignCenter -> "c"
306 AlignCenter -> "c"
294 AlignDefault -> "l"
307 AlignDefault -> "l"
295−toColDescriptor width align = ">{\\PBS" ++
297− AlignLeft -> "\\raggedright"
298− AlignRight -> "\\raggedleft"
299− AlignCenter -> "\\centering"
300− AlignDefault -> "\\raggedright") ++
301− "\\hspace{0pt}}p{" ++ printf "%.2f" width ++ "\\columnwidth}"
303blockListToLaTeX :: [Block] -> State WriterState Doc
309blockListToLaTeX :: [Block] -> State WriterState Doc
304blockListToLaTeX lst = mapM blockToLaTeX lst >>= return . vcat
310blockListToLaTeX lst = mapM blockToLaTeX lst >>= return . vcat
312+tableRowToLaTeX :: Bool
306−tableRowToLaTeX :: [Double] -> [[Block]] -> State WriterState Doc
316+ -> State WriterState Doc
307−tableRowToLaTeX widths cols = do
317+tableRowToLaTeX header aligns widths cols = do
308 renderedCells <- mapM blockListToLaTeX cols
318 renderedCells <- mapM blockListToLaTeX cols
319+ let valign = text $ if header then "[b]" else "[t]"
320+ let halign x = case x of
321+ AlignLeft -> "\\raggedright"
322+ AlignRight -> "\\raggedleft"
323+ AlignCenter -> "\\centering"
324+ AlignDefault -> "\\raggedright"
309− let toCell 0 c = c
325+ let toCell 0 _ c = c
310− toCell w c = "\\parbox[t]{" <> text (printf "%.2f" w) <>
326+ toCell w a c = "\\parbox" <> valign <>
311− "\\columnwidth}{" <> c <> cr <> "}"
327+ braces (text (printf "%.2f\\columnwidth" w)) <>
328+ braces (halign a <> cr <> c <> cr)
312− let cells = zipWith toCell widths renderedCells
329+ let cells = zipWith3 toCell widths aligns renderedCells
313− return $ (hcat $ intersperse (" & ") cells) <> "\\\\\\noalign{\\medskip}"
330+ return $ hcat $ intersperse (" & ") cells
315listItemToLaTeX :: [Block] -> State WriterState Doc
332listItemToLaTeX :: [Block] -> State WriterState Doc
316listItemToLaTeX lst = blockListToLaTeX lst >>= return . (text "\\item" $$) .
333listItemToLaTeX lst = blockListToLaTeX lst >>= return . (text "\\item" $$) .
@@ -413,9 +430,15 @@ inlineToLaTeX (Note contents) = do
413 modify (\s -> s{stInNote = True})
430 modify (\s -> s{stInNote = True})
414 contents' <- blockListToLaTeX contents
431 contents' <- blockListToLaTeX contents
415 modify (\s -> s {stInNote = False})
432 modify (\s -> s {stInNote = False})
433+ inTable <- liftM stInTable get
436+ curnotes <- liftM stTableNotes get
437+ let marker = cycle ['a'..'z'] !! length curnotes
438+ modify $ \s -> s{ stTableNotes = (marker, contents') : curnotes }
439+ return $ "\\tmark" <> brackets (char marker) <> space
440+ else return $ "\\footnote" <> braces (nest 2 contents')
416− -- note: a \n before } is needed when note ends with a Verbatim environment
441+ -- note: a \n before } needed when note ends with a Verbatim environment
417− return $ "\\footnote" <> braces (nest 2 contents')
420citationsToNatbib :: [Citation] -> State WriterState Doc
443citationsToNatbib :: [Citation] -> State WriterState Doc
421citationsToNatbib (one:[])
444citationsToNatbib (one:[])