git.iko.soy/typeable/pandoc
on master help sign in
RST writer: use simple tables when possible.

Closes #4750. Text.Pandoc.Writers.Shared now exports hasSimpleCells [API change].

commitbd8a66394bc25b52dca9ffd963a560a4ca492f9c authorJohn MacFarlane <jgm@berkeley.edu> dateSat 6 Oct 2018, 22:33 (8 years ago) parent36a6a40
4 files changed+82−42
src/Text/Pandoc/Writers/RST.hs+34−4 src/Text/Pandoc/Writers/Shared.hs+18 test/tables-rstsubset.native+4−4 test/tables.rst+26−34
src/Text/Pandoc/Writers/RST.hs+34−4
@@ -35,7 +35,7 @@ module Text.Pandoc.Writers.RST ( writeRST, flatten ) where
3535import Prelude
3636import Control.Monad.State.Strict
3737import Data.Char (isSpace, toLower)
38−import Data.List (isPrefixOf, stripPrefix)
38+import Data.List (isPrefixOf, stripPrefix, transpose)
3939import Data.Maybe (fromMaybe)
4040import Data.Text (Text, stripEnd)
4141import qualified Text.Pandoc.Builder as B
@@ -304,9 +304,12 @@ blockToRST (Table caption aligns widths headers rows) = do
304304 modify $ \st -> st{ stOptions = oldOpts }
305305 return result
306306 opts <- gets stOptions
307− tbl <- gridTable opts blocksToDoc (all null headers)
308− (map (const AlignDefault) aligns) widths
309− headers rows
307+ let isSimple = all (== 0) widths
308+ tbl <- if isSimple
309+ then simpleTable opts blocksToDoc headers rows
310+ else gridTable opts blocksToDoc (all null headers)
311+ (map (const AlignDefault) aligns) widths
312+ headers rows
310313 return $ if null caption
311314 then tbl $$ blankline
312315 else (".. table:: " <> caption') $$ blankline $$ nest 3 tbl $$
@@ -693,3 +696,30 @@ imageDimsToRST attr = do
693696 Just dim -> cols dim
694697 Nothing -> empty
695698 return $ cr <> name $$ showDim Width $$ showDim Height
699+
700+simpleTable :: PandocMonad m
701+ => WriterOptions
702+ -> (WriterOptions -> [Block] -> m Doc)
703+ -> [[Block]]
704+ -> [[[Block]]]
705+ -> m Doc
706+simpleTable opts blocksToDoc headers rows = do
707+ -- can't have empty cells in first column:
708+ let fixEmpties (d:ds) = if isEmpty d
709+ then text "\\ " : ds
710+ else d : ds
711+ fixEmpties [] = []
712+ headerDocs <- if all null headers
713+ then return []
714+ else fixEmpties <$> mapM (blocksToDoc opts) headers
715+ rowDocs <- mapM (fmap fixEmpties . mapM (blocksToDoc opts)) rows
716+ let numChars [] = 0
717+ numChars xs = maximum . map offset $ xs
718+ let colWidths = map numChars $ transpose (headerDocs : rowDocs)
719+ let toRow = hsep . zipWith lblock colWidths
720+ let hline = hsep (map (\n -> text (replicate n '=')) colWidths)
721+ let hdr = if all null headers
722+ then mempty
723+ else hline $$ toRow headerDocs
724+ let bdy = vcat $ map toRow rowDocs
725+ return $ hdr $$ hline $$ bdy $$ hline
src/Text/Pandoc/Writers/Shared.hs+18
@@ -41,6 +41,7 @@ module Text.Pandoc.Writers.Shared (
4141 , isDisplayMath
4242 , fixDisplayMath
4343 , unsmartify
44+ , hasSimpleCells
4445 , gridTable
4546 , lookupMetaBool
4647 , lookupMetaBlocks
@@ -54,6 +55,7 @@ module Text.Pandoc.Writers.Shared (
5455where
5556import Prelude
5657import Control.Monad (zipWithM)
58+import Data.Monoid (Any (..))
5759import Data.Aeson (FromJSON (..), Result (..), ToJSON (..), Value (Object),
5860 encode, fromJSON)
5961import Data.Char (chr, ord, isAscii, isSpace)
@@ -70,6 +72,7 @@ import Text.Pandoc.Pretty
7072import Text.Pandoc.Shared (stringify)
7173import Text.Pandoc.UTF8 (toStringLazy)
7274import Text.Pandoc.XML (escapeStringForXML)
75+import Text.Pandoc.Walk (query)
7376import Text.Printf (printf)
7477
7578-- | Create JSON value for template from a 'Meta' and an association list
@@ -243,6 +246,21 @@ unsmartify opts ('\8216':xs) = '\'' : unsmartify opts xs
243246unsmartify opts (x:xs) = x : unsmartify opts xs
244247unsmartify _ [] = []
245248
249+-- | True if block is a table that can be represented with
250+-- one line per row.
251+hasSimpleCells :: Block -> Bool
252+hasSimpleCells (Table _caption _aligns _widths headers rows) =
253+ all isSimpleCell (concat (headers:rows))
254+ where
255+ isLineBreak LineBreak = Any True
256+ isLineBreak _ = Any False
257+ hasLineBreak = getAny . query isLineBreak
258+ isSimpleCell [Plain ils] = not (hasLineBreak ils)
259+ isSimpleCell [Para ils ] = not (hasLineBreak ils)
260+ isSimpleCell [] = True
261+ isSimpleCell _ = False
262+hasSimpleCells _ = False
263+
246264gridTable :: Monad m
247265 => WriterOptions
248266 -> (WriterOptions -> [Block] -> m Doc)
test/tables-rstsubset.native+4−4
@@ -1,5 +1,5 @@
11[Para [Str "Simple",Space,Str "table",Space,Str "with",Space,Str "caption:"]
2−,Table [Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax."] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.1,8.75e-2,0.1125,0.125]
2+,Table [Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax."] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.0,0.0,0.0,0.0]
33 [[Plain [Str "Right"]]
44 ,[Plain [Str "Left"]]
55 ,[Plain [Str "Center"]]
@@ -17,7 +17,7 @@
1717 ,[Plain [Str "1"]]
1818 ,[Plain [Str "1"]]]]
1919,Para [Str "Simple",Space,Str "table",Space,Str "without",Space,Str "caption:"]
20−,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.1,8.75e-2,0.1125,0.125]
20+,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.0,0.0,0.0,0.0]
2121 [[Plain [Str "Right"]]
2222 ,[Plain [Str "Left"]]
2323 ,[Plain [Str "Center"]]
@@ -35,7 +35,7 @@
3535 ,[Plain [Str "1"]]
3636 ,[Plain [Str "1"]]]]
3737,Para [Str "Simple",Space,Str "table",Space,Str "indented",Space,Str "two",Space,Str "spaces:"]
38−,Table [Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax."] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.1,8.75e-2,0.1125,0.125]
38+,Table [Str "Demonstration",Space,Str "of",Space,Str "simple",Space,Str "table",Space,Str "syntax."] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.0,0.0,0.0,0.0]
3939 [[Plain [Str "Right"]]
4040 ,[Plain [Str "Left"]]
4141 ,[Plain [Str "Center"]]
@@ -81,7 +81,7 @@
8181 ,[Plain [Str "5.0"]]
8282 ,[Plain [Str "Here\8217s",Space,Str "another",Space,Str "one.",Space,Str "Note",SoftBreak,Str "the",Space,Str "blank",Space,Str "line",Space,Str "between",SoftBreak,Str "rows."]]]]
8383,Para [Str "Table",Space,Str "without",Space,Str "column",Space,Str "headers:"]
84−,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [7.5e-2,7.5e-2,7.5e-2,7.5e-2]
84+,Table [] [AlignDefault,AlignDefault,AlignDefault,AlignDefault] [0.0,0.0,0.0,0.0]
8585 [[]
8686 ,[]
8787 ,[]
test/tables.rst+26−34
@@ -2,41 +2,35 @@ Simple table with caption:
22
33.. table:: Demonstration of simple table syntax.
44
5− +-------+------+--------+---------+
6− | Right | Left | Center | Default |
7− +=======+======+========+=========+
8− | 12 | 12 | 12 | 12 |
9− +-------+------+--------+---------+
10− | 123 | 123 | 123 | 123 |
11− +-------+------+--------+---------+
12− | 1 | 1 | 1 | 1 |
13− +-------+------+--------+---------+
5+ ===== ==== ====== =======
6+ Right Left Center Default
7+ ===== ==== ====== =======
8+ 12 12 12 12
9+ 123 123 123 123
10+ 1 1 1 1
11+ ===== ==== ====== =======
1412
1513Simple table without caption:
1614
17−+-------+------+--------+---------+
18−| Right | Left | Center | Default |
19−+=======+======+========+=========+
20−| 12 | 12 | 12 | 12 |
21−+-------+------+--------+---------+
22−| 123 | 123 | 123 | 123 |
23−+-------+------+--------+---------+
24−| 1 | 1 | 1 | 1 |
25−+-------+------+--------+---------+
15+===== ==== ====== =======
16+Right Left Center Default
17+===== ==== ====== =======
18+12 12 12 12
19+123 123 123 123
20+1 1 1 1
21+===== ==== ====== =======
2622
2723Simple table indented two spaces:
2824
2925.. table:: Demonstration of simple table syntax.
3026
31− +-------+------+--------+---------+
32− | Right | Left | Center | Default |
33− +=======+======+========+=========+
34− | 12 | 12 | 12 | 12 |
35− +-------+------+--------+---------+
36− | 123 | 123 | 123 | 123 |
37− +-------+------+--------+---------+
38− | 1 | 1 | 1 | 1 |
39− +-------+------+--------+---------+
27+ ===== ==== ====== =======
28+ Right Left Center Default
29+ ===== ==== ====== =======
30+ 12 12 12 12
31+ 123 123 123 123
32+ 1 1 1 1
33+ ===== ==== ====== =======
4034
4135Multiline table with caption:
4236
@@ -70,13 +64,11 @@ Multiline table without caption:
7064
7165Table without column headers:
7266
73−+-----+-----+-----+-----+
74−| 12 | 12 | 12 | 12 |
75−+-----+-----+-----+-----+
76−| 123 | 123 | 123 | 123 |
77−+-----+-----+-----+-----+
78−| 1 | 1 | 1 | 1 |
79−+-----+-----+-----+-----+
67+=== === === ===
68+12 12 12 12
69+123 123 123 123
70+1 1 1 1
71+=== === === ===
8072
8173Multiline table without column headers:
8274