git.iko.soy/typeable/pandoc
on master help sign in
Fix for calculation of column widths for aligned multiline tables

This also fixes excessive CPU and memory usage for tables when --columns is set in such a way that cells must be very tiny. Now cells are guaranteed to be big enough so that single words don't need to line break, even if this pushes the line length above the column width. Closes #1911.

commit2761fecd57203c7dcdb30d72e194386942e62251 authorBjörn Peemöller <bjp@informatik.uni-kiel.de> dateTue 3 Feb 2015, 14:31 (12 years ago) parent18f5d25
1 file changed+20−8
src/Text/Pandoc/Writers/Markdown.hs+20−8
src/Text/Pandoc/Writers/Markdown.hs+20−8
@@ -592,20 +592,32 @@ pipeTable headless aligns rawHeaders rawRows = do
592592
593593pandocTable :: WriterOptions -> Bool -> [Alignment] -> [Double]
594594 -> [Doc] -> [[Doc]] -> MD Doc
595−pandocTable opts headless aligns widths rawHeaders rawRows = do
595+pandocTable opts headless aligns widths rawHeaders rawRows = do
596596 let isSimple = all (==0) widths
597597 let alignHeader alignment = case alignment of
598598 AlignLeft -> lblock
599599 AlignCenter -> cblock
600600 AlignRight -> rblock
601601 AlignDefault -> lblock
602− let numChars = maximum . map offset
603− let widthsInChars = if isSimple
604− then map ((+2) . numChars)
605− $ transpose (rawHeaders : rawRows)
606− else map
607− (floor . (fromIntegral (writerColumns opts) *))
608− widths
602+ -- Number of characters per column necessary to output every cell
603+ -- without requiring a line break.
604+ -- The @+2@ is needed for specifying the alignment.
605+ let numChars = (+ 2) . maximum . map offset
606+ -- Number of characters per column necessary to output every cell
607+ -- without requiring a line break *inside a word*.
608+ -- The @+2@ is needed for specifying the alignment.
609+ let minNumChars = (+ 2) . maximum . map minOffset
610+ let columns = transpose (rawHeaders : rawRows)
611+ -- minimal column width without wrapping a single word
612+ let noWordWrapWidth
613+ | writerWrapText opts == WrapAuto
614+ = fromIntegral $ maximum (map minNumChars columns)
615+ | otherwise = fromIntegral $ maximum (map numChars columns)
616+ let relWidth w = floor $ max (fromIntegral (writerColumns opts) * w)
617+ (noWordWrapWidth * w / minimum widths)
618+ let widthsInChars
619+ | isSimple = map numChars columns
620+ | otherwise = map relWidth widths
609621 let makeRow = hcat . intersperse (lblock 1 (text " ")) .
610622 (zipWith3 alignHeader aligns widthsInChars)
611623 let rows' = map makeRow rawRows