From eb8aee477db045a7449bc752975528263964b8ce Mon Sep 17 00:00:00 2001 From: John MacFarlane <jgm@berkeley.edu> Date: Fri, 30 Oct 2015 12:37:08 -0700 Subject: [PATCH] Pipe tables with long lines now get relative cell widths. If a pipe table contains a line longer than the column width (as set by `--columns` or 80 by default), relative widths are computed based on the widths of the separator lines relative to the column width. This should solve persistent problems with long pipe tables in LaTeX/PDF output, and give more flexibility for determining relative column widths in other formats, too. For narrower pipe tables, column widths of 0 are used, telling pandoc not to specify widths explicitly in output formats that permit this. Closes #2471. --- src/Text/Pandoc/Readers/Markdown.hs | 33 +++++++++++++++++------------ tests/pipe-tables.native | 13 +++++++++++- tests/pipe-tables.txt | 7 ++++++ 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/Text/Pandoc/Readers/Markdown.hs b/src/Text/Pandoc/Readers/Markdown.hs index e0b43d7f0..58878feb5 100644 --- a/src/Text/Pandoc/Readers/Markdown.hs +++ b/src/Text/Pandoc/Readers/Markdown.hs @@ -1320,7 +1320,7 @@ removeOneLeadingSpace xs = gridTableFooter :: MarkdownParser [Char] gridTableFooter = blanklines -pipeBreak :: MarkdownParser [Alignment] +pipeBreak :: MarkdownParser ([Alignment], [Int]) pipeBreak = try $ do nonindentSpaces openPipe <- (True <$ char '|') <|> return False @@ -1330,16 +1330,22 @@ pipeBreak = try $ do guard $ not (null rest && not openPipe) optional (char '|') blankline - return (first:rest) + return $ unzip (first:rest) pipeTable :: MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]]) pipeTable = try $ do nonindentSpaces lookAhead nonspaceChar - (heads,aligns) <- (,) <$> pipeTableRow <*> pipeBreak - lines' <- sequence <$> many pipeTableRow - let widths = replicate (length aligns) 0.0 - return $ (aligns, widths, heads, lines') + (heads,(aligns, seplengths)) <- (,) <$> pipeTableRow <*> pipeBreak + (lines', rawRows) <- unzip <$> many (withRaw pipeTableRow) + let maxlength = maximum $ map length rawRows + numColumns <- getOption readerColumns + let widths = if maxlength > numColumns + then map (\len -> + fromIntegral (len + 1) / fromIntegral numColumns) + seplengths + else replicate (length aligns) 0.0 + return $ (aligns, widths, heads, sequence lines') sepPipe :: MarkdownParser () sepPipe = try $ do @@ -1368,19 +1374,20 @@ pipeTableRow = do ils' | B.isNull ils' -> mempty | otherwise -> B.plain $ ils') cells' -pipeTableHeaderPart :: Parser [Char] st Alignment +pipeTableHeaderPart :: Parser [Char] st (Alignment, Int) pipeTableHeaderPart = try $ do skipMany spaceChar left <- optionMaybe (char ':') - many1 (char '-') + pipe <- many1 (char '-') right <- optionMaybe (char ':') skipMany spaceChar + let len = length pipe + maybe 0 (const 1) left + maybe 0 (const 1) right return $ - case (left,right) of - (Nothing,Nothing) -> AlignDefault - (Just _,Nothing) -> AlignLeft - (Nothing,Just _) -> AlignRight - (Just _,Just _) -> AlignCenter + ((case (left,right) of + (Nothing,Nothing) -> AlignDefault + (Just _,Nothing) -> AlignLeft + (Nothing,Just _) -> AlignRight + (Just _,Just _) -> AlignCenter), len) -- Succeed only if current line contains a pipe. scanForPipe :: Parser [Char] st () diff --git a/tests/pipe-tables.native b/tests/pipe-tables.native index 9d499c9c2..f52175ff0 100644 --- a/tests/pipe-tables.native +++ b/tests/pipe-tables.native @@ -83,4 +83,15 @@ [[[Plain [Str "3"]] ,[Plain [Str "33"]]] ,[[Plain [Str "4"]] - ,[Plain [Str "44"]]]]] + ,[Plain [Str "44"]]]] +,Para [Str "Long",Space,Str "pipe",Space,Str "table",Space,Str "with",Space,Str "relative",Space,Str "widths:"] +,Table [] [AlignDefault,AlignDefault,AlignDefault] [0.125,0.1375,0.5] + [[Plain [Str "Default1"]] + ,[Plain [Str "Default2"]] + ,[Plain [Str "Default3"]]] + [[[Plain [Str "123"]] + ,[Plain [Str "this",Space,Str "is",Space,Str "a",Space,Str "table",Space,Str "cell"]] + ,[Plain [Str "and",Space,Str "this",Space,Str "is",Space,Str "a",Space,Str "really",Space,Str "long",Space,Str "table",Space,Str "cell",Space,Str "that",Space,Str "will",Space,Str "probably",Space,Str "need",Space,Str "wrapping"]]] + ,[[Plain [Str "123"]] + ,[Plain [Str "123"]] + ,[Plain [Str "123"]]]]] diff --git a/tests/pipe-tables.txt b/tests/pipe-tables.txt index a8803724a..a5984b99b 100644 --- a/tests/pipe-tables.txt +++ b/tests/pipe-tables.txt @@ -59,3 +59,10 @@ Number of siblings | Salary ------------------:|:------ 3 | 33 4 | 44 + +Long pipe table with relative widths: + +| Default1 | Default2 | Default3 | + |---------|----------|---------------------------------------| +|123|this is a table cell|and this is a really long table cell that will probably need wrapping| +|123|123|123|