LaTeX writer: improve longtable output.
- Don't create minipages for regular paragraphs. - Put width and alignment information in the longtable column descriptors. - Closes #6883.
This commit is contained in:
parent
b50ac3a95b
commit
7c4d7db9c7
2 changed files with 61 additions and 41 deletions
|
@ -256,7 +256,7 @@ $if(highlighting-macros)$
|
||||||
$highlighting-macros$
|
$highlighting-macros$
|
||||||
$endif$
|
$endif$
|
||||||
$if(tables)$
|
$if(tables)$
|
||||||
\usepackage{longtable,booktabs}
|
\usepackage{longtable,booktabs,array}
|
||||||
\usepackage{calc} % for calculating minipage widths
|
\usepackage{calc} % for calculating minipage widths
|
||||||
$if(beamer)$
|
$if(beamer)$
|
||||||
\usepackage{caption}
|
\usepackage{caption}
|
||||||
|
|
|
@ -778,8 +778,17 @@ blockToLaTeX (Header level (id',classes,_) lst) = do
|
||||||
return hdr
|
return hdr
|
||||||
blockToLaTeX (Table _ blkCapt specs thead tbody tfoot) = do
|
blockToLaTeX (Table _ blkCapt specs thead tbody tfoot) = do
|
||||||
let (caption, aligns, widths, heads, rows) = toLegacyTable blkCapt specs thead tbody tfoot
|
let (caption, aligns, widths, heads, rows) = toLegacyTable blkCapt specs thead tbody tfoot
|
||||||
|
-- simple tables have to have simple cells:
|
||||||
|
let isSimple [Plain _] = True
|
||||||
|
isSimple [Para _] = True
|
||||||
|
isSimple [] = True
|
||||||
|
isSimple _ = False
|
||||||
|
let widths' = if all (== 0) widths && not (all (all isSimple) rows)
|
||||||
|
then replicate (length aligns)
|
||||||
|
(1 / fromIntegral (length aligns))
|
||||||
|
else widths
|
||||||
(captionText, captForLof, captNotes) <- getCaption False caption
|
(captionText, captForLof, captNotes) <- getCaption False caption
|
||||||
let toHeaders hs = do contents <- tableRowToLaTeX True aligns widths hs
|
let toHeaders hs = do contents <- tableRowToLaTeX True aligns hs
|
||||||
return ("\\toprule" $$ contents $$ "\\midrule")
|
return ("\\toprule" $$ contents $$ "\\midrule")
|
||||||
let removeNote (Note _) = Span ("", [], []) []
|
let removeNote (Note _) = Span ("", [], []) []
|
||||||
removeNote x = x
|
removeNote x = x
|
||||||
|
@ -796,8 +805,12 @@ blockToLaTeX (Table _ blkCapt specs thead tbody tfoot) = do
|
||||||
then empty
|
then empty
|
||||||
else "\\caption" <> captForLof <> braces captionText
|
else "\\caption" <> captForLof <> braces captionText
|
||||||
<> "\\tabularnewline"
|
<> "\\tabularnewline"
|
||||||
rows' <- mapM (tableRowToLaTeX False aligns widths) rows
|
rows' <- mapM (tableRowToLaTeX False aligns) rows
|
||||||
let colDescriptors = literal $ T.concat $ map toColDescriptor aligns
|
let colDescriptors =
|
||||||
|
(if all (== 0) widths'
|
||||||
|
then hcat . map literal
|
||||||
|
else (\xs -> cr <> nest 2 (vcat $ map literal xs))) $
|
||||||
|
zipWith (toColDescriptor (length widths')) aligns widths'
|
||||||
modify $ \s -> s{ stTable = True }
|
modify $ \s -> s{ stTable = True }
|
||||||
notes <- notesToLaTeX <$> gets stNotes
|
notes <- notesToLaTeX <$> gets stNotes
|
||||||
return $ "\\begin{longtable}[]" <>
|
return $ "\\begin{longtable}[]" <>
|
||||||
|
@ -832,13 +845,26 @@ getCaption externalNotes txt = do
|
||||||
else return empty
|
else return empty
|
||||||
return (capt, captForLof, footnotes)
|
return (capt, captForLof, footnotes)
|
||||||
|
|
||||||
toColDescriptor :: Alignment -> Text
|
toColDescriptor :: Int -> Alignment -> Double -> Text
|
||||||
toColDescriptor align =
|
toColDescriptor _numcols align 0 =
|
||||||
case align of
|
case align of
|
||||||
AlignLeft -> "l"
|
AlignLeft -> "l"
|
||||||
AlignRight -> "r"
|
AlignRight -> "r"
|
||||||
AlignCenter -> "c"
|
AlignCenter -> "c"
|
||||||
AlignDefault -> "l"
|
AlignDefault -> "l"
|
||||||
|
toColDescriptor numcols align width =
|
||||||
|
T.pack $ printf
|
||||||
|
">{%s\\arraybackslash}p{(\\columnwidth - %d\\tabcolsep) * \\real{%0.2f}}"
|
||||||
|
align'
|
||||||
|
((numcols - 1) * 2)
|
||||||
|
width
|
||||||
|
where
|
||||||
|
align' :: String
|
||||||
|
align' = case align of
|
||||||
|
AlignLeft -> "\\raggedright"
|
||||||
|
AlignRight -> "\\raggedleft"
|
||||||
|
AlignCenter -> "\\centering"
|
||||||
|
AlignDefault -> "\\raggedright"
|
||||||
|
|
||||||
blockListToLaTeX :: PandocMonad m => [Block] -> LW m (Doc Text)
|
blockListToLaTeX :: PandocMonad m => [Block] -> LW m (Doc Text)
|
||||||
blockListToLaTeX lst =
|
blockListToLaTeX lst =
|
||||||
|
@ -847,21 +873,10 @@ blockListToLaTeX lst =
|
||||||
tableRowToLaTeX :: PandocMonad m
|
tableRowToLaTeX :: PandocMonad m
|
||||||
=> Bool
|
=> Bool
|
||||||
-> [Alignment]
|
-> [Alignment]
|
||||||
-> [Double]
|
|
||||||
-> [[Block]]
|
-> [[Block]]
|
||||||
-> LW m (Doc Text)
|
-> LW m (Doc Text)
|
||||||
tableRowToLaTeX header aligns widths cols = do
|
tableRowToLaTeX header aligns cols = do
|
||||||
let isSimple [Plain _] = True
|
cells <- mapM (tableCellToLaTeX header) $ zip aligns cols
|
||||||
isSimple [Para _] = True
|
|
||||||
isSimple [] = True
|
|
||||||
isSimple _ = False
|
|
||||||
-- simple tables have to have simple cells:
|
|
||||||
let widths' = if all (== 0) widths && not (all isSimple cols)
|
|
||||||
then replicate (length aligns)
|
|
||||||
(1 / fromIntegral (length aligns))
|
|
||||||
else widths
|
|
||||||
let numcols = length widths'
|
|
||||||
cells <- mapM (tableCellToLaTeX header numcols) $ zip3 widths' aligns cols
|
|
||||||
return $ hsep (intersperse "&" cells) <> " \\\\ \\addlinespace"
|
return $ hsep (intersperse "&" cells) <> " \\\\ \\addlinespace"
|
||||||
|
|
||||||
-- For simple latex tables (without minipages or parboxes),
|
-- For simple latex tables (without minipages or parboxes),
|
||||||
|
@ -889,21 +904,26 @@ displayMathToInline (Math DisplayMath x) = Math InlineMath x
|
||||||
displayMathToInline x = x
|
displayMathToInline x = x
|
||||||
|
|
||||||
tableCellToLaTeX :: PandocMonad m
|
tableCellToLaTeX :: PandocMonad m
|
||||||
=> Bool -> Int -> (Double, Alignment, [Block])
|
=> Bool -> (Alignment, [Block])
|
||||||
-> LW m (Doc Text)
|
-> LW m (Doc Text)
|
||||||
tableCellToLaTeX _ _ (0, _, blocks) =
|
tableCellToLaTeX header (align, blocks) = do
|
||||||
blockListToLaTeX $ walk fixLineBreaks $ walk displayMathToInline blocks
|
|
||||||
tableCellToLaTeX header numcols (width, align, blocks) = do
|
|
||||||
beamer <- gets stBeamer
|
beamer <- gets stBeamer
|
||||||
externalNotes <- gets stExternalNotes
|
externalNotes <- gets stExternalNotes
|
||||||
inMinipage <- gets stInMinipage
|
inMinipage <- gets stInMinipage
|
||||||
-- See #5367 -- footnotehyper/footnote don't work in beamer,
|
-- See #5367 -- footnotehyper/footnote don't work in beamer,
|
||||||
-- so we need to produce the notes outside the table...
|
-- so we need to produce the notes outside the table...
|
||||||
modify $ \st -> st{ stExternalNotes = beamer,
|
modify $ \st -> st{ stExternalNotes = beamer }
|
||||||
stInMinipage = True }
|
let isPlainOrPara Para{} = True
|
||||||
|
isPlainOrPara Plain{} = True
|
||||||
|
isPlainOrPara _ = False
|
||||||
|
result <-
|
||||||
|
if all isPlainOrPara blocks
|
||||||
|
then
|
||||||
|
blockListToLaTeX $ walk fixLineBreaks $ walk displayMathToInline blocks
|
||||||
|
else do
|
||||||
|
modify $ \st -> st{ stInMinipage = True }
|
||||||
cellContents <- blockListToLaTeX blocks
|
cellContents <- blockListToLaTeX blocks
|
||||||
modify $ \st -> st{ stExternalNotes = externalNotes,
|
modify $ \st -> st{ stInMinipage = inMinipage }
|
||||||
stInMinipage = inMinipage }
|
|
||||||
let valign = text $ if header then "[b]" else "[t]"
|
let valign = text $ if header then "[b]" else "[t]"
|
||||||
let halign = case align of
|
let halign = case align of
|
||||||
AlignLeft -> "\\raggedright"
|
AlignLeft -> "\\raggedright"
|
||||||
|
@ -911,12 +931,12 @@ tableCellToLaTeX header numcols (width, align, blocks) = do
|
||||||
AlignCenter -> "\\centering"
|
AlignCenter -> "\\centering"
|
||||||
AlignDefault -> "\\raggedright"
|
AlignDefault -> "\\raggedright"
|
||||||
return $ "\\begin{minipage}" <> valign <>
|
return $ "\\begin{minipage}" <> valign <>
|
||||||
braces (text (printf
|
braces "\\linewidth" <> halign <> cr <>
|
||||||
"(\\columnwidth - %d\\tabcolsep) * \\real{%.2f}"
|
cellContents <> cr <>
|
||||||
(2 * (numcols - 1)) width)) <>
|
|
||||||
halign <> cr <> cellContents <> cr <>
|
|
||||||
"\\end{minipage}"
|
"\\end{minipage}"
|
||||||
-- (\columnwidth - 8\tabcolsep) * \real{0.15}
|
modify $ \st -> st{ stExternalNotes = externalNotes }
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
notesToLaTeX :: [Doc Text] -> Doc Text
|
notesToLaTeX :: [Doc Text] -> Doc Text
|
||||||
notesToLaTeX [] = empty
|
notesToLaTeX [] = empty
|
||||||
|
|
Loading…
Add table
Reference in a new issue