LaTeX writer: Improved calculation of table column widths.

We now have LaTeX do the calculation, using `\tabcolsep`.
So we should now have accurate relative column widths no
matter what the text width.

The default template has been modified to load the calc
package if tables are used.
This commit is contained in:
John MacFarlane 2020-10-29 12:10:05 -07:00
parent 517c55dae7
commit bd7c9eb32b
4 changed files with 79 additions and 49 deletions

View file

@ -257,6 +257,7 @@ $highlighting-macros$
$endif$
$if(tables)$
\usepackage{longtable,booktabs}
\usepackage{calc} % for calculating minipage widths
$if(beamer)$
\usepackage{caption}
% Make caption package work with longtable

View file

@ -851,9 +851,6 @@ tableRowToLaTeX :: PandocMonad m
-> [[Block]]
-> LW m (Doc Text)
tableRowToLaTeX header aligns widths cols = do
-- scale factor compensates for extra space between columns
-- so the whole table isn't larger than columnwidth
let scaleFactor = 0.97 ** fromIntegral (length aligns)
let isSimple [Plain _] = True
isSimple [Para _] = True
isSimple [] = True
@ -861,9 +858,10 @@ tableRowToLaTeX header aligns widths cols = do
-- simple tables have to have simple cells:
let widths' = if all (== 0) widths && not (all isSimple cols)
then replicate (length aligns)
(scaleFactor / fromIntegral (length aligns))
else map (scaleFactor *) widths
cells <- mapM (tableCellToLaTeX header) $ zip3 widths' aligns cols
(1 / fromIntegral (length aligns))
else widths
let numcols = length widths'
cells <- mapM (tableCellToLaTeX header numcols) $ zip3 widths' aligns cols
return $ hsep (intersperse "&" cells) <> "\\tabularnewline"
-- For simple latex tables (without minipages or parboxes),
@ -890,11 +888,12 @@ displayMathToInline :: Inline -> Inline
displayMathToInline (Math DisplayMath x) = Math InlineMath x
displayMathToInline x = x
tableCellToLaTeX :: PandocMonad m => Bool -> (Double, Alignment, [Block])
tableCellToLaTeX :: PandocMonad m
=> Bool -> Int -> (Double, Alignment, [Block])
-> LW m (Doc Text)
tableCellToLaTeX _ (0, _, blocks) =
tableCellToLaTeX _ _ (0, _, blocks) =
blockListToLaTeX $ walk fixLineBreaks $ walk displayMathToInline blocks
tableCellToLaTeX header (width, align, blocks) = do
tableCellToLaTeX header numcols (width, align, blocks) = do
beamer <- gets stBeamer
externalNotes <- gets stExternalNotes
inMinipage <- gets stInMinipage
@ -912,9 +911,12 @@ tableCellToLaTeX header (width, align, blocks) = do
AlignCenter -> "\\centering"
AlignDefault -> "\\raggedright"
return $ "\\begin{minipage}" <> valign <>
braces (text (printf "%.2f\\columnwidth" width)) <>
braces (text (printf
"(\\columnwidth - %d\\tabcolsep) * \\real{%.2f}"
(numcols - 1) width)) <>
halign <> cr <> cellContents <> "\\strut" <> cr <>
"\\end{minipage}"
-- (\columnwidth - 8\tabcolsep) * \real{0.15}
notesToLaTeX :: [Doc Text] -> Doc Text
notesToLaTeX [] = empty

View file

@ -23,18 +23,18 @@ hello\footnote{doc footnote}
\begin{longtable}[]{@{}c@{}}
\caption[Sample table.]{Sample table.\footnote{caption footnote}}\tabularnewline
\toprule
\begin{minipage}[b]{0.16\columnwidth}\centering
\begin{minipage}[b]{(\columnwidth - 0\tabcolsep) * \real{0.17}}\centering
Fruit\footnote{header footnote}\strut
\end{minipage}\tabularnewline
\midrule
\endfirsthead
\toprule
\begin{minipage}[b]{0.16\columnwidth}\centering
\begin{minipage}[b]{(\columnwidth - 0\tabcolsep) * \real{0.17}}\centering
Fruit{}\strut
\end{minipage}\tabularnewline
\midrule
\endhead
\begin{minipage}[t]{0.16\columnwidth}\centering
\begin{minipage}[t]{(\columnwidth - 0\tabcolsep) * \real{0.17}}\centering
Bans\footnote{table cell footnote}\strut
\end{minipage}\tabularnewline
\bottomrule

View file

@ -52,45 +52,57 @@ Multiline table with caption:
\begin{longtable}[]{@{}clrl@{}}
\caption{Here's the caption. It may span multiple lines.}\tabularnewline
\toprule
\begin{minipage}[b]{0.13\columnwidth}\centering
\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering
Centered Header\strut
\end{minipage} & \begin{minipage}[b]{0.12\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright
Left Aligned\strut
\end{minipage} & \begin{minipage}[b]{0.14\columnwidth}\raggedleft
\end{minipage} &
\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft
Right Aligned\strut
\end{minipage} & \begin{minipage}[b]{0.31\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright
Default aligned\strut
\end{minipage}\tabularnewline
\midrule
\endfirsthead
\toprule
\begin{minipage}[b]{0.13\columnwidth}\centering
\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering
Centered Header\strut
\end{minipage} & \begin{minipage}[b]{0.12\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright
Left Aligned\strut
\end{minipage} & \begin{minipage}[b]{0.14\columnwidth}\raggedleft
\end{minipage} &
\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft
Right Aligned\strut
\end{minipage} & \begin{minipage}[b]{0.31\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright
Default aligned\strut
\end{minipage}\tabularnewline
\midrule
\endhead
\begin{minipage}[t]{0.13\columnwidth}\centering
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering
First\strut
\end{minipage} & \begin{minipage}[t]{0.12\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright
row\strut
\end{minipage} & \begin{minipage}[t]{0.14\columnwidth}\raggedleft
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft
12.0\strut
\end{minipage} & \begin{minipage}[t]{0.31\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright
Example of a row that spans multiple lines.\strut
\end{minipage}\tabularnewline
\begin{minipage}[t]{0.13\columnwidth}\centering
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering
Second\strut
\end{minipage} & \begin{minipage}[t]{0.12\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright
row\strut
\end{minipage} & \begin{minipage}[t]{0.14\columnwidth}\raggedleft
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft
5.0\strut
\end{minipage} & \begin{minipage}[t]{0.31\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright
Here's another one. Note the blank line between rows.\strut
\end{minipage}\tabularnewline
\bottomrule
@ -100,33 +112,42 @@ Multiline table without caption:
\begin{longtable}[]{@{}clrl@{}}
\toprule
\begin{minipage}[b]{0.13\columnwidth}\centering
\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering
Centered Header\strut
\end{minipage} & \begin{minipage}[b]{0.12\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright
Left Aligned\strut
\end{minipage} & \begin{minipage}[b]{0.14\columnwidth}\raggedleft
\end{minipage} &
\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft
Right Aligned\strut
\end{minipage} & \begin{minipage}[b]{0.31\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[b]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright
Default aligned\strut
\end{minipage}\tabularnewline
\midrule
\endhead
\begin{minipage}[t]{0.13\columnwidth}\centering
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering
First\strut
\end{minipage} & \begin{minipage}[t]{0.12\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright
row\strut
\end{minipage} & \begin{minipage}[t]{0.14\columnwidth}\raggedleft
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft
12.0\strut
\end{minipage} & \begin{minipage}[t]{0.31\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright
Example of a row that spans multiple lines.\strut
\end{minipage}\tabularnewline
\begin{minipage}[t]{0.13\columnwidth}\centering
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering
Second\strut
\end{minipage} & \begin{minipage}[t]{0.12\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright
row\strut
\end{minipage} & \begin{minipage}[t]{0.14\columnwidth}\raggedleft
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft
5.0\strut
\end{minipage} & \begin{minipage}[t]{0.31\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright
Here's another one. Note the blank line between rows.\strut
\end{minipage}\tabularnewline
\bottomrule
@ -148,22 +169,28 @@ Multiline table without column headers:
\begin{longtable}[]{@{}clrl@{}}
\toprule
\endhead
\begin{minipage}[t]{0.13\columnwidth}\centering
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering
First\strut
\end{minipage} & \begin{minipage}[t]{0.12\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright
row\strut
\end{minipage} & \begin{minipage}[t]{0.14\columnwidth}\raggedleft
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft
12.0\strut
\end{minipage} & \begin{minipage}[t]{0.31\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright
Example of a row that spans multiple lines.\strut
\end{minipage}\tabularnewline
\begin{minipage}[t]{0.13\columnwidth}\centering
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.15}}\centering
Second\strut
\end{minipage} & \begin{minipage}[t]{0.12\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.14}}\raggedright
row\strut
\end{minipage} & \begin{minipage}[t]{0.14\columnwidth}\raggedleft
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.16}}\raggedleft
5.0\strut
\end{minipage} & \begin{minipage}[t]{0.31\columnwidth}\raggedright
\end{minipage} &
\begin{minipage}[t]{(\columnwidth - 3\tabcolsep) * \real{0.35}}\raggedright
Here's another one. Note the blank line between rows.\strut
\end{minipage}\tabularnewline
\bottomrule